首页 / three.js / API 文档
Quaternion
先看结论
四元数。用四个分量表示三维旋转,没有万向锁,插值平滑,
是 Object3D 内部真正存储旋转的字段。
new THREE.Quaternion(x, y, z, w)
构造参数
| 参数 | 默认 | 说明 |
|---|---|---|
x | 0 | 虚部第一分量 |
y | 0 | 虚部第二分量 |
z | 0 | 虚部第三分量 |
w | 1 | 实部,默认值组合成单位四元数,表示不旋转 |
属性
| 属性 | 说明 |
|---|---|
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)。