当前位置: 首页 > news >正文

quat:高性能四元数运算库

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):

# npm 安装
npm install quat# yarn 安装
yarn add quat

2. 浏览器 CDN(IIFE)

直接在浏览器中加载预构建的 IIFE 包(自动暴露全局变量 quat):

<!-- 加载 v1.1.0 版本(可替换为 npm 最新版本) -->
<script src="https://unpkg.com/quat@latest/dist/index.global.js"></script>
<!-- 通过全局变量 quat 使用 -->
<script>const q = quat.create(); // 创建单位四元数:[0,0,0,1]
</script>

使用示例

ESM 环境(TypeScript/JavaScript)

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)

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 环境(全局变量)

<script src="https://unpkg.com/quat@latest/dist/index.global.js"></script>
<script>// 绕 Z 轴旋转正方形顶点const rotateZ90 = quat.from([0,0,1], Math.PI/2); // 绕 Z 轴旋转 90°const squareVertices = new Float32Array([1,1,0, -1,1,0, -1,-1,0, 1,-1,0 // 4 个顶点的坐标]);const rotatedSquare = new Float32Array(squareVertices.length);quat.rotatePoints(rotateZ90, squareVertices, rotatedSquare);console.log('旋转后的顶点:', rotatedSquare);
</script>

完整 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),基于 lnexp 实现(如 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球面二次插值,通过两个控制点(bc)实现 ad 的平滑曲线过渡。

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%+。若 pointsout 长度不相等或长度非 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): Quata 的值复制到 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):

// 四元数:[x(虚部), y(虚部), z(虚部), w(实部)]
export type Quat = Float32Array & { length: 4 };
export type ReadonlyQuat = Readonly<Float32Array> & { length: 4 };// 三维向量:[x, y, z](用于点坐标或旋转轴)
export type Vec3 = Float32Array & { length: 3 };
export type ReadonlyVec3 = Readonly<Float32Array> & { length: 3 };// 3x3 矩阵(列优先存储,兼容 WebGL/OpenGL)
// 存储格式:[m00, m10, m20, m01, m11, m21, m02, m12, m22]
export type Mat3 = Float32Array & { length: 9 };
export type ReadonlyMat3 = Readonly<Float32Array> & { length: 9 };

许可证

MIT

http://www.dtcms.com/a/537059.html

相关文章:

  • [MySQL]表——分组查询
  • 济南做网站的好公司有哪些极简资讯网站开发
  • 网站后台页面设计互联网+可以做什么项目
  • 项目八 使用postman实现简易防火墙功能
  • 使用postman 测试restful接口
  • 2008 iis 添加 网站 权限设置网站策划案4500
  • 以自主创新推动能源装备智能化升级,为能源安全构筑“确定性”底座
  • 构建AI智能体:七十六、深入浅出LoRA:低成本高效微调大模型的原理与实践
  • 中国各大网站排名网站源码爬取
  • FFmpeg 安装与配置教程(Windows 系统)
  • 【数字逻辑】 60进制数字秒表设计实战:用74HC161搭计数器+共阴极数码管显示(附完整接线图)
  • 新网网站空间花都网站建设价格
  • 前端底层原理与复杂问题映射表
  • Digital Micrograph下载安装教程
  • 怎么做网站的301建设设计院网站
  • 自己的服务器 linux centos8部署django项目
  • 做网站注册会员加入实名认证功能广西建设工程质量监督网站
  • 遵义哪里有做网站的外国网站上做Task
  • 动态修改浏览器地址而不刷新页面
  • 车牌识别相机:中哈口岸的通关智能助力
  • 音视频开发远端未发布视频占位图2
  • 【普中STM32F1xx开发攻略--标准库版】-- 第 9 章 STM32 固件库介绍
  • OpenCV 视频处理
  • 有些网站做不了seo物业公司会计好做吗
  • 实惠的制作网站网站首页的功能需求分析
  • ROS2 轨迹规划核心点
  • [GESP202506 五级] 奖品兑换
  • Strassen矩阵乘法算法
  • 网站开发新闻怎么写相应式手机网站建设
  • [C++][windows]C++类成员函数默认参数和成员变量初始化问题