我的对象是在软件中的不同位置逐步接收4个转换。我们使用CAD引擎库,因此我有自定义对象进行转换。
我需要从一个物体平移和旋转的矩阵中恢复,这样我就可以在旋转后创建一个新的矩阵。
// create a transformation object, very simple 1 translation and 3 rotations
var t = new Translation(10, 15, 20)
* new Rotation(10d.ToRadian(), Vector3D.AxisX)
* new Rotation(10d.ToRadian(), Vector3D.AxisY)
* new Rotation(10d.ToRadian(), Vector3D.AxisZ);
// convert to the windows Matrix3D
var m1 = ToWindowsMatrix(t);
// decompose the matrix to get one random possibility of combinaison of rotation x, y and Z to obtain the same result
var rx = Math.Atan2(m1.M32, m1.M33).ToDegree();
var ry = Math.Atan2(-m1.M31, Math.Sqrt(Math.Pow(m1.M32, 2) + Math.Pow(m1.M33, 2))).ToDegree();
var rz = Math.Atan2(m1.M21, m1.M11).ToDegree();
Source for formula to get rotation x,y and z:
// create a transformation object, in the same order, hardcoded translate but use the computed equivalent rotation x,y and z
var t2 = new Translation(10, 15, 20)
* new Rotation(rx.ToRadian(), Vector3D.AxisX)
* new Rotation(ry.ToRadian(), Vector3D.AxisY)
* new Rotation(rz.ToRadian(), Vector3D.AxisZ);
// convert to the windows Matrix3D
var m2 = ToWindowsMatrix(t2);
如果我拍摄一个3d对象并应用t2
的变换,则与t1
给出的对象的旋转相比完全偏离。
我绝对需要获得分解值,因为整个系统使用6个参数(原点x,y,z和旋转x,y,z)显示对象,然后创建一个单位矩阵并应用平移和3旋转。 / p>
我已经工作了大约7个小时,我发现如果我只在t1
上进行一次轮换,即"旋转X 90"并且在t2
上我仍然使用旋转DO匹配的计算值应用所有旋转。所以我觉得转型的顺序需要按照特定的顺序,但我不能改变它。所以这意味着我需要获得旋转x,y和z,以便通过应用Translate * RotX * RotY * RotZ
来匹配。
我可能错过了什么?我也发现了一些mathlab样本,但到目前为止公式都是一样的。
答案 0 :(得分:0)
一段时间后想出如何获得矩阵的XYZ旋转。问题是欧拉角在ZYX旋转中返回。需要执行更多操作才能从中提取XYZ。
public static double[] GetXYZRotation(this Matrix3D matrix)
{
// get the euler angles
var eulerX = Math.Atan2(matrix.M32, matrix.M33).ToDegree();
var eulerY = Math.Atan2(-matrix.M31, Math.Sqrt(Math.Pow(matrix.M32, 2) + Math.Pow(matrix.M33, 2))).ToDegree();
var eulerZ = Math.Atan2(matrix.M21, matrix.M11).ToDegree();
// create transformation of the euler angle to get a matrix. euler rotation is ZYX
var eulerMatrix = (new Translation(matrix.OffsetX,matrix.OffsetY,matrix.OffsetZ)
* new Rotation(eulerZ.ToRadian(), Vector3D.AxisZ)
* new Rotation(eulerY.ToRadian(), Vector3D.AxisY)
* new Rotation(eulerX.ToRadian(), Vector3D.AxisX)).ToWindowsMatrix();
// get the Alpha Beta and Gamma of the euler matrix
var beta = Math.Atan2(eulerMatrix.M13, Math.Sqrt(Math.Pow(eulerMatrix.M11, 2d) + Math.Pow(-eulerMatrix.M12, 2d)));
var alpha = Math.Atan2(-(eulerMatrix.M23 / Math.Cos(beta)), eulerMatrix.M33 / Math.Cos(beta));
var gamma = Math.Atan2(-(eulerMatrix.M12 / Math.Cos(beta)), eulerMatrix.M11 / Math.Cos(beta));
// get the XYZ rotation per euler computed alpha beta gamma
var rotationX = alpha.ToDegree();
var rotationY = beta.ToDegree();
var rotationZ = gamma.ToDegree();
return new[] { rotationX, rotationY, rotationZ };
}
所以我需要计算以相反顺序应用欧拉角的矩阵:Z然后是Y然后是X并从那里计算出α,β和Gamma,它们可以检索XYZ旋转值