- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用欧拉角按 XYZ 的顺序旋转 n 个 3D 形状,这意味着对象首先沿 X
轴旋转,然后是 Y
,然后是 Z
。我想将欧拉角转换为四元数,然后使用一些 [最好] Python 代码或一些伪代码或算法从四元数获得相同的欧拉角。下面,我有一些代码将欧拉角转换为四元数,然后将四元数转换为欧拉角。但是,这并没有给我相同的欧拉角。
我认为问题在于我不知道如何将偏航、俯仰和滚转 关联到 X、Y 和 Z 轴。另外,我不知道如何更改代码中的转换顺序以正确地将欧拉角转换为四元数,然后将四元数转换为欧拉角,以便我能够获得相同的欧拉角。有人可以帮我解决这个问题吗?
这是我使用的代码:
此函数将欧拉角转换为四元数:
def euler_to_quaternion(yaw, pitch, roll):
qx = np.sin(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) - np.cos(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)
qy = np.cos(roll/2) * np.sin(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.cos(pitch/2) * np.sin(yaw/2)
qz = np.cos(roll/2) * np.cos(pitch/2) * np.sin(yaw/2) - np.sin(roll/2) * np.sin(pitch/2) * np.cos(yaw/2)
qw = np.cos(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)
return [qx, qy, qz, qw]
这会将四元数转换为欧拉角:
def quaternion_to_euler(x, y, z, w):
import math
t0 = +2.0 * (w * x + y * z)
t1 = +1.0 - 2.0 * (x * x + y * y)
X = math.degrees(math.atan2(t0, t1))
t2 = +2.0 * (w * y - z * x)
t2 = +1.0 if t2 > +1.0 else t2
t2 = -1.0 if t2 < -1.0 else t2
Y = math.degrees(math.asin(t2))
t3 = +2.0 * (w * z + x * y)
t4 = +1.0 - 2.0 * (y * y + z * z)
Z = math.degrees(math.atan2(t3, t4))
return X, Y, Z
我按如下方式使用它们:
import numpy as np
euler_Original = np.random.random(3) * 360).tolist() # Generate random rotation angles for XYZ within the range [0, 360)
quat = euler_to_quaternion(euler_Original[0], euler_Original[1], euler_Original[2]) # Convert to Quaternion
newEulerRot = quaternion_to_euler(quat[0], quat[1], quat[2], quat[3]) #Convert the Quaternion to Euler angles
print (euler_Original)
print (newEulerRot)
打印语句为 euler_Original
和 newEulerRot
打印不同的数字,我不希望出现这种情况。例如,如果 euler_original
包含以弧度表示的 (0.2, 1.12, 2.31)
这样的数字,我得到这个四元数 --> [0.749, 0.290, -0.449, 0.389]
并将四元数转换为欧拉角得到这个 --> (132.35, 64.17, 11.45)
这是非常错误的。我想知道如何解决这个问题?
虽然我有兴趣通过更改上面的代码来使其工作,但是,我更愿意学习如何正确设置方程式。这样我就知道如何获得正确的四元数,即使应用欧拉角的旋转顺序(XYZ --> YZX 等)发生了变化。
最佳答案
我们可以使用 scipy.spatial.transform
中的 Rotation
。
from scipy.spatial.transform import Rotation
# Create a rotation object from Euler angles specifying axes of rotation
rot = Rotation.from_euler('xyz', [90, 45, 30], degrees=True)
# Convert to quaternions and print
rot_quat = rot.as_quat()
print(rot_quat)
结果是:
[ 0.56098553 0.43045933 -0.09229596 0.70105738]
然后,你也可以在欧拉角中得到它:
print(rot.as_euler('xyz', degrees=True))
结果是:
[90. 45. 30.]
作为最后的检查,根据上面计算的四元数创建一个旋转对象并将其作为欧拉角:
rot = Rotation.from_quat(rot_quat)
# Convert the rotation to Euler angles given the axes of rotation
print(rot.as_euler('xyz', degrees=True))
结果是:
[90. 45. 30.]
关于python - 如何将欧拉角转换为四元数并从四元数返回相同的欧拉角?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53033620/
我有一个第一人称相机 Controller 实现如下: float rotSpeed = 20.0f; xRotation += deltaPos.y * rotSpeed * Time.deltaT
我正在编写一个程序,它加载一个包含场景描述的文件,然后使用 OpenGL 显示它。我将 GLM 用于我的所有数学运算。场景文件中的旋转以四元数格式存储。我的场景管理系统以欧拉角的形式对对象进行旋转,这
我想要实现的效果是从相机的 pointOfView 位置指向一个箭头,在 x 和 z 轴上与场景(和重力)对齐,但指向与相机相同的方向。它可能看起来像这样: 现在,我将其欧拉角 x 和 z 设置为 0
我是一名优秀的程序员,十分优秀!