代码之家  ›  专栏  ›  技术社区  ›  Ali Kanat

如何使用3x3旋转矩阵和平移向量应用变换?

  •  0
  • Ali Kanat  · 技术社区  · 7 年前

    我正在使用ARCore进行一个增强现实项目。每次启动以初始位置为原点的应用程序时,ARCore的坐标系都会发生变化。我在另一个坐标系中有5个点,我可以使用ARCore增强图像在Unity世界空间中找到其中4个位置。当然,这些点在我的另一个坐标系中有不同的值。我必须利用第五点在其他坐标系中的位置,找到它在统一世界空间中的位置。

    tutorial 为了实现这一点。但是由于Unity不支持我使用的3x3矩阵 Accord.NET 框架使用教程和Accord矩阵,我可以计算3x3 Rotation Translation 矢量。

    然而,当我试图将这一点应用到我的第五点时 TestObject.transform.Translate(AccordtoUnity(Translation),Space.World) 我有麻烦了。当最初的4个对象和参考对象位于同一方向时,我的翻译工作就完美了。但是,旋转参照对象时,此平移不起作用。这当然有道理,因为我只做了一次翻译。我的问题是如何将旋转和平移应用于我的第五点。或者有没有办法将我的3x3旋转矩阵和平移转换为单位 4x4Matrix Matrix4x4.MultiplyPoint3x4 . 或者可以将我的3x3旋转矩阵转换为 Quaternion 4x4Matrix.SetTRS . 我对这种转换有点困惑,因为 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 回复  |  直到 7 年前
        1
  •  1
  •   senden9    7 年前

    要使用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);
    

    通知 :

    仅当此旋转和平移定义了第五点在当前使用的坐标系中的世界位置时,此选项才有用。。。

    如果你的旋转和平移还有其他意义,你必须做得更多。如果您能准确定义此旋转和平移的含义,很高兴能进一步提供帮助。

        2
  •  1
  •   Dino Dini    7 年前

    可以将3x3旋转矩阵视为长度为1的三个向量,它们彼此成90度角。例如。:

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

    https://docs.unity3d.com/ScriptReference/Quaternion.LookRotation.html

    这将创建与矩阵对应的四元数。根据您的实际情况,您可能需要使用四元数的倒数,但本质上这就是您需要的。