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