代码之家  ›  专栏  ›  技术社区  ›  cmann

将矩阵从右手坐标系更改为左手坐标系

  •  24
  • cmann  · 技术社区  · 17 年前


    x是左右的,y是前后的,z是上下的

    到左手系统,其中:
    x是左和右, Y 上下起伏。

    7 回复  |  直到 17 年前
        1
  •  28
  •   bleater    12 年前

    让我试着解释清楚一点。 我需要从Blender中导出一个模型,其中z轴朝上,到OpenGL中,y轴朝上。


    因为我已经交换了所有的y和z值,所以我使用的任何矩阵也需要翻转,以便它具有相同的效果。

    gamedev :

    如果矩阵如下所示:

    { rx, ry, rz, 0 }  
    { ux, uy, uz, 0 }  
    { lx, ly, lz, 0 }  
    { px, py, pz, 1 }
    

    { rx, rz, ry, 0 }  
    { lx, lz, ly, 0 }  
    { ux, uz, uy, 0 }  
    { px, pz, py, 1 }
    
        2
  •  14
  •   Gerrit    14 年前

    我想我理解你的问题,因为我目前正面临一个类似的问题。

    • 现在你有了一个Y向上的空间,你想知道如何处理你的旧矩阵。

    试试这个:

    有一个给定的世界矩阵

    Matrix world = ...  //space where Z is up
    

    此矩阵更改向量的Y和Z分量

    Matrix mToggle_YZ = new Matrix(
    {1, 0, 0, 0}
    {0, 0, 1, 0}
    {0, 1, 0, 0}
    {0, 0, 0, 1})
    

    您正在搜索以下内容:

    //same world transformation in a space where Y is up
    Matrix world2 = mToggle_YZ * world * mToggle_YZ;
    

    结果与下面发布的矩阵cmann相同。但我认为这更容易理解,因为它结合了以下计算:

    1) 开关Y和Z

    2) 做旧的改造

    3) 切换回Z和Y

        3
  •  11
  •   Paul Du Bois    9 年前

    通常情况下,您希望将矩阵从一组正向/向右/向上约定更改为另一组正向/向右/向上约定。例如,ROS使用z-up,而Unreal使用y-up。无论你是否需要进行惯用手翻转,这个过程都是有效的。

    我如何将ROS的前进/右转/上升概念转换为虚幻的前进/右转/上升概念 ".

    因此,创建在约定之间转换的矩阵是一项简单的工作。让我们假设我们已经做到了,现在我们已经做到了

    mat4x4 unrealFromRos = /* construct this by hand */;
    mat4x4 rosFromUnreal = unrealFromRos.inverse();
    

    假设OP有一个来自ROS的矩阵,她想在虚幻中使用它。她的原始矩阵采用ROS风格的向量,对其进行一些处理,并发出ROS风格的向量。她需要一个矩阵,它接受一个虚幻风格的向量,做同样的事情,并发出一个虚幻风格的向量。看起来是这样的:

    mat4x4 turnLeft10Degrees_ROS = ...;
    mat4x4 turnLeft10Degrees_Unreal = unrealFromRos * turnLeft10Degrees_ROS * rosFromUnreal;
    

    这其中的原因应该很清楚。你得到一个虚幻的向量,把它转换成ROS风格,现在你可以在上面使用ROS风格矩阵。这会给你一个ROS向量,你可以把它转换回虚幻的风格。

    Gerrit的回答并不十分笼统,因为在一般情况下,rosFromUnreal!=不切实际。如果你只是反转一个轴,这是正确的,但如果你正在做一些像转换X->Y、 Y->Z、 Z->我发现总是使用矩阵及其逆矩阵来进行这些约定切换,而不是尝试编写只翻转正确成员的特殊函数,这样的错误就更少了。

    这种矩阵运算 inverse(M) * X * M https://en.wikipedia.org/wiki/Matrix_similarity .

        4
  •  6
  •   bigcmos    10 年前

    我一直在致力于将Unity SteamVR_Utils.RigidTransform转换为ROS geometry_msgs/姿势,并需要将Unity左手坐标系转换为ROS右手坐标系。

    这就是我最后编写的转换坐标系的代码。

    var device = SteamVR_Controller.Input(index);
    // Modify the unity controller to be in the same coordinate system as ROS.
    Vector3 ros_position = new Vector3(
        device.transform.pos.z,
        -1 * device.transform.pos.x,
        device.transform.pos.y);
    Quaternion ros_orientation = new Quaternion(
        -1 * device.transform.rot.z,
        device.transform.rot.x,
        -1 * device.transform.rot.y,
        device.transform.rot.w);
    

    起初,我尝试使用@blater中的矩阵示例,但似乎无法使其发挥作用。我很想知道我是否在某个地方犯了错误。

    HmdMatrix44_t m = device.transform.ToHmdMatrix44();
    HmdMatrix44_t m2 = new HmdMatrix44_t();
    m2.m = new float[16];
    // left -> right
    m2.m[0] = m.m[0]; m2.m[1] = m.m[2]; m2.m[2] = m.m[1]; m2.m[3] = m.m[3];
    m2.m[4] = m.m[8]; m2.m[5] = m.m[10]; m2.m[6] = m.m[9]; m2.m[7] = m.m[7];
    m2.m[8] = m.m[4]; m2.m[9] = m.m[6]; m2.m[10] = m.m[5]; m2.m[11] = m.m[11];
    m2.m[12] = m.m[12]; m2.m[13] = m.m[14]; m2.m[14] = m.m[13]; m2.m[15] = m.m[15];
    
    SteamVR_Utils.RigidTransform rt = new SteamVR_Utils.RigidTransform(m2);
    
    Vector3 ros_position = new Vector3(
        rt.pos.x,
        rt.pos.y,
        rt.pos.z);
    Quaternion ros_orientation = new Quaternion(
        rt.rot.x,
        rt.rot.y,
        rt.rot.z,
        rt.rot.w);
    
        5
  •  1
  •   tugudum tugudum    17 年前

    如果从左边乘(例如:Ax=x',其中A是矩阵,x'是变换点),只需交换第二列和第三列。 如果从右边乘(例如:xA=x'),则需要交换第二行和第三行。

    如果你的点是列向量,那么你在第一个场景中。

        6
  •  0
  •   Yesman    13 年前

    将sin因子更改为-sin,以便在右手和左手之间交换坐标空间

        7
  •  -15
  •   jagdit jagdit    17 年前

    因为这似乎是一个家庭作业的答案;我给你一个提示:你能做些什么使矩阵的行列式为负?

    进一步(更好的提示):既然你已经知道如何对单个向量进行转换,你不认为你能够对跨越矩阵表示的转换的基向量进行转换吗?(请记住,矩阵可以视为对单位向量元组执行的线性转换)