基礎概念
四元數是一個包含四個元素的數組 [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圖形、游戲開發、機器人學等領域更好地使用四元數來處理旋轉和方向問題。