///|
// =====================================================================
// quat.mbt — 四元數代數 H 與 H^n 作為實內積空間
// ⟨q,p⟩ = Re(q̄p);‖q‖² = q̄q;旋轉由單位四元數共軛作用給出
// =====================================================================
/// 四元數 q = w + xi + yj + zk
pub struct Quat {
w : Double
x : Double
y : Double
z : Double
} derive(Debug, Eq)
/// Q-1 構造
pub fn quat_new(w : Double, x : Double, y : Double, z : Double) -> Quat {
{ w, x, y, z }
}
/// Q-2 零
pub fn quat_zero() -> Quat {
{ w: 0.0, x: 0.0, y: 0.0, z: 0.0 }
}
/// Q-3 純量四元數
pub fn quat_real(w : Double) -> Quat {
{ w, x: 0.0, y: 0.0, z: 0.0 }
}
/// Q-4 純虛四元數(對應 R³ 向量)
pub fn quat_imag(x : Double, y : Double, z : Double) -> Quat {
{ w: 0.0, x, y, z }
}
/// Q-5 加法
pub fn quat_add(a : Quat, b : Quat) -> Quat {
{ w: a.w + b.w, x: a.x + b.x, y: a.y + b.y, z: a.z + b.z }
}
/// Q-6 負元
pub fn quat_neg(a : Quat) -> Quat {
{ w: -a.w, x: -a.x, y: -a.y, z: -a.z }
}
/// Q-7 實純量乘法
pub fn quat_scale(c : Double, a : Quat) -> Quat {
{ w: c * a.w, x: c * a.x, y: c * a.y, z: c * a.z }
}
/// Q-8 Hamilton 乘法
pub fn quat_mul(a : Quat, b : Quat) -> Quat {
{
w: a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z,
x: a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
y: a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,
z: a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w,
}
}
/// Q-9 共軛
pub fn quat_conj(a : Quat) -> Quat {
{ w: a.w, x: -a.x, y: -a.y, z: -a.z }
}
/// Q-10 範數平方
pub fn quat_norm2(a : Quat) -> Double {
a.w * a.w + a.x * a.x + a.y * a.y + a.z * a.z
}
/// Q-11 範數
pub fn quat_norm(a : Quat) -> Double {
quat_norm2(a).sqrt()
}
/// Q-12 逆 q⁻¹ = q̄/‖q‖²
pub fn quat_inv(a : Quat) -> Quat {
let d = quat_norm2(a)
{ w: a.w / d, x: -a.x / d, y: -a.y / d, z: -a.z / d }
}
/// Q-13 單位化
pub fn quat_unit(a : Quat) -> Quat {
quat_scale(1.0 / quat_norm(a), a)
}
/// Q-14 由軸角構造單位四元數(旋轉角 θ 繞單位軸 u)
pub fn quat_from_axis_angle(axis : Array[Double], theta : Double) -> Quat {
let n = (axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]).sqrt()
let s = @math.sin(theta / 2.0)
{
w: @math.cos(theta / 2.0),
x: axis[0] / n * s,
y: axis[1] / n * s,
z: axis[2] / n * s,
}
}
/// Q-15 旋轉 R³ 向量:v ↦ q v q̄(q 為單位四元數)
pub fn quat_rotate_vec(q : Quat, v : Array[Double]) -> Array[Double] {
let p = quat_imag(v[0], v[1], v[2])
let r = quat_mul(quat_mul(q, p), quat_conj(q))
[r.x, r.y, r.z]
}
/// Q-16 H 上之內積 ⟨q,p⟩ = Re(q̄p)
pub fn quat_inner(a : Quat, b : Quat) -> Double {
quat_mul(quat_conj(a), b).w
}
/// H^n 之元素
pub struct HVec {
comps : Array[Quat]
} derive(Debug, Eq)
/// Q-17 H^n 零向量
pub fn hvec_zero(n : Int) -> HVec {
{ comps: Array::make(n, quat_zero()) }
}
/// Q-18 H^n 加法
pub fn hvec_add(a : HVec, b : HVec) -> HVec {
let out : Array[Quat] = []
for i = 0; i < a.comps.length(); i = i + 1 {
out.push(quat_add(a.comps[i], b.comps[i]))
}
{ comps: out }
}
/// Q-19 H^n 實純量乘法(H^n 視為實向量空間)
pub fn hvec_scale(c : Double, a : HVec) -> HVec {
let out : Array[Quat] = []
for q in a.comps {
out.push(quat_scale(c, q))
}
{ comps: out }
}
/// Q-20 H^n 之實內積 Σ Re(q̄ᵢ pᵢ)
pub fn hvec_inner(a : HVec, b : HVec) -> Double {
let mut s = 0.0
for i = 0; i < a.comps.length(); i = i + 1 {
s = s + quat_inner(a.comps[i], b.comps[i])
}
s
}
/// Q-21 H^n 作為實內積空間之字典(實維數 4n)
pub fn hvec_ip(n : Int) -> IPSp[HVec] {
ips_make(
{
zero: hvec_zero(n),
add: hvec_add,
neg: fn(v) { hvec_scale(-1.0, v) },
scale: hvec_scale,
},
hvec_inner,
)
}
/// Q-22 H^n 之實維數 = 4n
pub fn hvec_real_dim(n : Int) -> Int {
4 * n
}
/// Q-23 Gram–Schmidt 於 H^n(經由實內積字典)
pub fn hvec_orthonormal(vs : Array[HVec], eps : Double) -> Array[HVec] {
ip_orthonormal(hvec_ip(vs[0].comps.length()), vs, eps)
}
/// Q-24 四元數旋轉複合:q₂∘q₁ 對應四元數乘法(注意次序)
pub fn quat_compose(q1 : Quat, q2 : Quat) -> Quat {
quat_mul(q2, q1)
}