Как умножить 2D точку с 4D матрицей - PullRequest
1 голос
/ 21 февраля 2011

Как я могу преобразовать 2D точку (или 3D с Z = 0) в 2D точку (где Z игнорируется) с 4D матрицей?

Я использую Microsoft Silverlight для проецирования 2D-элемента управления в качестве псевдо-3D с использованием Matrix3D определение Matrix3D

Я знаю начальную 2D-точку точки в нетрансформированном элементе управления, и я хочу 2D-положение точки после преобразования.

API Silverlight немногочислен в отношении 3D-методов.

Пожалуйста, предложите основную математику для выполнения расчета.

Это продолжение вопроса silverlight

Изменить подробности

не работает. Я использую

x = x0 * matrix[0][0] + y0 * matrix[1][0] + z0 * matrix[2][0] +
    w0 * matrix[3][0];

y = x0 * matrix[0][1] + y0 * matrix[1][1] + z0 * matrix[2][1] +
    w0 * matrix[3][1];

z = x0 * matrix[0][2] + y0 * matrix[1][2] + z0 * matrix[2][2] +
    w0 * matrix[3][2];

и входные данные x и y равны 0,0, а результат x, y равен 0, 58,5786 матрица

HasInverse  true    bool
IsIdentity  false   bool
M11 1.0 double
M12 0.0 double
M13 0.0 double
M14 0.0 double
M21 0.0 double
M22 0.70710676908493042 double
M23 0.70710676908493042 double
M24 0.0 double
M31 0.0 double
M32 -0.70710676908493042    double
M33 0.70710676908493042 double
M34 0.0 double
M44 1.0 double
OffsetX 0.0 double
OffsetY 58.578643798828125  double
OffsetZ -141.42135620117187 double

, который создает угол поворота на 45 градусов по оси Z, где точка поворота является нижней частью плоскости.

все значения M1n, включая OffsetX, равны 0,0, в результате x всегда является исходным значением.

Что я делаю не так?

Вот мои четыре примера значений с результатами приведенной выше математики

0, 0, 0, 1 -> 0, 58.5786437988281, -141.421356201172, 1
50, 0, 0, 1 -> 50, 58.5786437988281, -141.421356201172, 1
0, 100, 0, 1 -> 0, 129.289320707321, -70.7106792926788, 1
100, 100, 0, 1 -> 100, 129.289320707321, -70.7106792926788, 1

глядя на полученное изображение, плоскость 400x400 имеет верхний левый угол 45,135 и верхний правый угол 355,135, нижний левый угол 0,400 и нижний правый угол 400,400

поэтому для тестового значения 0,0,0,1,0 я бы ожидал x и y до 45,135

Ответы [ 2 ]

3 голосов
/ 23 февраля 2011

Расширить ваш 2D-вектор до 4D-вектора - (X, Y, 0, 1); это трехмерный вектор, указанный в однородных координатах . Умножьте вектор 4D на матрицу 4D, чтобы получить новый вектор 4D, из которого вы берете первые 2 компонента.

Если матрица задает какую-то перспективную проекцию, то вам нужно разделить на последний компонент, т.е. если ваш результирующий вектор (x, y, z, w), то окончательные координаты (x / w) , г / з, з / ш). Если матрица не имеет перспективной проекции, то w = 1 и конечный вектор равен просто (x, y, z)

0 голосов
/ 21 февраля 2011

Я не уверен, есть ли для этого ярлык, но вам нужно:

newX = oldx * mat.M11 + oldY * mat.M21 + mat.OffsetX;
newX = oldx * mat.M12 + oldY * mat.M22 + mat.OffsetY;

(при условии, что ваш oldZ равен нулю и вы игнорируете значение newZ).

Редактировать: лучший способ сделать это:

Vector3D oldPos(oldx, oldy, 0.0f);
Vector3D newPos = oldPos * matrix;

Ваши новые координаты: newPos.X и newPos.Y;

...