【学Rust写CAD】17 通用2D仿射变换矩阵结构体(matrix/generic.rs)

源代码

// 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 方法实现了两个矩阵的乘法运算,特点是:

  1. 允许输入矩阵和输出矩阵使用不同的类型

  2. 通过泛型和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约束

方法定义了大量trait约束来确保类型兼容性:

  1. 乘法相关约束:
  • Xx1: Mul + Mul

  • 表示Xx1类型可以与Xx2和Yx2相乘,结果类型为XxOut

  1. 加法相关约束:
  • XxOut: Add

  • 表示XxOut类型支持加法操作且结果类型不变

  1. Clone约束:
  • 所有输入类型都需要可克隆,因为乘法过程中需要多次使用它们
计算逻辑

矩阵乘法的计算遵循标准仿射变换矩阵乘法规则:

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     |
特点
  1. 高度通用:支持不同类型的矩阵元素,只要它们满足必要的运算约束

  2. 类型安全:通过Rust的类型系统确保所有运算在编译时都是合法的

  3. 精确控制:每个分量的运算都有明确的类型约束

这种实现方式特别适合需要高精度或特殊数值类型的图形变换场景。

你可能感兴趣的:(学Rust写CAD,rust,矩阵,CAD)