Вопрос по math, java, affinetransform – Преобразовать треугольник в другой треугольник

14

Привет, я пытаюсь создать аффинное преобразование, которое позволит мне превратить треугольник в другой. То, что у меня есть, это координаты для 2 треугольников. Вы можете мне помочь?

После ответа Адама Розенфилда я придумал этот код на тот случай, если кому-то надоест самому решить уравнение:

public static AffineTransform createTransform(ThreePointSystem source,
            ThreePointSystem dest) {        
    double x11 = source.point1.getX();
    double x12 = source.point1.getY();
    double x21 = source.point2.getX();
    double x22 = source.point2.getY();
    double x31 = source.point3.getX();
    double x32 = source.point3.getY();
    double y11 = dest.point1.getX();
    double y12 = dest.point1.getY();
    double y21 = dest.point2.getX();
    double y22 = dest.point2.getY();
    double y31 = dest.point3.getX();
    double y32 = dest.point3.getY();

    double a1 = ((y11-y21)*(x12-x32)-(y11-y31)*(x12-x22))/
                ((x11-x21)*(x12-x32)-(x11-x31)*(x12-x22));
    double a2 = ((y11-y21)*(x11-x31)-(y11-y31)*(x11-x21))/
                ((x12-x22)*(x11-x31)-(x12-x32)*(x11-x21));
    double a3 = y11-a1*x11-a2*x12;
    double a4 = ((y12-y22)*(x12-x32)-(y12-y32)*(x12-x22))/
                ((x11-x21)*(x12-x32)-(x11-x31)*(x12-x22));
    double a5 = ((y12-y22)*(x11-x31)-(y12-y32)*(x11-x21))/
                ((x12-x22)*(x11-x31)-(x12-x32)*(x11-x21));
    double a6 = y12-a4*x11-a5*x12;
    return new AffineTransform(a1, a4, a2, a5, a3, a6);
}
Так что вам нужно "переместить" один треугольник таким образом, что координаты совпадают со вторыми координатами без изменения внешнего вида треугольника? Какие у вас координаты? Janusz
2 совершенно разных треугольника (как по форме, так и по расположению). Они оба находятся в одной системе координат. Savvas Dalkitsis
Очень полезно, спасибо! Просто быстрое напоминание о том, что при использовании javascript html5 canvas функция context.setTransform () принимает точные выходные данные вашей функции, так что это отличный инструмент для отображения изображений из одной системы координат в другую, когда зарегистрирован треугольник точек для каждого. JayCrossler

Ваш Ответ

4   ответа
13

Я предполагаю, что вы говорите о 2D здесь. Матрица аффинного преобразования содержит 9 значений:

    | a1 a2 a3 |
A = | a4 a5 a6 |
    | a7 a8 a9 |

Есть 3 входные вершиныx1, x2, а такжеx3который при преобразовании должен статьy1, y2, y3, Однако, поскольку мы работаем в однородных координатах, применяяA вx1 не обязательно даетy1 - это дает кратноеy1, Итак, у нас также есть неизвестные множителиk1, k2, а такжеk3с уравнениями:

A*x1 = k1*y1
A*x2 = k2*y2
A*x3 = k3*y3

Каждый из них является вектором, поэтому у нас действительно есть 9 уравнений на 12 неизвестных, поэтому решение будет ограничено. Если мы требуем, чтобыa7=0, a8=0, а такжеa9=1, тогда решение будет уникальным (этот выбор является естественным, поскольку это означает, что если точка входаx, y, 1), тогда выходная точка всегда будет иметь однородную координату 1, поэтому результирующее преобразование - это просто преобразование 2x2 плюс перевод).

Следовательно, это сводит уравнения к:

a1*x11 + a2*x12 + a3 = k1*y11
a4*x11 + a5*x12 + a6 = k1*y12
                   1 = k1
a1*x21 + a2*x22 + a3 = k2*y21
a4*x21 + a5*x22 + a6 = k2*y22
                   1 = k2
a1*x31 + a2*x32 + a3 = k3*y31
a4*x31 + a5*x32 + a6 = k3*y32
                   1 = k3

Так,k1 = k2 = k3 = 1. Включение их и преобразование в матричную форму дает:

| x11 x12   1   0   0   0 |   | a1 |   | y11 |
| x21 x22   1   0   0   0 |   | a2 |   | y21 |
| x31 x32   1   0   0   0 | * | a3 | = | y31 |
|   0   0   0 x11 x12   1 |   | a4 |   | y12 |
|   0   0   0 x21 x22   1 |   | a5 |   | y22 |
|   0   0   0 x31 x32   1 |   | a6 |   | y32 |

Решение этой системы уравнений 6x6 дает вам матрицу аффинного преобразованияA, Он будет иметь уникальное решение, если и только если 3 точки вашего исходного треугольника не коллинеарны.

Разве система 6x6 не слишком сложная?
Поскольку в вопросе указано «аффинное преобразование» не означает ли это, что [a7, a8, a9] == [0, 0, 1]? Я знаю, что это результат, который вы в итоге получили, просто кажется, что вы прошли через некоторые ненужные искажения, чтобы попасть туда. Коэффициент k также казался слишком общим.
1

Просто сформулируйте задачу в виде системы уравнений, а затем решите ее:

P1 * M = P1'
P2 * M = P2'
P3 * M = P3'

M это матрица 3x3, например:

[m00, m01, m02;
 m10, m11, m12;
 0  ,   0,   1]

А такжеP_i это кортеж[k*x_i, k*y_i, k] (однородные координаты) ...

Теперь вы можете попытаться расширить 3 матричных уравнения, показанных выше, и создать новую систему сm_ij как это происходит, но если я что-то не упустил (и, возможно, я что-то), вам понадобится еще один пункт, чтобы полностью определить трансформацию, иначе вы получите дополнительную степень свободы (и, конечно, вы можете исправить это). Это).

1

Если я правильно понимаю, ваши треугольники имеют одинаковый размер и углы, поэтому вы должны иметь возможность трансформировать их так, чтобы они имели (как минимум) одну общую точку. После этого они должны различаться только по вращению или могут быть зеркально отражены, чтобы вы могли видеть получить углы между линиями треугольника и попробовать их для поворота и может отразить один из треугольников, если ни один из углов не работает.

РЕДАКТИРОВАТЬ: ОК, этого недостаточно, аффинные преобразования также могут содержать сдвиг и масштабирование ... Масштабирование можно выполнить легко, просто разделите длину линий, это также даст вам некоторую информацию о соответствующих линиях треугольников, но стрижка будет сложнее ...

OTOH, не могли бы вы просто решить какую-то систему уравнений для этого? Ведь должна быть матрица преобразования и 3 точки (новая и старая) ...

Нету. Я хочу отразить 1 треугольник в совершенно другой (та же система координат) Savvas Dalkitsis
2

Эй, ребята, без потери общности, сделайте так, чтобы два треугольника имели начало как одну вершину (вы можете добавить аффинный сдвиг позже), чтобы они были определены точками0, a, b, c, d затем умножьте свои очкиx по матрице Н.М.

где

M = обратная (a b) & lt; --- это матрица 2x2 с точкамиa а такжеb как его столбцы

а также

N = (c d)

Это должно сделать это.

Похожие вопросы