Как применить преобразование с использованием матрицы вращения 3х3 и вектора перевода? - PullRequest
0 голосов
/ 23 ноября 2018

Я работаю над проектом дополненной реальности, используя ARCore.Система координат ARCore меняется каждый раз, когда вы запускаете приложение, занимая исходную позицию в качестве источника.У меня есть 5 точек в другой системе координат, и я могу найти 4 из этих позиций в мировом пространстве Unity, используя ARCore Augmented Image.Эти точки имеют разные значения в моей другой системе координат, конечно.Я должен найти положение 5-й точки в мировом пространстве Unity, используя ее положение в другой системе координат.

Я следовал этому учебнику , чтобы добиться этого.Но поскольку Unity не поддерживает матрицы 3x3, я использовал Accord.NET framework.Используя учебное пособие и матрицы согласия, я могу вычислить матрицу 3x3 Rotation и вектор Translation.

Однако, когда я попытался применить это к своей 5-й точке, используя TestObject.transform.Translate(AccordtoUnity(Translation),Space.World), у меня возникли проблемы.Когда начальные 4 объекта и эталонные объекты находятся в одинаковой ориентации, мой перевод работает отлично.Однако, когда мои ссылочные объекты повернуты, этот перевод не работает.Это имеет смысл, конечно, так как я только сделал перевод.У меня вопрос, как я могу применить ротацию и перевод к моей 5-й точке.Или есть способ конвертировать мою матрицу вращения 3x3 и перевод в Unity 4x4Matrix, с тех пор я могу использовать Matrix4x4.MultiplyPoint3x4.Или возможно преобразовать мою матрицу вращения 3x3 в Quaternion, которая позволяет мне использовать 4x4Matrix.SetTRS.Я немного озадачен этим преобразованием, потому что 4x4Matrix также включает масштабирование, но я не делаю никакого масштабирования.

Я был бы рад, если бы кто-то дал мне подсказку или предложил лучший подход, чтобы найти способчтобы найти 5-й пункт.Спасибо!

РЕДАКТИРОВАТЬ:

Я действительно решил проблему, основываясь на ответе Daveloper.Я построил матрицу Unity 4x4 следующим образом:

[ R00 R01 R02 T.x ]
[ R10 R11 R12 T.y ]
[ R20 R21 R22 T.z ]
[ 0    0   0   1  ]

Я протестировал это создание примитивных объектов в Unity и применил перемещение и вращение, используя приведенную выше матрицу, например:

 TestObject.transform.position  = TransformationMatrix.MultiplyPoint3x4(TestObject.transform.position);
 TestObject.transform.rotation *= Quaternion.LookRotation(TransformationMatrix.GetColumn(2), TransformationMatrix.GetColumn(1));

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Если я правильно понимаю ваш вопрос, вы захотите создать кватернион вращения из матрицы 3х3.

Вы можете думать о матрице вращения 3x3 как о трех векторах длины 1, все на 90 градусов друг к другу.Например:

| forward.x    forward.y    forward.z |
| up.x         up.y         up.z      |
| right.x      right.y      right.z   |

Довольно надежный способ сделать преобразование состоит в том, чтобы убрать векторы вперед и вверх из вашей матрицы и применить их к методу Unity https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html

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

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

0 голосов
/ 23 ноября 2018

, чтобы использовать матрицу вращения 3x3 и вектор перевода для установки преобразования, используйте

// rotationMatrixCV = your 3x3 rotation matrix; translation = your translation vector

var rotationMatrix = new Matrix4x4();
for (int i = 0; i < 3; i++)
{
    for (int j = 0; j < 3; j++)
    {
        rotationMatrix[i, j] = rotationMatrixCV[i, j];
    }
}
rotationMatrix[3, 3] = 1f;

var localToWorldMatrix = Matrix4x4.Translate(translation) * rotationMatrix);

Vector3 scale;
scale.x = new Vector4(localToWorldMatrix.m00, localToWorldMatrix.m10, matrix.m20, localToWorldMatrix.m30).magnitude;
scale.y = new Vector4(localToWorldMatrix.m01, localToWorldMatrix.m11, matrix.m21, localToWorldMatrix.m31).magnitude;
scale.z = new Vector4(localToWorldMatrix.m02, localToWorldMatrix.m12, matrix.m22, localToWorldMatrix.m32).magnitude;
transform.localScale = scale;

Vector3 position;
position.x = localToWorldMatrix.m03;
position.y = localToWorldMatrix.m13;
position.z = localToWorldMatrix.m23;
transform.position = position;

Vector3 forward;
forward.x = localToWorldMatrix.m02;
forward.y = localToWorldMatrix.m12;
forward.z = localToWorldMatrix.m22;

Vector3 upwards;
upwards.x = localToWorldMatrix.m01;
upwards.y = localToWorldMatrix.m11;
upwards.z = localToWorldMatrix.m21;

transform.rotation = Quaternion.LookRotation(forward, upwards);

УВЕДОМЛЕНИЕ :

Это полезно, только если это вращение иперевод определяет местоположение вашей 5-й точки в мире в системе координат, которая активно используется ...

Если ваш поворот и перемещение означают что-то еще, вам придется сделать больше.Рад помочь в дальнейшем, если вы сможете точно определить, что означают этот поворот и перевод.

...