如何计算3D物体指向另一物体坐标所需的三轴旋转角度?
3D物体指向目标点的通用旋转计算方法
先明确前提规则
计算前必须统一坐标系和旋转顺序,否则结果必然出错:
- 坐标系约定:默认采用和Unity/Unreal一致的右手坐标系:X轴向右,Y轴向上,Z轴向后,物体初始正前方为**-Z方向**;若你的坐标系是Z轴向前,后续向量计算需将Z分量的符号反转。
- 欧拉角旋转顺序:这里使用最常用的Y-X-Z顺序(先绕Y轴转航向,再绕X轴转俯仰,最后绕Z轴转滚转),不同旋转顺序的计算逻辑差异很大,请勿混淆。
步骤1:计算指向目标的方向向量
假设物体当前位置为 P(x₁,y₁,z₁),目标点为 Q(x₂,y₂,z₂),先计算从物体到目标的世界空间方向向量:
V = (x₂ - x₁, y₂ - y₁, z₂ - z₁)
对该向量做归一化处理(转换为长度为1的单位向量),避免距离远近干扰旋转计算:
V_normalized = V / √[(x₂-x₁)² + (y₂-y₁)² + (z₂-z₁)²]
步骤2:计算目标姿态的欧拉角
我们需要让物体的前向轴(局部-Z轴)对齐上述的 V_normalized,分三个角度逐一计算:
俯仰角(Pitch,绕X轴旋转,控制抬头/低头)
该角度对应方向向量的垂直高度差,直接用反正弦函数计算:
pitch = arcsin(V_normalized.y)
结果范围为 -π/2 到 π/2(即-90°到90°),完全符合抬头低头的合理角度范围。
航向角(Yaw,绕Y轴旋转,控制左右转向)
先将方向向量投影到水平面上(去除Y分量),再用反正切2函数计算左右转向角度:
yaw = arctan2(-V_normalized.z, V_normalized.x)
此处加负号是因为我们约定前向为-Z轴,arctan2的结果范围是 -π 到 π(即-180°到180°),可直接作为航向角使用,无需额外调整。
滚转角(Roll,绕Z轴旋转,控制侧翻)
若无特殊需求(比如保持物体水平),直接设为0即可;若需保留物体当前的侧翻状态,直接沿用原有滚转角即可。
步骤3:计算旋转增量(从当前姿态到目标姿态的角度差)
若你需要的不是绝对旋转角度,而是相对于当前姿态需要转动的角度差值,按以下步骤操作:
- 将当前的欧拉角(假设α为绕X轴的旋转角,β为绕Y轴的旋转角,γ为绕Z轴的旋转角)转换为旋转矩阵;
- 将步骤2算出的目标欧拉角(pitch, yaw, roll)也转换为旋转矩阵;
- 计算增量旋转矩阵:
M_delta = M_target * M_current的逆矩阵(矩阵乘法顺序需与旋转顺序对应,Y-X-Z顺序下需从右到左相乘); - 将增量矩阵转换回欧拉角,得到的就是需要转动的角度差值。
欧拉角转旋转矩阵(Y-X-Z顺序)
直接套用以下现成计算式即可:
- 绕Y轴转yaw角的矩阵
R_y:
[ cos(yaw) 0 sin(yaw) ] [ 0 1 0 ] [ -sin(yaw) 0 cos(yaw) ]
- 绕X轴转pitch角的矩阵
R_x:
[ 1 0 0 ] [ 0 cos(pitch) -sin(pitch) ] [ 0 sin(pitch) cos(pitch) ]
- 绕Z轴转roll角的矩阵
R_z:
[ cos(roll) -sin(roll) 0 ] [ sin(roll) cos(roll) 0 ] [ 0 0 1 ]
总旋转矩阵 M = R_z * R_x * R_y(因旋转顺序为Y→X→Z,矩阵乘法需反向进行)。
旋转矩阵转欧拉角(Y-X-Z顺序)
从旋转矩阵中提取三个角度的计算式:
pitch = arcsin(-M[2][1]) yaw = arctan2(M[0][1], M[1][1]) roll = arctan2(M[2][0], M[2][2])
注意矩阵是行优先还是列优先,需与生成矩阵时的规则保持一致,避免混淆。
特殊情况处理
- 若物体与目标点重合(方向向量长度为0):可保持当前姿态或返回0旋转,此时无明确朝向可指向;
- 若方向向量为纯垂直方向(X和Z分量均为0):航向角可保留当前值,此时无左右方向差异。
内容的提问来源于stack exchange,提问作者JunEternal
相关产品推荐
相关产品推荐

