threejs方向向量和速度向量学习

一、方向向量 (Direction Vector)

1. 概念
  • 方向向量表示物体在 3D 空间中的朝向,通常是一个单位向量(长度为 1)。

  • 在 Three.js 中,物体的默认前方是 +Z 方向,可通过 Object3D 的 getWorldDirection() 获取。

2. 获取物体的方向向量
const direction = new THREE.Vector3();
object.getWorldDirection(direction); // 获取物体的正前方方向向量
3. 旋转物体改变方向
// 通过旋转物体改变方向向量
object.rotation.y += 0.01; // 绕 Y 轴旋转
object.getWorldDirection(direction); // 更新后的方向向量
4. 应用示例:箭头指示方向
const arrowHelper = new THREE.ArrowHelper(
  new THREE.Vector3(0, 0, 1), // 初始方向
  object.position, 
  5, // 箭头长度
  0xff0000
);
scene.add(arrowHelper);

// 每帧更新箭头方向
function animate() {
  object.getWorldDirection(direction);
  arrowHelper.setDirection(direction);
}

二、速度向量 (Velocity Vector)

1. 概念
  • 速度向量是物体运动的速率和方向的组合,通常表示为 velocity = speed * direction

  • 速度向量的长度(模)代表实际速度值。

2. 定义速度向量
const velocity = new THREE.Vector3();
const speed = 0.1;
3. 结合方向向量移动物体
// 沿当前方向移动
object.getWorldDirection(direction);
velocity.copy(direction).multiplyScalar(speed);
object.position.add(velocity);
4. 时间补偿(Delta Time)

为保证不同帧率下的速度一致,需使用时间增量:

let deltaTime = 0;
let clock = new THREE.Clock();

function animate() {
  deltaTime = clock.getDelta();
  
  object.getWorldDirection(direction);
  velocity.copy(direction).multiplyScalar(speed * deltaTime);
  object.position.add(velocity);
}

三、综合示例:键盘控制运动

1. 初始化物体和速度
const cube = new THREE.Mesh(
  new THREE.BoxGeometry(),
  new THREE.MeshBasicMaterial({ color: 0x00ff00 })
);
scene.add(cube);

const velocity = new THREE.Vector3();
const speed = 2; // 单位:米/秒
const rotationSpeed = Math.PI / 4; // 45度/秒
2. 键盘事件监听
const keyStates = { w: false, a: false, s: false, d: false };

document.addEventListener('keydown', (e) => {
  if (keyStates.hasOwnProperty(e.key)) keyStates[e.key] = true;
});
document.addEventListener('keyup', (e) => {
  if (keyStates.hasOwnProperty(e.key)) keyStates[e.key] = false;
});
3. 更新逻辑
function update(deltaTime) {
  const direction = new THREE.Vector3();
  cube.getWorldDirection(direction);

  // 旋转控制
  if (keyStates.a) cube.rotation.y += rotationSpeed * deltaTime;
  if (keyStates.d) cube.rotation.y -= rotationSpeed * deltaTime;

  // 移动控制
  let moveDirection = new THREE.Vector3();
  if (keyStates.w) moveDirection.z = -1; // Three.js 前方是 +Z,按键向前需反向
  if (keyStates.s) moveDirection.z = 1;

  // 应用方向旋转
  moveDirection.applyQuaternion(cube.quaternion);
  moveDirection.normalize();

  // 更新位置
  cube.position.add(moveDirection.multiplyScalar(speed * deltaTime));
}

四、常见问题

1. 方向向量未归一化
// 错误:非单位向量会导致速度异常
velocity.copy(direction).multiplyScalar(speed); 

// 正确:确保方向向量是单位向量
velocity.copy(direction.normalize()).multiplyScalar(speed);
2. 忽略四元数更新

旋转物体后需更新四元数:

cube.rotation.y += angle;
cube.updateMatrixWorld(); // 强制更新世界矩阵
cube.getWorldDirection(direction); // 获取最新方向
3. 局部坐标系与全局坐标系
  • 使用 object.localToWorld() 转换局部方向到全局坐标系:

  • const localDirection = new THREE.Vector3(0, 0, -1); // 物体局部前方
    const globalDirection = localDirection.applyMatrix4(object.matrixWorld);

    通过方向向量控制物体的朝向,结合速度向量实现运动,是游戏和交互应用的基础。通过键盘/鼠标输入调整方向,再按帧更新位置,即可实现复杂的运动效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值