windows-numerics 实战指南:在 Rust 中使用 Windows.Foundation.Numerics 向量与矩阵类型
【免费下载链接】windows-rsRust for Windows项目地址: https://gitcode.com/GitHub_Trending/wi/windows-rs
windows-numerics是 windows-rs 工作区中提供 Windows 图形数学类型的 crate,它投影了Windows.Foundation.Numerics命名空间下的 POD 值类型:Vector2、Vector3、Vector4、Matrix3x2与Matrix4x4。这些类型与 Direct2D、DirectComposition、Canvas 等 Windows 图形与合成 API 直接互操作,无需任何转换即可跨越 ABI 边界。阅读本文后,你将掌握这些类型的引入方式、完整 API 面、运算符语义、平台约束,并能直接将其接入图形渲染与动画工作流。
这个 crate 解决什么问题
当 Windows 图形或合成 API 接受Windows.Foundation.Numerics值时,就需要使用windows-numerics。crate 中的每个结构体都是#[repr(C)]的普通数据(POD)类型,字段全部公开,布局与 Windows 端一一对应,因此向量和矩阵可以不经转换直接传给 API。
需要说明的是,它并非通用数学引擎:不提供四元数(quaternion)、平面(plane)、SIMD 专用操作或更完整的变换集合。如果只需 Rust 侧纯数学运算,建议选择通用数学 crate;windows-numerics专注于本 crate 投影出的五个值类型(详见 crate 文档 的 "When to use" 部分)。
快速开始
在Cargo.toml中加入依赖(版本声明见 crate README):
[dependencies.windows-numerics] version = "0.100"一个典型的首步工作流:用目标 Windows API 期望的同一批类型做计算。例如计算一个位置向量加上偏移,再把结果转成平移矩阵:
use windows_numerics::{Matrix3x2, Vector2}; let position = Vector2::new(20.0, 30.0); let offset = Vector2::new(5.0, -10.0); let translated = position + offset; let transform = Matrix3x2::translation(translated.x, translated.y); assert_eq!((transform.m31, transform.m32), (25.0, 20.0));注意保持数值类型为f32——这些 Windows 数值类型没有f64变体,这是由其 ABI 定义决定的。
类型、布局与 Windows 签名
五个类型在 bindings.rs 中定义,全部为#[repr(C)]结构体并派生Clone、Copy、Debug、Default、PartialEq,同时实现windows_core::RuntimeType,携带完整的 Windows 类型签名,例如Matrix3x2的签名为struct(Windows.Foundation.Numerics.Matrix3x2;f4;f4;f4;f4;f4;f4)。这意味着它们满足windows-core对值类型的运行时类型要求,可直接参与 WinRT 互操作。
向量:Vector2 / Vector3 / Vector4
三个向量类型提供了一致的 API 面,实现在 vector2.rs、vector3.rs 与 vector4.rs 中:
- 构造器:
new(x, y[, z[, w]]);zero()、one();轴向单位向量unit_x()、unit_y()(以及Vector3::unit_z()、Vector4::unit_w())。 - 运算:
dot(&self, rhs)点积;length()、length_squared();distance()、distance_squared();normalize();Vector3额外提供cross()叉积。 - 运算符:
Neg、Add、Sub、Div、Mul均支持自有值或借用值的组合(v + u、v + &u、&v + u、&v + &u全部可用);向量之间的乘除法是**逐分量(component-wise)**的,标量乘除使用f32。测试用例 numerics.rs 通过宏test_with_same_type与test_with_scalar系统地覆盖了这四类借用组合。
性能与安全提示
- 仅做比较时优先用
length_squared/distance_squared,避免一次平方根计算。实现上二者分别等价于self.dot(self)与(self - value).length_squared()。 - 调用
normalize前必须检查零长度向量——其实现是self / self.length(),零向量会产生除零,得到非有限值(NaN/Inf)。 - 需要平方根、三角函数的
length、distance、normalize、旋转、斜切等方法在 lib.rs 中以#[cfg(feature = "std")]条件编译;基础的构造、算术与点积在关闭std特性后依然可用(crate 支持no_std)。
矩阵与变换:Matrix3x2 / Matrix4x4
Matrix3x2:2D 仿射变换
Matrix3x2表示 2D 仿射变换(平移、旋转、缩放、斜切),实现在 matrix3x2.rs:
identity()、translation(x, y)为const fn;rotation(angle)/rotation_around(angle, center):围绕原点或指定中心旋转,角度单位为度,内部经angle.to_radians().sin_cos()换算;scale(sx, sy)/scale_around(sx, sy, center):缩放,支持指定中心;skew(angle_x, angle_y)/skew_around(...):斜切,角度同样为度,内部使用to_radians().tan();- 运算符:
Add、Sub、Mul(矩阵乘法组合变换)与Mul<f32>标量乘法。
Matrix4x4:3D 变换
Matrix4x4提供 3D 平移、绕 Y 轴旋转与透视投影,实现在 matrix4x4.rs:
translation(x, y, z)(const fn);rotation_y(degree):绕 Y 轴旋转,角度为度;perspective_projection(depth):透视投影矩阵,depth > 0时产生透视缩短(m34 = -1.0 / depth),非正值则投影系数为 0(无透视效果);Add、Sub、Mul、Mul<f32>与 3x2 语义一致。
矩阵乘法的顺序约定
矩阵乘法用于组合变换,但顺序约定必须与目标 Windows API 保持一致。Matrix3x2的乘法实现(matrix3x2.rs)遵循其自身的行列展开式;如果你的既有代码来自另一个数学库,不要想当然地沿用其顺序约定,而应用代表性点验证结果。测试文件 matrix3x2.rs 提供了平移、旋转、缩放、斜切及组合变换的断言参考。
平台约束与常见陷阱
- 初始化方式:类型字段全部公开且无私有布局约束,可直接用结构体字面量构造(如示例 transform.rs 直接为
Matrix3x2逐字段赋值);但务必初始化每一个字段,否则编译失败——更稳妥的做法是优先使用new与各构造器。 - 相等比较:
PartialEq是精确的浮点相等。对计算得到的值做断言或比较时,应使用适合应用场景的容差(epsilon),不要直接依赖精确相等。 - 非有限值:归一化零向量、传入非法投影参数都可能产生非有限值(NaN/Inf),调用方需自行防护。
std特性:默认启用std,提供length、distance、normalize、旋转、斜切所需的平方根与三角函数;关闭后基础值类型与算术仍然可用(见 Cargo.toml 的 feature 定义,std会连带启用windows-core/std)。- 唯一依赖:crate 仅依赖
windows-core,并且lib.rs中声明了#![forbid(unsafe_code)]——整个 crate 是纯安全代码。
从源码理解构建与测试
如何生成绑定
src/bindings.rs 由tool_bindings工具依据 numerics.txt 生成,该文件内容为:
--out crates/libs/numerics/src/bindings.rs --flat --minimal --filter Windows::Foundation::Numerics::{Matrix3x2, Matrix4x4, Vector2, Vector3, Vector4}即从元数据中筛选出这五个值类型生成#[repr(C)]结构体与RuntimeType实现;而固有方法(inherent methods)与运算符 trait 实现是手工编写的(分布在vector2.rs、vector3.rs、vector4.rs、matrix3x2.rs、matrix4x4.rs五个模块中,由 lib.rs 统一导出)。
运行测试
在仓库根目录执行:
cargo test -p windows-numericscrate 自身的测试依赖集中在工作区测试目录,例如 numerics.rs(992 行,覆盖向量与矩阵的构造、点积、长度、归一化、距离及全部运算符组合)与 matrix3x2.rs。
示例与下一步
这些类型已大量出现在仓库的真实图形工作流中:
- 2D 矩阵实战:canvas transform 示例 直接构造旋转
Matrix3x2,配合ctx.with_transform绘制动画方块,展示了字段字面量构造与旋转矩阵在 Canvas 中的真实用法; - 向量传入合成 API:composition animation 示例 演示把
Vector2/Vector3等值传给 Composition 动画 API。
Canvas、Composition、Direct2D、DirectComposition 等示例(见 crates/samples 目录)都在真实使用这些类型。建议从上述两个示例入手,先跑通 2D 变换,再进入合成动画场景,逐步建立"同一批类型贯穿 Rust 与 Windows 图形 API"的直觉。
内部文档说明
本文后续的构建与维护细节(绑定生成、测试命令)面向贡献者,日常使用windows-numerics无需关注;如果你想深入参与 crate 维护,可对照 numerics.txt 与五个手写实现模块了解生成与手写部分的分工。
【免费下载链接】windows-rsRust for Windows项目地址: https://gitcode.com/GitHub_Trending/wi/windows-rs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考