You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

球体旁固定距离飞行器自由移动的优化方案咨询

球面固定距离下的飞机二维操控移动优化

需要操控飞机始终与球心保持固定距离,实现前后左右自由移动(二维操控映射到三维球面坐标)。当前采用球坐标系实现的效果不佳,仅能让飞机在固定轨道环上移动,无法达到预期的自由操控体验。

当前实现代码

function moveShipInCircle(ship, movement) {
  const playerSpeed = 0.1;
  const TEMP_RAD = EARTH_RADIUS + 0.2;
  const TEMP_CAM_RADIUS = TEMP_RAD + 0.2;
  const radian = movement.firstAngle * Math.PI / 180;
  const elevation = movement.secondAngle * Math.PI / 180;
  const x = TEMP_RAD * Math.cos(radian);
  const y = TEMP_RAD * Math.sin(radian) * Math.sin(elevation);
  const z = TEMP_RAD * Math.sin(radian) * Math.cos(elevation);
  const xC = TEMP_CAM_RADIUS * Math.cos(radian);
  const yC = TEMP_CAM_RADIUS * Math.sin(radian) * Math.sin(elevation);
  const zC = TEMP_CAM_RADIUS * Math.sin(radian) * Math.cos(elevation);
  if (movement.left) {
    movement.firstAngle += playerSpeed;
  }
  if (movement.right) {
    movement.firstAngle -= playerSpeed;
  }
  if (movement.forward) {
    movement.secondAngle -= playerSpeed;
  }
  if (movement.backward) {
    movement.secondAngle += playerSpeed;
  }
  unit.position.set(x, y, z);

  camera.position.lerp(ship.position, 1.3);
  camera.position.set(xC, yC, zC);
}

优化方案:基于局部切线平面的球面移动

核心思路:以飞机当前位置的局部切线平面为基准处理二维输入,将移动向量投影到球面上,始终保持与球心的固定距离。这种方式更符合操作直觉,不会局限于固定轨道。

具体实现步骤

  • 计算局部坐标系:
    首先获取球心到飞机的径向向量,再以此为基准生成切线平面的两个正交轴(右方向和前方向),作为二维操控的参考轴。
  • 生成移动向量:根据左右、前后的输入,在切线平面内生成对应的移动向量。
  • 投影到球面:将飞机当前位置加上移动向量后,归一化再乘以固定半径,确保距离球心不变。
  • 相机跟随优化:基于飞机位置和径向向量计算相机偏移,保持相机与飞机的相对位置并看向飞机。

完整优化代码

function moveShipOnSphere(ship, movement) {
  const playerSpeed = 0.1;
  const TEMP_RAD = EARTH_RADIUS + 0.2;
  const TEMP_CAM_RADIUS = TEMP_RAD + 0.2;

  // 计算球心到飞机的径向向量(归一化)
  const radial = ship.position.clone().normalize();

  // 生成切线平面的正交轴:处理极点等特殊位置的向量共线问题
  let referenceVec = new THREE.Vector3(0, 1, 0);
  if (Math.abs(radial.dot(referenceVec)) > 0.99) {
    referenceVec = new THREE.Vector3(1, 0, 0);
  }
  const rightDir = radial.clone().cross(referenceVec).normalize();
  const forwardDir = rightDir.clone().cross(radial).normalize();

  // 根据输入生成切线平面内的移动向量
  const moveVector = new THREE.Vector3();
  if (movement.left) moveVector.sub(rightDir).multiplyScalar(playerSpeed);
  if (movement.right) moveVector.add(rightDir).multiplyScalar(playerSpeed);
  if (movement.forward) moveVector.add(forwardDir).multiplyScalar(playerSpeed);
  if (movement.backward) moveVector.sub(forwardDir).multiplyScalar(playerSpeed);

  // 更新飞机位置,保持与球心的固定距离
  const tempPosition = ship.position.clone().add(moveVector);
  tempPosition.normalize().multiplyScalar(TEMP_RAD);
  ship.position.copy(tempPosition);

  // 更新相机位置,保持跟随并看向飞机
  const cameraOffset = radial.clone().multiplyScalar(TEMP_CAM_RADIUS - TEMP_RAD);
  camera.position.copy(ship.position.clone().add(cameraOffset));
  camera.lookAt(ship.position);
}

方案优势

  • 操作直觉化:前后左右移动基于飞机当前的局部切线方向,完全摆脱固定轨道限制
  • 实现简洁:无需复杂的球面展开映射,通过基础向量运算即可完成
  • 全位置适配:自动处理南北极点等特殊位置的向量计算问题

内容的提问来源于stack exchange,提问作者Proxy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:05:54