# 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