我想从右手系统更改4x4矩阵,其中:
x是左右,y是前后,z是上下
到左手系统,其中:
x是左右,z是前后,y是上下.
对于矢量,它很容易,只需交换y和z值,但是如何为矩阵做?
cma*_*ann 26
让我试着更好地解释一下.我需要将模型从Blender中导出,其中z轴朝上,进入OpenGL,y轴朝上.
对于每个坐标(x,y,z),它很简单; 只需交换y和z值:(x,z,y).
因为我已经交换了所有y和z值,所以我使用的任何矩阵也需要翻转,以便它具有相同的效果.
经过大量搜索后,我终于在gamedev找到了解决方案:
如果矩阵看起来像这样:
{ rx, ry, rz, 0 }
{ ux, uy, uz, 0 }
{ lx, ly, lz, 0 }
{ px, py, pz, 1 }
Run Code Online (Sandbox Code Playgroud)
要从左到右或从右到左更改它,请按以下方式将其翻转:
{ rx, rz, ry, 0 }
{ lx, lz, ly, 0 }
{ ux, uz, uy, 0 }
{ px, pz, py, 1 }
Run Code Online (Sandbox Code Playgroud)
Ger*_*rit 13
我想我理解你的问题,因为我目前正面临类似的问题.
您从世界矩阵开始,该矩阵在Z向上的空间中转换向量(例如,世界矩阵).
现在你有一个空间,Y在哪里,你想知道如何处理你的旧矩阵.
试试这个:
有一个给定的世界矩阵
Matrix world = ... //space where Z is up
Run Code Online (Sandbox Code Playgroud)
此矩阵更改Vector的Y和Z分量
Matrix mToggle_YZ = new Matrix(
{1, 0, 0, 0}
{0, 0, 1, 0}
{0, 1, 0, 0}
{0, 0, 0, 1})
Run Code Online (Sandbox Code Playgroud)
您正在搜索此内容:
//same world transformation in a space where Y is up
Matrix world2 = mToggle_YZ * world * mToggle_YZ;
Run Code Online (Sandbox Code Playgroud)
结果是下面发布的相同矩阵cmann.但我认为这更容易理解,因为它结合了以下计算:
1)开关Y和Z.
2)做旧的转变
3)切换回Z和Y.
12年后,由于缺乏对轴方向的描述,这个问题仍然具有误导性。
问的问题大概应该是如何转换到
。
@cmann 的答案对于上述问题是正确的,@Gerrit 解释了原因。我将解释如何以图形方式在变换矩阵上获得该转换。
我们应该清楚,正交矩阵既包含旋转矩阵又包含点反射(只有点反射会改变左手和右手之间的坐标系)。因此它们可以表示为 4x4 矩阵并服从变换矩阵乘法顺序。“复合变换的矩阵是通过将各个变换的矩阵相乘获得的。”
到
包含旋转矩阵和点反射。但我们可以通过图形方式得到复合变换。
根据上图,变换后,在 RhC(右手坐标)中将是
在 LfC 中如下
在哪里是将以上 RhC 表示的点转换为 LhC 表示的点的变换。现在我们可以转换
(
) 到
(
)按照下图所示的变换矩阵乘法顺序。
结果与@cmann 的相同。
结果:
我一直在将Unity SteamVR_Utils.RigidTransform转换为ROS geometry_msgs / Pose,需要将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);
Run Code Online (Sandbox Code Playgroud)
最初,我尝试使用@bleater中的矩阵示例,但似乎无法正常工作。很想知道我是否在某个地方犯了错误。
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);
Run Code Online (Sandbox Code Playgroud)
通常,您希望将矩阵从一组向前/向右/向上约定更改为另一组向前/向右/向上约定。例如,ROS使用z-up,而Unreal使用y-up。无论您是否需要进行惯用惯性翻转,该过程均有效。
注意,短语“从右手切换到左手”是不明确的。有很多左手向前/向右/向上约定。例如:forward = z,right = x,up = y; 和正向= x,向右= y,向上= z。您应该真正将其视为“ 我如何将ROS的前向/右/向上概念转换为虚幻的前向/右/向上概念 ”。
因此,创建在约定之间转换的矩阵是一项简单的工作。假设我们已经做到了,现在我们有了
mat4x4 unrealFromRos = /* construct this by hand */;
mat4x4 rosFromUnreal = unrealFromRos.inverse();
Run Code Online (Sandbox Code Playgroud)
假设OP具有一个来自ROS的矩阵,她想在Unreal中使用它。她的原始矩阵采用ROS样式的矢量,对其进行处理,然后发出ROS样式的矢量。她需要一个采用虚幻风格矢量的矩阵,做同样的事情,然后发出虚幻风格矢量。看起来像这样:
mat4x4 turnLeft10Degrees_ROS = ...;
mat4x4 turnLeft10Degrees_Unreal = unrealFromRos * turnLeft10Degrees_ROS * rosFromUnreal;
Run Code Online (Sandbox Code Playgroud)
应该很清楚为什么这行得通。您获取一个虚幻矢量,将其转换为ROS样式,现在您可以在其上使用ROS样式的矩阵。这为您提供了一个ROS向量,您可以将其转换回虚幻风格。
Gerrit的回答不是很全面,因为在一般情况下,rosFromUnreal!= unrealFromRos。如果仅反转单个轴,则为true;如果进行诸如X-> Y,Y-> Z,Z-> X的转换,则为true。我发现,总是使用矩阵及其逆矩阵来进行这些约定切换,而不是尝试编写仅翻转正确成员的特殊函数,这样的出错率较小。
这种矩阵运算的inverse(M) * X * M
出现很多。您可以将其视为“基础变更”操作。要了解更多信息,请参见https://en.wikipedia.org/wiki/Matrix_similarity。
归档时间: |
|
查看次数: |
44110 次 |
最近记录: |