Quat 四元数库使用教程:应用场景概述
基础概念
四元数是一个包含四个元素的数组 [x, y, z, w]
,其中 x,y,z表示虚部,w
表示实部。单位四元数常用于表示3D空间中的旋转。
1. 创建和初始化函数
create() - 创建单位四元数
应用场景:初始化一个新的四元数对象,通常作为其他操作的基础。
import { create } from 'quat';// 创建一个新的单位四元数 [0, 0, 0, 1]
const quaternion = create();
console.log(quaternion); // [0, 0, 0, 1]
identity(out) - 设置为单位四元数
应用场景:重置四元数为无旋转状态,常用于对象的初始化或重置。
import { create, identity } from 'quat';const q = create();
// 对q进行一些操作...
// 重置为单位四元数(无旋转状态)
identity(q);
setAxisAngle(out, axis, rad) - 从轴角创建四元数
应用场景:根据旋转轴和角度创建四元数,常用于绕特定轴旋转对象。
import { create, setAxisAngle } from 'quat';// 绕Y轴旋转90度(π/2弧度)
const q = create();
const yAxis = [0, 1, 0];
setAxisAngle(q, yAxis, Math.PI / 2);
fromEuler(out, x, y, z, order) - 从欧拉角创建四元数
应用场景:将欧拉角(如万向节)转换为四元数,常用于从用户输入或已有数据创建旋转。
import { create, fromEuler } from 'quat';// 创建一个绕X轴旋转45度,绕Y轴旋转90度的四元数
const q = create();
fromEuler(q, 45, 90, 0, 'xyz'); // 角度单位为度
fromMat3(out, m) - 从旋转矩阵创建四元数
应用场景:从3x3旋转矩阵转换为四元数,常用于与其他数学库或引擎的数据转换。
import { create, fromMat3 } from 'quat';// 从旋转矩阵创建四元数
const q = create();
const rotationMatrix = [1, 0, 0,0, 1, 0,0, 0, 1
];
fromMat3(q, rotationMatrix);
2. 查询和获取函数
getAxisAngle(out_axis, q) - 获取旋转轴和角度
应用场景:提取四元数的旋转轴和角度信息,用于UI显示或调试。
import { create, setAxisAngle, getAxisAngle } from 'quat';const q = create();
const axis = [0, 1, 0];
setAxisAngle(q, axis, Math.PI / 4);const resultAxis = [0, 0, 0];
const angle = getAxisAngle(resultAxis, q);
console.log('旋转轴:', resultAxis); // [0, 1, 0]
console.log('旋转角度:', angle); // 0.785 (π/4)
getAngle(a, b) - 获取两个四元数之间的角度
应用场景:计算两个旋转状态之间的差异,用于动画插值或差异检测。
import { create, setAxisAngle, getAngle } from 'quat';const q1 = create();
const q2 = create();
setAxisAngle(q1, [0, 1, 0], Math.PI / 4);
setAxisAngle(q2, [0, 1, 0], Math.PI / 2);const angleDiff = getAngle(q1, q2);
console.log('角度差异:', angleDiff);
3. 数学运算函数
multiply(out, a, b) - 四元数乘法
应用场景:组合两个旋转操作,常用于对象的连续旋转。
import { create, setAxisAngle, multiply } from 'quat';// 先绕Y轴旋转90度,再绕X轴旋转45度
const rotationY = create();
const rotationX = create();
setAxisAngle(rotationY, [0, 1, 0], Math.PI / 2);
setAxisAngle(rotationX, [1, 0, 0], Math.PI / 4);const combinedRotation = create();
multiply(combinedRotation, rotationX, rotationY);
rotateX(out, a, rad) - 绕X轴旋转
应用场景:在现有旋转基础上增加绕X轴的旋转,常用于第一人称视角控制。
import { create, rotateX } from 'quat';const currentRotation = create();
// 增加绕X轴的旋转(如抬头/低头)
rotateX(currentRotation, currentRotation, 0.1);
rotateY(out, a, rad) - 绕Y轴旋转
应用场景:在现有旋转基础上增加绕Y轴的旋转,常用于角色左右转向。
import { create, rotateY } from 'quat';const currentRotation = create();
// 增加绕Y轴的旋转(如左右转头)
rotateY(currentRotation, currentRotation, 0.1);
rotateZ(out, a, rad) - 绕Z轴旋转
应用场景:在现有旋转基础上增加绕Z轴的旋转,常用于滚转操作。
import { create, rotateZ } from 'quat';const currentRotation = create();
// 增加绕Z轴的旋转(如飞机滚转)
rotateZ(currentRotation, currentRotation, 0.1);
invert(out, a) - 计算逆四元数
应用场景:计算相反的旋转,用于撤销旋转操作或计算相对旋转。
import { create, setAxisAngle, invert } from 'quat';const rotation = create();
setAxisAngle(rotation, [0, 1, 0], Math.PI / 4);// 计算相反的旋转
const inverseRotation = create();
invert(inverseRotation, rotation);
conjugate(out, a) - 计算共轭四元数
应用场景:对于单位四元数,共轭等同于逆,用于旋转的反向操作。
import { create, conjugate } from 'quat';const q = create();
// 对于单位四元数,共轭等于逆
const conjugateQ = create();
conjugate(conjugateQ, q);
4. 插值函数
slerp(out, a, b, t) - 球面线性插值
应用场景:在两个旋转状态之间平滑过渡,是动画系统的核心函数。
import { create, setAxisAngle, slerp } from 'quat';const startRotation = create();
const endRotation = create();
setAxisAngle(startRotation, [0, 1, 0], 0);
setAxisAngle(endRotation, [0, 1, 0], Math.PI);// 在起始和结束旋转之间插值
const interpolatedRotation = create();
slerp(interpolatedRotation, startRotation, endRotation, 0.5); // 50%位置
lerp(out, a, b, t) - 线性插值
应用场景:快速的线性插值,适用于性能要求高的场景或作为slerp的近似。
import { create, setAxisAngle, lerp } from 'quat';const startRotation = create();
const endRotation = create();
setAxisAngle(startRotation, [0, 1, 0], 0);
setAxisAngle(endRotation, [0, 1, 0], Math.PI);const interpolatedRotation = create();
lerp(interpolatedRotation, startRotation, endRotation, 0.5);
sqlerp(out, a, b, c, d, t) - 球面二次插值
应用场景:使用控制点进行更复杂的旋转插值,适用于高级动画系统。
import { create, sqlerp } from 'quat';const q1 = create();
const q2 = create();
const q3 = create();
const q4 = create();const result = create();
sqlerp(result, q1, q2, q3, q4, 0.5);
5. 实用工具函数
normalize(out, a) - 归一化四元数
应用场景:确保四元数为单位长度,防止数值误差累积。
import { create, normalize } from 'quat';const q = [0.5, 0.5, 0.5, 0.5]; // 非单位四元数
const normalizedQ = create();
normalize(normalizedQ, q);
dot(a, b) - 点积计算
应用场景:计算两个四元数的相似度,用于检测旋转是否相近。
import { create, dot } from 'quat';const q1 = create();
const q2 = create();const similarity = dot(q1, q2);
if (similarity > 0.99) {console.log('两个旋转非常接近');
}
equals(a, b) - 近似相等比较
应用场景:比较两个四元数是否近似相等,用于状态检测。
import { create, setAxisAngle, equals } from 'quat';const q1 = create();
const q2 = create();
setAxisAngle(q2, [0, 1, 0], 0.0001); // 很小的旋转if (equals(q1, q2)) {console.log('两个旋转近似相等');
}
random(out) - 生成随机四元数
应用场景:生成随机旋转,用于测试或特殊效果。
import { create, random } from 'quat';const randomRotation = create();
random(randomRotation);
console.log('随机旋转:', randomRotation);
6. 高级数学函数
exp(out, a) - 指数函数
应用场景:高级数学运算,用于特定的物理模拟或数学计算。
import { create, exp } from 'quat';const q = create();
const result = create();
exp(result, q);
ln(out, a) - 自然对数
应用场景:与指数函数配合使用,用于复杂的数学运算。
import { create, ln } from 'quat';const q = create();
const result = create();
ln(result, q);
pow(out, a, b) - 幂运算
应用场景:对四元数进行缩放,用于特殊的动画或数学运算。
import { create, pow } from 'quat';const q = create();
const result = create();
pow(result, q, 2); // 计算q的平方
实际应用示例
1. 3D相机控制
import { create, rotateY, rotateX, multiply } from 'quat';class CameraController {constructor() {this.rotation = create();}// 左右转头yaw(angle) {rotateY(this.rotation, this.rotation, angle);}// 抬头低头pitch(angle) {const pitchRotation = create();rotateX(pitchRotation, pitchRotation, angle);multiply(this.rotation, this.rotation, pitchRotation);}
}
2. 角色动画插值
import { create, slerp } from 'quat';class AnimationSystem {interpolateRotation(start, end, progress) {const result = create();slerp(result, start, end, progress);return result;}
}
3. 物体朝向计算
import { create, setAxisAngle, multiply, invert } from 'quat';function lookAtRotation(forward, up) {// 计算物体看向某个方向的旋转const rotation = create();// 实现lookAt逻辑...return rotation;
}function relativeRotation(from, to) {// 计算从一个朝向到另一个朝向的相对旋转const inverseFrom = create();invert(inverseFrom, from);const relative = create();multiply(relative, inverseFrom, to);return relative;
}
总结
通过本教程,我们了解了 quat库中各个函数的应用场景:
- 创建和初始化函数:用于创建和设置四元数的初始状态
- 查询和获取函数:用于提取四元数的信息
- 数学运算函数:实现四元数的基本数学操作
- 插值函数:实现旋转的平滑过渡
- 实用工具函数:提供常用的操作和比较功能
- 高级数学函数:用于复杂的数学计算
掌握这些函数的应用场景,可以帮助您在3D图形、游戏开发、机器人学等领域更好地使用四元数来处理旋转和方向问题。