вращая 2d квадрат в другой - PullRequest
1 голос
/ 09 июля 2010

У меня есть два квадрата, S1 = (x1, y1, x2, y2) и S2 = (a1, b1, a2, b2)

Я ищу матрицу преобразования, с которой A * S1 = S2

Насколько я вижу, А - это аффинная матрица 3х3, поэтому у меня 9 неизвестных значений.

Как я могу рассчитать эти значения?

спасибо и всего наилучшего, Viktor

Ответы [ 5 ]

6 голосов
/ 09 июля 2010

Здесь действительно только четыре неизвестных значения. Угол поворота, масштабный коэффициент и перемещение по осям X и Y. Из вашей матрицы три на три нижний ряд всегда равен 0,0,1, что сокращает вас до шести неизвестных. Правый столбец будет Tx,Ty,1, который будет вашим переводом (и 1, о котором мы уже знаем).

Два на два оставленных "матрицы" будут вашим вращением и масштабированием. Это будет (от макушки моей головы) что-то вроде:

ACos(B), -Asin(B)
ASin(B),  aCos(B)

Итого всего:

ACos(B), -Asin(B), Tx
ASin(B),  ACos(B), Ty
0      ,  0      , 1

Вы расширяете свои матрицы координат с 1 на конце каждой координаты, чтобы получить матрицы 2x3, а затем они умножаются, чтобы дать вам четыре уравнения, которые вам нужно решить для четырех переменных. Это оставлено как упражнение для читателя.

2 голосов
/ 09 июля 2010

Матрица преобразования - это коэффициент масштабирования матрицы Ss, матрицы перехода St и матрицы вращения Sr.

Предположим, что старой точкой является Po (Xo, Yo), а вектор будет представлен как (Xo Yo1) 'то же самое для новой точки Pn Тогда Pnv = Ss St SrPov Где Sx равно

Sx  0    0
0   Sy   0
0   0    1

St равно

1   0   Tx
0   1   Ty
0   0   1

Sr равно

Cos(th)    -Sin(th)    0
Sin(th)     Cos(th)    0
0           0          1

Теперь вернемся к вашему вопросу.если две точки дают представление прямоугольника, мы можем просто найти параметр двух матриц, а третья будет единичной матрицей.

Rect1 представлен в виде верхней левой точки P11 и нижней правой точки P12 Rect2представлена ​​как верхняя левая точка P21 и нижняя правая точка P22

S = Ss * St

Sx  0  Tx
0   Sy Ty
0   0  1

Теперь у вас есть 4 пропущенных параметра и 4 набора уравнений

P21=S*P11
P22=S*P12

X[P21] =Sx*X[P11]+Tx
Y[P21] =Sy*Y[P11]+Ty
X[P22] =Sx*X[P12]+Tx
Y[P22] =Sy*Y[P12]+Ty

Решите его, и вы получите ответ.

и если у вас есть переход и вращение, то S = Sr * St.

Cos(th)    -Sin(th)    Tx
Sin(th)     Cos(th)    Ty
0           0          1

Теперь у вас есть 3 пропущенных параметра и4 набора уравнений

P21=S*P11
P22=S*P12

X[P21] =Cos(th)*X[P11]-Sin(th)*Y[P11]+Tx
Y[P21] =Sin(th)*X[P11]+Cos(th)*Y[P11]+Ty
X[P22] =Cos(th)*X[P11]-Sin(th)*Y[P12]+Tx
Y[P22] =Sin(th)*X[P11]+Cos(th)*Y[P12]+Ty

Замените Cos (th) на A и Sin (th) на B и решите уравнения.

X[P21] =A*X[P11]-B*Y[P11]+Tx
Y[P21] =B*X[P11]+A*Y[P11]+Ty
X[P22] =A*X[P11]-B*Y[P12]+Tx
Y[P22] =B*X[P11]+A*Y[P12]+Ty

Проверьте, правильно ли это A^2+B^2 =? 1, еслиtrue тогда th = aCos(A)

Последняя часть решения, если у вас будет все три матрицы, то S = Sr St Ss равно

 Sx*sin(th) -Sx*cos(th)  Tx
 Sy*cos(th)  Sy*sin(th)  Ty
          0           0   1

Теперьу нас есть 5 пропущенных переменных, и нам нужно 6 различных систем уравнений для их решения.что означает 3 очка от каждого прямоугольника.

0 голосов
/ 11 июля 2010

Как я могу рассчитать эти значения?

Применительно к 2d / 3d преобразованиям матрица может быть представлена ​​системой координат, если мы не говорим о проекциях.

Строки матрицы (или столбцы, в зависимости от обозначений) образуют оси новой системы координат, в которую будет помещен объект, если каждая вершина объекта умножается на матрицу. Последний ряд (или столбец, в зависимости от обозначений) указывает на центр новой системы координат.

Стандартная матрица преобразования OpenGL / DirectX (НЕ матрица проекции):

class Matrix{//C++ code
public:
    union{
        float f[16];
        float m[4][4];
    };
};

Может быть представлен как комбинация из 4 векторов vx (ось x новой системы координат), vy (ось y новой системы координат), vz (ось z новой системы координат) и vp (центр новая система). Как это:

vx.x vx.y vx.z 0
vy.x vy.y vy.z 0
vz.x vz.y vz.z 0
vp.x vp.y vp.z 1

Все «вычислить матрицу вращения», «вычислить матрицу масштаба» и т. Д. Ведут к этой идее.

Таким образом, для 2d матрицы у вас будет матрица 3x3, которая состоит из 3 векторов - vx, vy, vp, потому что в 2d нет вектора z. I.e.:

vx.x vx.y 0
vy.x vy.y 0
vp.x vp.y 1

Чтобы найти преобразование, которое преобразовало бы квад A, в квад B, вам нужно найти два преобразования:

  1. Преобразование, которое переместит квад А в начало координат (то есть в нулевую точку), и преобразует его в квад фиксированного размера. Скажем, quad (прямоугольник), у которого одна вершина x = 0, y = 0 и вершины которого расположены в точках (0, 1), (1, 0), (1, 1).
  2. Преобразование, которое превращает четырехугольник фиксированного размера в четырехугольник B.

Вы НЕ МОЖЕТЕ сделать это таким образом, если противоположные ребра четырехугольника не параллельны. То есть параллелограммы хороши, а случайные 4-сторонние многоугольники - нет.

Четырехугольник может быть представлен базовой точкой (vp), которая может быть любой вершиной четырехугольника, и двумя векторами, определяющими размеры квадра (направление ребра, умноженное на длину ребра). То есть вектор "вверх" и вектор "сторона". Что делает его матрицей:

side.x side.y 0
up.x   up.y   0
vp.x   vp.y   1

Таким образом, умножение квадрата (vp.x = 0, vp.y = 0, side.x = 1, side.y = 0, up.x = 0, up.y = 1) на эту матрицу превратится в оригинальный квад в ваш квад. Что означает, что для того, чтобы преобразовать из четверки А в четверку В, вам нужно сделать следующее:

1) создать матрицу, которая преобразует «базовый квадрант из 1 единицы» в квадро А. Давайте назовем это matA.
2) создайте матрицу, которая преобразует «квад 1 единицы базы 1» в квад 4. Назовем это matB.
3) инвертировать matA и сохранить результат в invMatA.
4) матрица результата - invMatA * matB.

Готово. Если вы умножите квадра A на матрицу результатов, вы получите квад B. Это не будет работать, если у квадратов нулевая ширина или высота, и не будет работать, если квад не является параллелограммом.

Это трудно понять, но я не могу сделать это проще.

0 голосов
/ 09 июля 2010

Что вы подразумеваете под S1 = (x1,y1,x2,y2)?

Они представляют верхний левый и нижний правый углы квадрата?

Кроме того, можете ли вы гарантировать, что между квадратами есть только вращение, или вам нужно полное аффинное преобразование, которое позволяет масштабировать, наклонять и переводить?

Или вам также нужно перспективное преобразование?

Только если это перспективное преобразование, вам понадобится матрица 3x3 с 8 степенями свободы, как вы упоминали в своем посте.

0 голосов
/ 09 июля 2010

У вас не должно быть матрицы 3х3, если вы просто хотите преобразовать 2D-объект.То, что вы ищете, это матрица 2x2, которая решает A * S1 = S2.Это можно сделать разными способами;в MATLAB вы должны сделать S2/S1 ( правильное матричное деление ), и, как правило, выполняется некое исключение Гаусса .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...