# quat
**Repository Path**: cesiumjs/quat
## Basic Information
- **Project Name**: quat
- **Description**: 是一个高性能的四元数库,专为 3D 数学设计,复制粘贴于 [gl-matrix]
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2025-09-15
- **Last Updated**: 2025-10-27
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# quat:高性能四元数运算库
一款轻量且高性能的 TypeScript 四元数库,专为 3D 旋转计算设计。支持四元数的创建、运算、插值、转换等全功能操作,以及批量点旋转,同时提供通用模块支持(ESM/CJS/IIFE),可无缝集成到 Node.js、打包工具及浏览器环境中。
## 核心特性
- **多环境兼容**:支持 ESM(Node.js/打包工具)、CommonJS(Node.js)和 IIFE(浏览器全局变量),可通过 CDN 直接引入。
- **极致性能**:基于 `Float32Array` 实现,内存布局优化,CPU 缓存利用率高,垃圾回收开销最小化。
- **完整 3D 旋转工具链**:覆盖四元数与欧拉角/矩阵的转换、插值计算及批量顶点旋转。
- **类型安全**:严格的 TypeScript 类型定义 + 运行时类型检查,避免无效旋转数据导致的错误。
- **浏览器友好**:提供 IIFE 构建版本(v1.1.0+),可通过 unpkg 加载,自动暴露全局变量 `quat` 直接使用。
## 安装方式
### 1. 包管理器(ESM/CJS)
适用于 Node.js 或打包工具(Webpack/Vite/Rollup):
```bash
# npm 安装
npm install quat
# yarn 安装
yarn add quat
```
### 2. 浏览器 CDN(IIFE)
直接在浏览器中加载预构建的 IIFE 包(自动暴露全局变量 `quat`):
```html
```
## 使用示例
### ESM 环境(TypeScript/JavaScript)
```typescript
import * as quat from 'quat';
// 1. 创建四元数
const q1 = quat.create(); // 单位四元数:[0,0,0,1]
const q2 = quat.from([0, 1, 0], Math.PI / 2); // 绕 Y 轴旋转 90°
const q3 = quat.of(Math.PI/2, 0, 0); // 从 XYZ 欧拉角创建(绕 X 轴旋转 90°)
const q4 = quat.set(0.5, 0.5, 0, Math.SQRT1_2); // 从显式分量创建
// 2. 四元数运算
const combined = quat.multiply(q2, q3); // 组合旋转(先应用 q2,再应用 q3)
const conjugate = quat.conjugate(combined); // 计算共轭(翻转虚部)
const inverse = quat.invert(combined); // 计算逆(反转旋转方向)
const normalized = quat.normalize(q4); // 归一化(确保单位长度,保证旋转有效性)
// 3. 插值计算
const slerped = quat.slerp(q2, q3, 0.5); // 球面线性插值(平滑旋转,角速度恒定)
const lerped = quat.lerp(q2, q3, 0.5); // 线性插值(速度快,需后续归一化)
const sqlerped = quat.sqlerp(q1, q2, q3, q4, 0.5); // 球面二次插值(带控制点,曲线更平滑)
// 4. 单个点旋转
const point = [1, 0, 0];
const rotatedPoint = quat.rotatePoint(q2, point); // 旋转结果:[0,0,1]
// 5. 批量顶点旋转(WebGL 友好)
const vertices = new Float32Array([1,0,0, 0,1,0, 0,0,1]); // 3 个点(扁平化存储)
const rotatedVertices = new Float32Array(vertices.length);
quat.rotatePoints(q2, vertices, rotatedVertices); // 批量旋转,比循环调用快约 40%
// 6. 矩阵转换
const mat = quat.toMat3(q2); // 四元数 → 3x3 列优先矩阵
const qFromMat = quat.fromMat3(mat); // 3x3 列优先矩阵 → 四元数
// 7. 工具函数
const isQuat = quat.isQuat(q2); // 类型检查:返回 true
const quatStr = quat.str(q2); // 转为字符串:"quat(0.707107, 0.000000, 0.000000, 0.707107)"
```
### CommonJS 环境(Node.js)
```javascript
const quat = require('quat');
// 创建随机旋转四元数
const randomQuat = quat.random();
// 提取旋转轴和角度
const axis = new Float32Array(3);
const angle = quat.getAxisAngle(axis, randomQuat);
console.log(`绕轴 [${axis.join(', ')}] 旋转 ${angle.toFixed(2)} 弧度`);
```
### 浏览器 IIFE 环境(全局变量)
```html
```
## 完整 API 参考
所有方法均支持可选的 `out` 参数以复用内存(减少垃圾回收),若未传入 `out`,则默认创建新的 `Float32Array` 实例返回。
### 1. 四元数创建
| 方法 | 函数签名 | 描述 |
|--------|--------------------------------------------------------------------------|----------------------------------------------------------------------|
| `create` | `(): Quat` | 创建单位四元数 `[0, 0, 0, 1]`。 |
| `from` | `(axis: [number,number,number] \| ReadonlyVec3, angle: number, out?: Quat): Quat` | 从旋转轴(建议单位向量)和角度(弧度)创建四元数。 |
| `of` | `(x: number, y: number, z: number, out?: Quat): Quat` | 从 XYZ 欧拉角(弧度,旋转顺序 X→Y→Z,与 Three.js 兼容)创建四元数。 |
| `set` | `(x: number, y: number, z: number, w: number, out?: Quat): Quat` | 从显式分量创建四元数(`x/y/z` 为虚部,`w` 为实部)。 |
| `fromMat3` | `(mat: ReadonlyMat3, out?: Quat): Quat` | 将 3x3 列优先旋转矩阵转换为四元数。 |
| `fromArray` | `(arr: number[]): Quat` | 将 4 元素普通数组 `[x,y,z,w]` 转换为四元数,数组长度非 4 时抛出错误。 |
| `random` | `(out?: Quat): Quat` | 生成随机单位四元数(旋转分布均匀)。 |
### 2. 四元数运算
| 方法 | 函数签名 | 描述 |
|--------------|--------------------------------------------------------------------------|----------------------------------------------------------------------|
| `multiply` | `(a: ReadonlyQuat, b: ReadonlyQuat, out?: Quat): Quat` | 四元数乘法(`out = a * b`),几何意义:先应用 `b` 的旋转,再应用 `a` 的旋转。 |
| `add` | `(a: ReadonlyQuat, b: ReadonlyQuat, out?: Quat): Quat` | 四元数分量相加(`out[i] = a[i] + b[i]`)。 |
| `scale` | `(a: ReadonlyQuat, s: number, out?: Quat): Quat` | 四元数标量缩放(`out[i] = a[i] * s`)。 |
| `conjugate` | `(a: ReadonlyQuat, out?: Quat): Quat` | 计算共轭四元数(翻转虚部:`out = [-x, -y, -z, w]`)。 |
| `invert` | `(a: ReadonlyQuat, out?: Quat): Quat` | 计算逆四元数(单位四元数的逆等于其共轭)。 |
| `normalize` | `(a: ReadonlyQuat, out?: Quat): Quat` | 归一化四元数(确保单位长度,是有效旋转的前提,避免缩放效果)。 |
| `exp` | `(a: ReadonlyQuat, out?: Quat): Quat` | 计算四元数的指数(高阶旋转数学运算)。 |
| `ln` | `(a: ReadonlyQuat, out?: Quat): Quat` | 计算四元数的自然对数(高阶旋转数学运算)。 |
| `pow` | `(a: ReadonlyQuat, b: number, out?: Quat): Quat` | 计算四元数的标量幂(`a^b`),基于 `ln` 和 `exp` 实现(如 `pow(q, 0.5)` 可将旋转角度减半)。 |
### 3. 插值计算
| 方法 | 函数签名 | 描述 |
|------------|--------------------------------------------------------------------------|----------------------------------------------------------------------|
| `slerp` | `(a: ReadonlyQuat, b: ReadonlyQuat, t: number, out?: Quat): Quat` | 球面线性插值,保持角速度恒定(最适合平滑旋转动画),`t ∈ [0,1]`(0 对应 `a`,1 对应 `b`)。 |
| `lerp` | `(a: ReadonlyQuat, b: ReadonlyQuat, t: number, out?: Quat): Quat` | 线性插值,速度快但角速度非恒定,**需后续归一化**才能作为有效旋转四元数。 |
| `sqlerp` | `(a: ReadonlyQuat, b: ReadonlyQuat, c: ReadonlyQuat, d: ReadonlyQuat, t: number, out?: Quat): Quat` | 球面二次插值,通过两个控制点(`b`、`c`)实现 `a` 到 `d` 的平滑曲线过渡。 |
### 4. 点与顶点旋转
| 方法 | 函数签名 | 描述 |
|----------------|--------------------------------------------------------------------------|----------------------------------------------------------------------|
| `rotatePoint` | `(q: ReadonlyQuat, point: [number,number,number] \| ReadonlyVec3, out?: Vec3): Vec3` | 旋转单个 3D 点,基于公式 `p' = q * p * q⁻¹`(`p` 为纯四元数 `[x,y,z,0]`)。 |
| `rotatePoints` | `(q: ReadonlyQuat, points: Float32Array, out: Float32Array): Float32Array` | 批量旋转扁平化 3D 点数组(格式:`[x1,y1,z1,x2,y2,z2,...]`),专为 WebGL 顶点数据优化,比循环调用 `rotatePoint` 快 40%+。若 `points` 与 `out` 长度不相等或长度非 3 的倍数,将抛出错误。 |
### 5. 矩阵转换
| 方法 | 函数签名 | 描述 |
|--------------|--------------------------------------------------------------------------|----------------------------------------------------------------------|
| `toMat3` | `(q: ReadonlyQuat, out?: Mat3): Mat3` | 将四元数转换为 3x3 列优先旋转矩阵(兼容 WebGL/OpenGL)。 |
| `fromMat3` | `(mat: ReadonlyMat3, out?: Quat): Quat` | 将 3x3 列优先旋转矩阵转换为四元数(`toMat3` 的逆操作)。 |
### 6. 旋转轴与角度提取
| 方法 | 函数签名 | 描述 |
|----------------|--------------------------------------------------------------------------|----------------------------------------------------------------------|
| `getAxisAngle` | `(outAxis: Vec3, q: ReadonlyQuat): number` | 从四元数中提取旋转轴(存储到 `outAxis`)和角度(返回值,单位:弧度),复用 `outAxis` 避免内存分配。 |
### 7. 工具函数
| 方法 | 函数签名 | 描述 |
|------------------|--------------------------------------------------------------------------|----------------------------------------------------------------------|
| `clone` | `(a: ReadonlyQuat): Quat` | 深拷贝四元数。 |
| `copy` | `(a: ReadonlyQuat, out: Quat): Quat` | 将 `a` 的值复制到 `out`(复用 `out` 的内存)。 |
| `toArray` | `(q: ReadonlyQuat): number[]` | 将四元数转换为 4 元素普通数组 `[x,y,z,w]`。 |
| `str` | `(a: ReadonlyQuat): string` | 将四元数转换为人类可读字符串(如:`"quat(0.707107, 0.000000, 0.000000, 0.707107)"`)。 |
| `length` | `(a: ReadonlyQuat): number` | 计算四元数的模长(长度),公式:`√(x²+y²+z²+w²)`。 |
| `squaredLength` | `(a: ReadonlyQuat): number` | 计算四元数的平方模长(`x²+y²+z²+w²`),比 `length` 快(避免开方),适合用于比较。 |
| `dot` | `(a: ReadonlyQuat, b: ReadonlyQuat): number` | 计算两个四元数的点积(`a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w`),用于相似度判断和 `slerp` 计算。 |
| `equals` | `(a: ReadonlyQuat, b: ReadonlyQuat): boolean` | 检查两个四元数是否**近似相等**(考虑浮点误差,判断条件:`dot(a,b) ≥ 1 - 1e-6`)。 |
| `exactEquals` | `(a: ReadonlyQuat, b: ReadonlyQuat): boolean` | 检查两个四元数是否**完全相等**(严格分量对比,仅用于精确值判断)。 |
| `isQuat` | `(value: unknown): value is Quat` | 运行时类型守卫:判断值是否为有效四元数(`Float32Array` 且长度为 4)。 |
| `isVec3` | `(value: unknown): value is Vec3` | 运行时类型守卫:判断值是否为有效三维向量(`Float32Array` 且长度为 3)。 |
## 类型定义
TypeScript 类型定义已内置(无需额外安装 `@types/quat`):
```typescript
// 四元数:[x(虚部), y(虚部), z(虚部), w(实部)]
export type Quat = Float32Array & { length: 4 };
export type ReadonlyQuat = Readonly & { length: 4 };
// 三维向量:[x, y, z](用于点坐标或旋转轴)
export type Vec3 = Float32Array & { length: 3 };
export type ReadonlyVec3 = Readonly & { length: 3 };
// 3x3 矩阵(列优先存储,兼容 WebGL/OpenGL)
// 存储格式:[m00, m10, m20, m01, m11, m21, m02, m12, m22]
export type Mat3 = Float32Array & { length: 9 };
export type ReadonlyMat3 = Readonly & { length: 9 };
```
## 许可证
MIT