经纬志
首页 / three.js / API 文档

Quaternion

先看结论

四元数。用四个分量表示三维旋转,没有万向锁,插值平滑, 是 Object3D 内部真正存储旋转的字段。

最后验证 2026-11-03 · three.js 0.160.0 · 更新 2026-10-29 · 引用本文
new THREE.Quaternion(x, y, z, w)

构造参数

参数默认说明
x0虚部第一分量
y0虚部第二分量
z0虚部第三分量
w1实部,默认值组合成单位四元数,表示不旋转

属性

属性说明
x / y / z / w四个分量,直接赋值不会自动归一化
isQuaternion恒为 true
_onChangeCallback内部回调,Object3D 用它同步欧拉角

方法

方法说明
set(x, y, z, w)设置四个分量
setFromAxisAngle(axis, angle)绕单位轴旋转指定弧度
setFromEuler(euler)由欧拉角转换
setFromRotationMatrix(matrix)由纯旋转矩阵转换
setFromUnitVectors(from, to)求把方向 A 转到方向 B 的最短旋转
angleTo(other)两个旋转之间的夹角,弧度
rotateTowards(other, step)朝目标旋转最多 step 弧度
invert()求逆旋转
conjugate()共轭,单位四元数下等同求逆
dot(other)点积,可用于判断朝向是否接近
length() / lengthSq()模长与模长平方
normalize()归一化,累乘后必须调用
slerp(other, t)球面插值,t 从 0 到 1
slerpQuaternions(a, b, t)两个四元数之间插值,结果写入自身
multiply(q) / premultiply(q)右乘与左乘,顺序不同结果不同
multiplyQuaternions(a, b)计算 a × b 写入自身
equals(q)逐分量比较
clone() / copy(q)复制

示例:让物体朝向目标

const forward = new THREE.Vector3(0, 0, 1);
const direction = new THREE.Vector3()
  .subVectors(target, mesh.position)
  .normalize();

mesh.quaternion.setFromUnitVectors(forward, direction);

// 平滑转向,不写死目标角度
const targetQuat = mesh.quaternion.clone();
mesh.quaternion.slerp(targetQuat, 0.15);

示例:绕轴自转

const axis = new THREE.Vector3(0, 1, 0).normalize();
const delta = new THREE.Quaternion().setFromAxisAngle(axis, 0.01);

// 每帧叠加一点旋转
mesh.quaternion.multiply(delta);
mesh.quaternion.normalize();   // 长时间累乘后防止漂移

与欧拉角的关系

Object3D 同时维护 rotation(欧拉角)与 quaternion,两者通过回调自动同步。改任意一个, 另一个立即更新,不需要手动转换。需要连续插值时用四元数, 需要按坐标轴直接设定角度时用欧拉角更方便。

手动赋值后要归一化。quaternion.x = 0.5 这类写法 会破坏单位长度,累积后出现缩放与扭曲。要么用 set、setFromAxisAngle 这类方法, 要么改完调用 normalize()。

引用本文

经纬志(2026)。《Quaternion》。https://www.jingweizhi.com/three/api/quaternion.html(访问日期 2026-11-03)。