基于Pitch、Yaw、Roll与距离的纯JavaScript 3D移动计算问题
解决方案:纳入ROLL角度的3D平移计算
核心逻辑
要让移动基于机身自身的局部坐标系(而非世界坐标系),需将机身的局部向前方向(局部Y轴)通过ROLL、PITCH、YAW三个旋转转换为世界坐标系下的向量,再乘以移动速度得到最终平移量。这里的旋转顺序为ROLL(绕局部Y轴)→ PITCH(绕局部X轴)→ YAW(绕局部Z轴),完全贴合飞行模拟器的操作逻辑:
- ROLL改变机身倾斜角度,直接影响俯仰的轴向
- PITCH基于倾斜后的机身横向轴实现抬头/低头
- YAW基于机身的垂直轴完成转向
计算公式
假设:
xrot:俯仰角(PITCH,弧度)yrot:滚转角(ROLL,弧度)zrot:偏航角(YAW,弧度)vel:每帧移动距离
世界坐标系下的三轴平移量计算公式为:
xmov = vel * (-cos(yrot)*sin(zrot) - sin(xrot)*sin(yrot)*cos(zrot)) ymov = vel * (cos(xrot)*cos(zrot)) zmov = vel * (sin(xrot)*cos(yrot) - cos(xrot)*sin(yrot)*sin(zrot))
公式验证
- 当
yrot=0(无滚转),公式退化为你原有的计算逻辑,符合直立状态下的移动需求 - 当
yrot=90°(向右滚转90度)且xrot=90°(抬头90度),计算结果为xmov=-vel、ymov=0、zmov=0,即机头朝向世界X轴负方向(西),完全符合滚转后抬头的飞行逻辑
JavaScript代码实现
注意:JavaScript的三角函数使用弧度,若你的角度是度数,需先转换为弧度:
// 角度转弧度工具函数(如果需要) const degToRad = (deg) => deg * Math.PI / 180; const xrot = degToRad(pitchDegrees); const yrot = degToRad(rollDegrees); const zrot = degToRad(yawDegrees); // 预计算三角函数值,提升性能 const cosX = Math.cos(xrot); const sinX = Math.sin(xrot); const cosY = Math.cos(yrot); const sinY = Math.sin(yrot); const cosZ = Math.cos(zrot); const sinZ = Math.sin(zrot); // 计算世界坐标系下的移动向量 const xmov = vel * (-cosY * sinZ - sinX * sinY * cosZ); const ymov = vel * (cosX * cosZ); const zmov = vel * (sinX * cosY - cosX * sinY * sinZ);
逻辑补充
- 计算结果直接输出世界坐标系下的平移量,可直接用于更新物体位置,无需额外转换
- 所有旋转均基于机身局部轴,滚转后俯仰、偏航的控制逻辑完全贴合飞行模拟器操作习惯,彻底解决倒飞/倾斜时移动逻辑混乱、碰撞检测失效的问题
内容的提问来源于stack exchange,提问作者jdmayfield
相关产品推荐
相关产品推荐

