源代碼
// matrix.rs
use std::ops::{Add, Mul};use std::ops::{Add, Mul};/// 通用2D仿射變換矩陣(元素僅需Copy)
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Matrix<X, Y, Xx, Xy, Yx, Yy> {pub x: X, pub y: Y,pub xx: Xx, pub xy: Xy,pub yx: Yx, pub yy: Yy,
}impl<X, Y, Xx, Xy, Yx, Yy> Matrix<X, Y, Xx, Xy, Yx, Yy> {/// 通用二元運算接口#[inline]fn binary_op<A, B, C, D, O>(a: A, b: B, c: C, d: D) -> OwhereO: From<(A, B, C, D)>{O::from((a, b, c, d))}
}/// 線性組合運算轉換器
pub struct LinearCombination<A, B, C, D>(pub A, pub B, pub C, pub D);impl<A, B, C, D> From<(A, B, C, D)> for LinearCombination<A, B, C, D> {fn from(t: (A, B, C, D)) -> Self {LinearCombination(t.0, t.1, t.2, t.3)}
}impl<A, B, C, D, AB, CD> From<LinearCombination<A, B, C, D>> for <AB as Add<CD>>::Output
whereA: Mul<B, Output = AB>,C: Mul<D, Output = CD>,AB: Add<CD>
{fn from(lc: LinearCombination<A, B, C, D>) -> Self {lc.0 * lc.1 + lc.2 * lc.3}
}impl<X1, Y1, Xx1, Xy1, Yx1, Yy1,X2, Y2, Xx2, Xy2, Yx2, Yy2,
> Mul<Matrix<X2, Y2, Xx2, Xy2, Yx2, Yy2>> for Matrix<X1, Y1, Xx1, Xy1, Yx1, Yy1>
where// 基礎約束(僅Copy)X1: Copy, Y1: Copy, Xx1: Copy, Xy1: Copy, Yx1: Copy, Yy1: Copy,X2: Copy, Y2: Copy, Xx2: Copy, Xy2: Copy, Yx2: Copy, Yy2: Copy,// 平移運算約束(不限制Output類型)Xx2: Mul<X1>,Xy2: Mul<Y1>,Yx2: Mul<X1>,Yy2: Mul<Y1>,// 線性變換約束(不限制Output類型)Xx1: Mul<Xx2>,Xx1: Mul<Yx2>,Xy1: Mul<Xy2>,Xy1: Mul<Yy2>,Yx1: Mul<Xx2>,Yx1: Mul<Yx2>,Yy1: Mul<Xy2>,Yy1: Mul<Yy2>,// 加法約束(自動推導)<Xx1 as Mul<Xx2>>::Output: Add<<Xy1 as Mul<Yx2>>::Output>,<Xx1 as Mul<Xy2>>::Output: Add<<Xy1 as Mul<Yy2>>::Output>,<Yx1 as Mul<Xx2>>::Output: Add<<Yy1 as Mul<Yx2>>::Output>,<Yx1 as Mul<Xy2>>::Output: Add<<Yy1 as Mul<Yy2>>::Output>,
{type Output = Matrix<<X1 as Add<<Xx2 as Mul<X1>>::Output>>::Output, // X<Y1 as Add<<Yy2 as Mul<Y1>>::Output>>::Output, // Y<<Xx1 as Mul<Xx2>>::Output as Add<<Xy1 as Mul<Yx2>>::Output>>::Output, // Xx<<Xx1 as Mul<Xy2>>::Output as Add<<Xy1 as Mul<Yy2>>::Output>>::Output, // Xy<<Yx1 as Mul<Xx2>>::Output as Add<<Yy1 as Mul<Yx2>>::Output>>::Output, // Yx<<Yx1 as Mul<Xy2>>::Output as Add<<Yy1 as Mul<Yy2>>::Output>>::Output // Yy>;fn mul(self, rhs: Matrix<X2, Y2, Xx2, Xy2, Yx2, Yy2>) -> Self::Output {Matrix {// 平移計算(完全自由類型推導)x: self.x + rhs.x * self.xx + rhs.y * self.yx,y: self.y + rhs.x * self.xy + rhs.y * self.yy,// 通過轉換器計算線性變換xx: Self::binary_op::<_, _, _, _, _>(self.xx, rhs.xx, self.xy, rhs.yx),xy: Self::binary_op::<_, _, _, _, _>(self.xx, rhs.xy, self.xy, rhs.yy),yx: Self::binary_op::<_, _, _, _, _>(self.yx, rhs.xx, self.yy, rhs.yx),yy: Self::binary_op::<_, _, _, _, _>(self.yx, rhs.xy, self.yy, rhs.yy),}}
}
代碼分析
- 矩陣布局
矩陣采用以下布局:
[ 1 x y 0 x x x y 0 y x y y ] \begin{bmatrix}1 & x & y \\ 0 & xx & xy \\ 0 & yx & yy \end{bmatrix} ?100?xxxyx?yxyyy? ?
這種布局的特點是:
-
平移分量 x 和 y 位于第一行
-
線性變換部分位于右下2x2子矩陣
-
左下保持 [0, 0] 以保證是仿射變換
- 核心功能
矩陣乘法
兩個矩陣相乘的結果計算如下:
[ 1 x 1 y 1 0 x x 1 x y 1 0 y x 1 y y 1 ] ? [ 1 x 2 y 2 0 x x 2 x y 2 0 y x 2 y y 2 ] = [ 1 x 1 + x 2 ? x x 1 + y 2 ? y x 1 y 1 + x 2 ? x y 1 + y 2 ? y y 1 0 x x 1 ? x x 2 + x y 1 ? y x 2 x x 1 ? x y 2 + x y 1 ? y y 2 0 y x 1 ? x x 2 + y y 1 ? y x 2 y x 1 ? x y 2 + y y 1 ? y y 2 ] \begin{bmatrix}1 & x1 & y1 \\ 0 & xx1 & xy1 \\ 0 & yx1 & yy1 \end{bmatrix} * \begin{bmatrix}1 & x2 & y2 \\ 0 & xx2 & xy2 \\ 0 & yx2 & yy2 \end{bmatrix}= \begin{bmatrix}1 & x1+x2*xx1+y2*yx1 & y1+x2*xy1+y2*yy1 \\ 0 & xx1*xx2+xy1*yx2 & xx1*xy2+xy1*yy2 \\ 0 & yx1*xx2+yy1*yx2 & yx1*xy2+yy1*yy2 \end{bmatrix} ?100?x1xx1yx1?y1xy1yy1? ?? ?100?x2xx2yx2?y2xy2yy2? ?= ?100?x1+x2?xx1+y2?yx1xx1?xx2+xy1?yx2yx1?xx2+yy1?yx2?y1+x2?xy1+y2?yy1xx1?xy2+xy1?yy2yx1?xy2+yy1?yy2? ?
實現特點
-
泛型設計:支持不同類型的矩陣元素
-
trait約束:確保類型安全
-
乘法約束:Mul trait
-
加法約束:Add trait
-
克隆約束:Clone trait
-
精確控制:可以控制每種運算的輸出類型
-
性能優化:使用#[inline]提示編譯器優化
使用場景
這種矩陣適用于:
-
2D圖形變換(平移、旋轉、縮放、傾斜)
-
需要高精度計算的場景
-
需要組合多個變換的場景(通過矩陣乘法)
優勢
-
靈活性:支持不同的數值類型(f32, f64, 定點數等)
-
類型安全:編譯時檢查所有操作的有效性
-
明確語義:矩陣布局更直觀反映變換參數
-
可組合性:通過矩陣乘法組合多個變換
這個實現提供了強大而類型安全的2D仿射變換操作基礎,適合用于圖形引擎、物理模擬等需要精確數學計算的領域。