我正在使用ARCore进行增强现实项目。每次启动应用程序时,ARCore的坐标系都会更改,并将初始位置作为原点。我在另一个坐标系中有5个点,我可以使用ARCore增强图像在Unity世界空间中找到这些位置中的4个。当然,这些点在我的其他坐标系中具有不同的值。我必须使用其在其他坐标系中的位置来找到第5个点在Unity世界空间中的位置。
我已遵循此tutorial来实现这一目标。但是由于Unity不支持3x3矩阵,因此我使用了Accord.NET框架。使用教程和Accord矩阵,我可以计算3x3 Rotation
矩阵和Translation
向量。
但是,当我尝试使用TestObject.transform.Translate(AccordtoUnity(Translation),Space.World)
将其应用于我的第五点时,我遇到了麻烦。当最初的4个对象和参考对象处于相同方向时,我的翻译效果很好。但是,当旋转参考对象时,此平移不起作用。这当然很有意义,因为我只做了翻译。我的问题是我该如何对第五点进行旋转和平移。还是有一种方法可以将我的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));
答案 0 :(得分:1)
要使用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点在世界上的位置时,这才有用...
如果轮换和翻译还有其他意义,则您需要做更多的事情。如果您可以准确定义此旋转和平移的含义,我们将为您提供进一步的帮助。
答案 1 :(得分:1)
如果我正确理解您的问题,则希望能够从3x3矩阵创建旋转四元数。
您可以将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
这将创建一个与您的矩阵相对应的四元数。根据您的实际情况,您可能需要使用四元数的倒数,但这实际上就是您所需要的。
请注意,您只需要前进和前进,因为正确的选择永远是这两者的叉积,并且不添加任何信息。另外请注意,矩阵是纯旋转矩阵(即没有缩放或倾斜),否则可能会得到意外的结果。