四元数

Quaternion 是3D旋转的核心表示方式,相比欧拉角不会出现万向节死锁问题,且支持平滑插值。位于 laya/maths/Quaternion.ts

一、概述

图1-1

(图1-1)

四元数由 (x, y, z, w) 四个分量组成。相比欧拉角的优势:

  • 无万向节死锁:欧拉角在特定旋转角度下会丢失一个自由度
  • 平滑插值:支持球面线性插值(Slerp),旋转角速度恒定
  • 高效组合:四元数乘法比矩阵乘法更轻量
// 创建单位四元数(无旋转)
let q = new Laya.Quaternion(0, 0, 0, 1);

// 预定义常量
Laya.Quaternion.DEFAULT;   // 单位四元数 (0,0,0,1)
Laya.Quaternion.NAN;       // 无效四元数

二、创建四元数

2.1 从欧拉角

let q = new Laya.Quaternion();
// yaw(Y轴偏航)、pitch(X轴俯仰)、roll(Z轴翻滚),单位弧度
Laya.Quaternion.createFromYawPitchRoll(yaw, pitch, roll, q);

2.2 从轴角

let axis = new Laya.Vector3(0, 1, 0);
let q = new Laya.Quaternion();
Laya.Quaternion.createFromAxisAngle(axis, Math.PI / 2, q);

2.3 从矩阵

let q = new Laya.Quaternion();
// 从4x4矩阵
Laya.Quaternion.createFromMatrix4x4(mat4, q);
// 从3x3矩阵
Laya.Quaternion.rotationMatrix(mat3x3, q);

三、四元数运算

let q1 = new Laya.Quaternion();
let q2 = new Laya.Quaternion();
let out = new Laya.Quaternion();

// 组合旋转(乘法)
Laya.Quaternion.multiply(q1, q2, out);

// 加法
Laya.Quaternion.add(q1, q2, out);

// 点积
let dot = Laya.Quaternion.dot(q1, q2);

// 求逆(反向旋转)
Laya.Quaternion.invert(q1, out);
q1.invert(out);

// 归一化
q1.normalize(out);

// 缩放
q1.scaling(2, out);

// 长度
let len = q1.length();
let lenSq = q1.lengthSquared();

// 设置值
q1.setValue(0, 0, 0, 1);
q1.set(0, 0, 0, 1);
q1.identity();   // 重置为单位四元数

四、旋转插值

4.1 线性插值(Lerp)

Laya.Quaternion.lerp(startRot, endRot, 0.5, out);

4.2 球面线性插值(Slerp)

沿球面最短弧插值,旋转角速度恒定,推荐用于旋转动画:

Laya.Quaternion.slerp(startRot, endRot, 0.5, out);

五、朝向控制

let q = new Laya.Quaternion();
let eye = new Laya.Vector3(0, 0, 0);
let target = new Laya.Vector3(0, 0, 10);
let up = new Laya.Vector3(0, 1, 0);

// 适用Camera/灯光的观察四元数
Laya.Quaternion.lookAt(eye, target, up, q);

// 适用GameObject的观察四元数
Laya.Quaternion.forwardLookAt(eye, target, up, q);

// 从前方向+上方向计算旋转
let forward = new Laya.Vector3(0, 0, 1);
Laya.Quaternion.rotationLookAt(forward, up, q);

六、欧拉角互转

// 四元数 → 欧拉角
let ypr = new Laya.Vector3();
q.getYawPitchRoll(ypr);
// ypr.x = yaw, ypr.y = pitch, ypr.z = roll

// 欧拉角 → 四元数
Laya.Quaternion.createFromYawPitchRoll(yaw, pitch, roll, q);

七、追加旋转

let q = new Laya.Quaternion();
let out = new Laya.Quaternion();

q.rotateX(Math.PI / 6, out);   // 绕X轴追加旋转
q.rotateY(Math.PI / 6, out);   // 绕Y轴追加旋转
q.rotateZ(Math.PI / 6, out);   // 绕Z轴追加旋转

八、与向量配合

// 通过四元数旋转三维向量
let v = new Laya.Vector3(1, 0, 0);
let rotated = new Laya.Vector3();
Laya.Vector3.transformQuat(v, q, rotated);

九、实用示例:平滑转向

onUpdate(): void {
    let currentRot = (this.owner as Laya.Sprite3D).transform.rotation;
    let targetRot = new Laya.Quaternion();
    Laya.Quaternion.createFromYawPitchRoll(targetYaw, 0, 0, targetRot);

    let smoothRot = new Laya.Quaternion();
    Laya.Quaternion.slerp(currentRot, targetRot, 0.1, smoothRot);
    (this.owner as Laya.Sprite3D).transform.rotation = smoothRot;
}
Copyright ©Layabox 2026 all right reserved,powered by LayaAir Engine更新时间: 2026-06-02 11:29:28

results matching ""

    No results matching ""