我有一个(世界)矩阵,它将平移,旋转和缩放应用到3D对象中。它是使用函数RotationQuaternion
(DirectXMath)创建的,参数XMQuaternionRotationRollPitchYaw
是通过调用XMMatrixDecompose(&Scale, &RotationQ, &Translation, Matrix);
创建的。然后将其与其他数据一起存储在文件中。
然后我需要恢复这些值,所以我可以使用这个函数将它分解为每个组件:
XMQuaternionToAxisAngle(&Axis, &Angle, RotationQ);
缩放和平移是向量,旋转是四元数。如果矩阵在单个轴上旋转对象,我可以使用它将四元数转换回角度:
float Roll = atan2(2.0*(F.x*F.y + F.z*F.w), 1 - 2 * (F.y*F.y + F.z*F.z));
float Pitch = asin(2.0*(F.x*F.z - F.w*F.y));
float Yaw = atan2(2.0*(F.x*F.w + F.y*F.z), 1 - 2 * (F.y*F.y + F.z*F.z));
工作正常。但是当它在两个或更多轴上旋转时,我该怎么做呢?有没有办法做到这一点?
PS:我不在乎输出角度是否与输入相同。他们只需要等同。
PS2:好的,所以我跟着Gene的链接(我已经看过那里了,但那段时间没找到我需要的东西)。我根据维基百科中的公式制作了这段代码:(90°, 0°, 90°)
在输出中我有不同的角度。输出似乎与(45°, 45°, 45°)
相同,但不适用于SELECT A, B FROM TUser
UNION
IF EXISTS(SELECT dataUserId FROM TUserData WHERE DataId = @dataId AND UserId = @userId)
BEGIN
SELECT @dataUserId = dataUserId FROM TUserData WHERE DataId = @dataId AND UserId = @userId
SELECT A, B FROM TUser WHERE UserId =()
。
答案 0 :(得分:1)
您有两种选择。
您仍然可以使用XMQuaternionToAxisAngle()函数,它将使用基数轴以外的轴。任何旋转都可以表示为围绕给定轴旋转的单个角度。
另一方面,如果你真的需要将它作为欧拉角,那么为你做这个没有好的功能。这些公式很容易获得。来自维基百科:
根据维基百科的定义,phi是围绕全局Z轴的角度,θ是围绕“法线轴”N的角度(通过局部原点并且与全局Z轴的平面正交的轴和最终局部Z轴 - 是的,它有点奇怪),psi是局部(即旋转)Z轴周围的角度。
如果我是一位更好的数学家,我可以帮助你将其转化为全局空间X,Y,Z旋转,但不幸的是,这超出了我的能力范围。
只要知道四元数和欧拉角之间没有严格的1-1相关性;例如,万向节锁意味着存在共享相同欧拉角的某些角度。真的要考虑你是否真的需要欧拉角 - 大多数情况下,轴角旋转可以以相同的方式工作,而没有欧拉角的重大问题。