// matrix/generic.rs
use std::ops::{Add, Mul};
use super::algebraic_units::{Zero, One};
/// 通用2D仿射变换矩阵结构体
#[derive(Clone, Debug, PartialEq)]
pub struct Matrix<Ox, Oy, Xx, Xy, Yx, Yy> {
pub ox: Ox, // x方向平移量
pub oy: Oy, // y方向平移量
pub xx: Xx, // x方向缩放和旋转分量
pub xy: Xy, // x方向倾斜分量
pub yx: Yx, // y方向倾斜分量
pub yy: Yy, // y方向缩放和旋转分量
}
impl<Ox1, Oy1, Xx1, Xy1, Yx1, Yy1> Matrix<Ox1, Oy1, Xx1, Xy1, Yx1, Yy1> {
/// 通用矩阵乘法,可以返回不同类型的矩阵
pub fn multiply<Ox2, Oy2, Xx2, Xy2, Yx2, Yy2, OxOut, OyOut, XxOut, XyOut, YxOut, YyOut>(
&self,
rhs: &Matrix<Ox2, Oy2, Xx2, Xy2, Yx2, Yy2>
) -> Matrix<OxOut, OyOut, XxOut, XyOut, YxOut, YyOut>
where
Xx1: Clone + Mul<Xx2, Output = XxOut> + Mul<Yx2, Output = XxOut>,
Xy1: Clone + Mul<Xy2, Output = XyOut> + Mul<Yy2, Output = XyOut>,
Yx1: Clone + Mul<Xx2, Output = YxOut> + Mul<Yx2, Output = YxOut>,
Yy1: Clone + Mul<Xy2, Output = YyOut> + Mul<Yy2, Output = YyOut>,
Ox1: Clone + Mul<Xx2, Output = OxOut> + Mul<Xy2, Output = OyOut> + Add<OxOut, Output = OxOut>,
Oy1: Clone + Mul<Yx2, Output = OxOut> + Mul<Yy2, Output = OyOut> + Add<OyOut, Output = OyOut>,
Ox2: Clone,
Oy2: Clone,
Xx2: Clone,
Xy2: Clone,
Yx2: Clone,
Yy2: Clone,
XxOut: Add<Output = XxOut>,
XyOut: Add<Output = XyOut>,
YxOut: Add<Output = YxOut>,
YyOut: Add<Output = YyOut>,
{
Matrix {
ox: self.xx.clone() * rhs.ox.clone() + self.xy.clone() * rhs.oy.clone() + self.ox.clone(),
oy: self.yx.clone() * rhs.ox + self.yy.clone() * rhs.oy + self.oy.clone(),
xx: self.xx.clone() * rhs.xx.clone() + self.xy.clone() * rhs.yx.clone(),
xy: self.xx * rhs.xy.clone() + self.xy * rhs.yy.clone(),
yx: self.yx.clone() * rhs.xx + self.yy.clone() * rhs.yx,
yy: self.yx * rhs.xy + self.yy * rhs.yy,
}
}
}
这段代码定义了一个通用的2D仿射变换矩阵结构体及其乘法操作。下面是对代码的详细解释:
pub struct Matrix<Ox, Oy, Xx, Xy, Yx, Yy> {
pub ox: Ox, // x方向平移量
pub oy: Oy, // y方向平移量
pub xx: Xx, // x方向缩放和旋转分量
pub xy: Xy, // x方向倾斜分量
pub yx: Yx, // y方向倾斜分量
pub yy: Yy, // y方向缩放和旋转分量
}
这个结构体表示一个2D仿射变换矩阵,通常表示为:
| 1 0 0 |
| ox xx xy |
| oy yx yy |
其中:
ox 和 oy 是平移分量(位于第二列第一行和第三列第一行)
xx 和 yy 是缩放和旋转分量(主对角线)
xy 和 yx 是倾斜/剪切分量(非对角线)
multiply 方法实现了两个矩阵的乘法运算,特点是:
允许输入矩阵和输出矩阵使用不同的类型
通过泛型和trait约束确保类型兼容性
pub fn multiply<Ox2, Oy2, Xx2, Xy2, Yx2, Yy2, OxOut, OyOut, XxOut, XyOut, YxOut, YyOut>(
&self,
rhs: &Matrix<Ox2, Oy2, Xx2, Xy2, Yx2, Yy2>
) -> Matrix<OxOut, OyOut, XxOut, XyOut, YxOut, YyOut>
输入矩阵(rhs)可以有不同于当前矩阵的类型参数
输出矩阵可以有不同于输入矩阵的类型参数
方法定义了大量trait约束来确保类型兼容性:
Xx1: Mul
表示Xx1类型可以与Xx2和Yx2相乘,结果类型为XxOut
XxOut: Add
表示XxOut类型支持加法操作且结果类型不变
矩阵乘法的计算遵循标准仿射变换矩阵乘法规则:
Matrix {
ox: self.xx.clone() * rhs.ox.clone() + self.xy.clone() * rhs.oy.clone() + self.ox.clone(),
oy: self.yx.clone() * rhs.ox + self.yy.clone() * rhs.oy + self.oy.clone(),
xx: self.xx.clone() * rhs.xx.clone() + self.xy.clone() * rhs.yx.clone(),
xy: self.xx * rhs.xy.clone() + self.xy * rhs.yy.clone(),
yx: self.yx.clone() * rhs.xx + self.yy.clone() * rhs.yx,
yy: self.yx * rhs.xy + self.yy * rhs.yy,
}
对应数学运算:
新矩阵 = 当前矩阵 × 输入矩阵
| 1 0 0 | | 1 0 0 | | 1 0 0 |
| ox' xx' xy' | = | ox xx xy | × | rhs.ox rhs.xx rhs.xy |
| oy' yx' yy' | | oy yx yy | | rhs.oy rhs.yx rhs.yy |
高度通用:支持不同类型的矩阵元素,只要它们满足必要的运算约束
类型安全:通过Rust的类型系统确保所有运算在编译时都是合法的
精确控制:每个分量的运算都有明确的类型约束
这种实现方式特别适合需要高精度或特殊数值类型的图形变换场景。