почему матрицы преобразования ведут себя иначе - PullRequest
1 голос
/ 30 мая 2020

Я получаю разные результаты при масштабировании объектов.

Объекты имеют четыре разных значения glm :: vec3

 1) Position , Rotation , Scaling , Center Point

Это матрица преобразования объекта

   TransformationMatrix = PositionMatrix() * RotationMatrix() * ScalingMatrix();

Матрица поворота и масштабирования выглядит так.

glm::vec3 pivotVector(pivotx, pivoty, pivotz);
glm::mat4 TransPivot = glm::translate(glm::mat4x4(1.0f), pivotVector);
glm::mat4 TransPivotInverse = glm::translate(glm::mat4x4(1.0f), -pivotVector);
glm::mat4 TransformationScale = glm::scale(glm::mat4(1.0), glm::vec3(scax, scay, scaz));
return   TransPivot * TransformationScale * TransPivotInverse;

В первом случае.

enter image description here

Я перемещаю объект прямоугольника до 200 единиц в x.

Затем я масштабирую группу, которая находится в позиции x = 0,0

, так что окончательная матрица для объекта прямоугольника будет

 finalMatrix = rectangleTransformationMatrix * groupTransformationMatrix

Результат - то, что я ожидал. Прямоугольник масштабируется и перемещается к центру экрана.

enter image description here

Теперь, если я сделаю то же самое с тремя контейнерами .

Здесь я перемещаю контейнер группы на 200 и масштабирую контейнер Top, который находится в позиции 0,0

   finalMatrix = rectangleTransformationMatrix * groupTransformationMatrix * TopTransformationMatrix

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

enter image description here

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

где прямоугольник перемещается к центру экрана и масштабируется.

Если кто-нибудь может объяснить мне, почему мне нужно чтобы добавить -200 единиц к центральной точке контейнера Top. Тогда как в первом случае мне не нужно было добавлять какое-либо значение в точку поворота контейнера масштабирования.

, когда обе операции идентичны по своей природе .

/////////////////////////////////////////// ////////////////////////////////////////////////// /////////////////////////

Первый случай

Rectangle - > position( x = 200 , y = 0, z = 0) , scaling( 1.0 , 1.0 , 1.0 ) , Rotation( 0.0 , 0.0 , 0.0 )
glm::mat4 PositionMatrix = glm::position( // fill the values);
glm::mat4 ScalingMatrix = glm::scaling( // fill the values);
glm::mat4 RotationMatrix = glm::rotate( // fill the values);
RectangleMatrix = PositionMatrix() * RotationMtrix() * ScalingMatrix();

матрица для группы

 froup - > position( x = 0.0 , y = 0, z = 0) , scaling( 0.5 , 1.0 , 1.0 ) , Rotation( 0.0 , 0.0 , 0.0 )
groupMatrix = PositionMatrix() * RotationMtrix() * ScalingMatrix();

окончательный результат finalMatrix = RectangleMatrix * groupMatrix

////////////////////////////////// ////////////////////////////////////////////////// ////////////////////////////////////

Второй регистр

Rectangle - > position( x = 0 , y = 0, z = 0) , scaling( 1.0 , 1.0 , 1.0 ) , Rotation( 0.0 , 0.0 , 0.0 )
glm::mat4 PositionMatrix = glm::position( // fill the values);
glm::mat4 ScalingMatrix = glm::scaling( // fill the values);
glm::mat4 RotationMatrix = glm::rotate( // fill the values);
RectangleMatrix = PositionMatrix() * RotationMtrix() * ScalingMatrix();

матрица для группы

 group - > position( x = 200.0 , y = 0, z = 0) , scaling( 1.0 , 1.0 , 1.0 ) , Rotation( 0.0 , 0.0 , 0.0 )
groupMatrix = PositionMatrix() * RotationMtrix() * ScalingMatrix();

матрица для Top

 Top - > position( x = 0.0 , y = 0, z = 0) , scaling( 0.5 , 1.0 , 1.0 ) , Rotation( 0.0 , 0.0 , 0.0 )
TopMatrix = PositionMatrix() * RotationMtrix() * ScalingMatrix();

конечный результат finalMatrix = RectangleMat rix * groupMatrix * TopMatrix

1 Ответ

3 голосов
/ 30 мая 2020

Матричные операции не Коммутативные . scale * translate не то же самое, что translate * scale

Если у вас есть перевод 200 и масштаб 0,2, тогда

translate(200) * scale(0.2)

дает объект, масштабированный на 0,2 и переведенный на 200 . Но

scale(0.2) * translate(200)

дает объект, масштабированный на 0,2 и переведенный на 40 (0,2 * 200).

Если у вас 2 матрицы:

groupMatrix = PositionMatrix() * RotationMtrix() * ScalingMatrix();
TopMatrix = PositionMatrix() * RotationMtrix() * ScalingMatrix();

Тогда groupMatrix * TopMatrix совпадает с

groupPositionMatrix * groupRotationMtrix * groupScalingMatrix * topPositionMatrix * topRotationMtrix * topScalingMatrix

Результат будет другим, если масштаб закодирован в groupScalingMatrix или topScalingMatrix соответственно перевод кодируется в groupPositionMatrix или topPositionMatrix.

...