Преобразовать треугольник в другой треугольник - программирование
Подтвердить что ты не робот

Преобразовать треугольник в другой треугольник

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

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

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);
}
4b9b3361

Ответ 1

Я собираюсь предположить, что вы говорите о 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. Он будет иметь уникальное решение тогда и только тогда, когда три точки вашего исходного треугольника не будут коллинеарными.

Ответ 2

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

где

M = обратный (ab) < --- это 2x2-матрица с точками a и b как ее столбцы p >

и

N = (c d)

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

Ответ 3

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

EDIT: ОК, этого недостаточно, аффинные преобразования также могут содержать сдвиг и масштабирование... Масштабирование можно сделать легко, просто разделите длину строк, это также даст вам некоторую информацию о соответствующих строках треугольников, но стрижка будет сложнее...

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

Ответ 4

Просто сформулируйте проблему как набор уравнений, а затем решите ее:

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 как инкогнитом и решить ее, но если я не упущу что-то (и, может быть, я), вам понадобится один укажите больше, чтобы полностью указать преобразование, иначе вы получите дополнительную степень свободы (и, конечно же, можете исправить ее).