针对 Transform2D 结构体的详细解析如下:
pub struct Transform2D<T, Src, Dst> {
// 矩阵元素(列主序)
pub m11: T, pub m12: T, // 第一列:线性变换部分
pub m21: T, pub m22: T, // 第二列:线性变换部分
pub m31: T, pub m32: T, // 第三列:平移分量
// 类型标记(零大小类型)
#[doc(hidden)]
pub _unit: PhantomData<(Src, Dst)>,
}
m11 = 第一列第一个元素
m12 = 第一列第二个元素
m21 = 第二列第一个元素
...
3 泛型参数
T:数值类型(如 f32/f64)
Src/Dst:编译期坐标空间标记(类型安全的核心)
属性 | 作用 |
---|---|
#[repr©] | 保证C语言兼容内存布局,便于FFI交互 |
#[cfg_attr(feature = “serde”, …)] | 按需启用序列化能力 |
#[rustfmt::skip] | 保留矩阵元素的可视化对齐 |
元素 | 数学意义 | 示例场景 |
---|---|---|
m11, m12 | X轴方向变换 缩放/旋转时影响X坐标 | |
m21, m22 | Y轴方向变换 剪切变换时关联XY坐标 | |
m31, m32 | 平移分量 直接决定原点偏移 |
_unit: PhantomData<(Src, Dst)>
// 正确:世界空间→屏幕空间
let world_to_screen: Transform2D<f32, WorldSpace, ScreenSpace> = ...;
// 错误:类型不匹配(编译时报错)
let p: Point2D<f32, LocalSpace> = ...;
world_to_screen.transform_point(p);
对于 Transform2D
地址偏移 | 字段 | 值示例 |
---|---|---|
0x00 | m11 | 1.0 (缩放X) |
0x04 | m12 | 0.0 |
0x08 | m21 | 0.0 |
0x0C | m22 | 1.0 (缩放Y) |
0x10 | m31 | 50.0 (平移X) |
0x14 | m32 | 100.0(平移Y) |
0x18 | _unit | (无实际存储) |
明确区分不同坐标空间的转换
强制通过类型系统保证变换合法性
紧凑的存储布局(6个T类型元素)
通过feature gate支持可选功能(如序列化)
泛型设计适配不同数值类型
{
"m11": 1.0,
"m12": 0.0,
"m21": 0.0,
"m22": 1.0,
"m31": 0.0,
"m32": 0.0
}
// 转换为mint兼容格式
let mint_mat: mint::RowMatrix3x2<f32> = transform.into();
// 安全地进行字节级转换
let bytes: &[u8] = bytemuck::bytes_of(&transform);
空间效率
压缩存储比完整3×3矩阵节省25%-33%内存(f32下从36字节→24字节)
类型安全
PhantomData在编译期阻止如WorldSpace→LocalSpace的矩阵误用于ScreenSpace的点
硬件友好
列主序布局与OpenGL/DirectX等图形API原生兼容
语义明确
通过m31/m32直接暴露平移分量,比通用矩阵更易理解
这种设计完美平衡了:
数学严谨性(完整的仿射变换能力)
运行时效率(最优内存布局)
开发体验(类型安全的API)
/// 通用2D仿射变换矩阵(所有字段自动继承Copy约束)
#[derive(Clone, Copy, Debug, PartialEq)]
//#[repr(C, align(64))] // 强制缓存行对齐
#[repr(C)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'de>"))
)]
#[rustfmt::skip]// 保持矩阵代码视觉对齐
pub struct Transform2D<
X: Copy,
Y: Copy,
Xx: Copy,
Xy: Copy,
Yx: Copy,
Yy: Copy,
Src,
Dst,
> {
pub xx: Xx ,pub xy: Xy,
pub yx: Yx ,pub yy: Yy,
pub x: X ,pub y: Y,
_unit: PhantomData<(Src, Dst)>
}
#[repr(C)] // 保证C兼容内存布局
// #[repr(align(64))] 可选缓存行对齐
内存布局:确保字段顺序与声明严格一致
对齐优化:注释掉的64字节对齐可提升SIMD效率
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde",
serde(bound = "T: Serialize + Deserialize<'de>")
)]
条件编译:仅在启用serde特性时添加序列化能力
泛型约束:自动传播到序列化系统
#[derive(Clone, Copy, Debug, PartialEq)]
#[rustfmt::skip] // 保持矩阵视觉对齐
自动派生:
Clone/Copy:允许值语义复制
Debug:支持格式化打印
PartialEq:允许比较操作
格式化抑制:保留手工排列的矩阵样式
// 特化常量变换示例
type Translate2D<T> = Transform2D<T, T, Const<1>, Const<0>, Const<0>, Const<1>>;
常量传播:对Const类型可触发编译期计算
零成本抽象:PhantomData无运行时开销