- 前端
- UI组件
- 3D渲染
- 跨平台
- 游戏开发
【免费下载链接】makepad
Makepad is a creative software development platform for Rust that compiles to wasm/webGL, osx/metal, windows/dx11 linux/opengl
导读
本文聚焦 Makepad 仓库中的定点数(fixed-point)数学库 libs/i_float,以 libs/i_float/README.md 为骨架,结合 i_float 源码 深入讲解它的设计动机、数值原理与实战用法。读完本文,你将掌握:为什么固定精度计算能带来跨平台确定性、FixFloat/FixVec/FixAngle的精度与取值范围,以及如何在 Rust 工程中把它与泛型数学抽象、glam向量库、i_overlay几何布尔运算生态无缝衔接。
一、为什么需要定点数:确定性优先
IEEE-754 浮点数的表示与舍入行为在不同硬件、不同编译优化级别下可能存在细微差异。对于几何算法(多边形布尔运算、网格剖分、碰撞检测等),这种不确定性会导致同一份代码在不同设备上产生不同结果——这在跨平台 UI 与图形应用(如 Makepad 面向 wasm/WebGL、Metal、DX11、OpenGL 的多后端架构)中是难以接受的。
i_float库的解决方案是用定点数代替浮点数:以固定小数位数的整数存储数值,四则运算完全落在整数域内,天然具备确定性与可复现性。根据 Cargo.toml 的声明,该库定位为no-std、mathematics类别,版本 3.0.0,许可证 MIT。
二、核心特性一览
按照 README,i_float提供三层能力:
- FixFloat:定点数标量,支撑确定性的算术计算;
- FixVec:二维定点向量,提供向量运算的方法与运算符;
- FixAngle:定点角度工具,覆盖三角函数与角度换算。
在引入时只需声明:
use i_float::fix_float::FixFloat; use i_float::fix_vec::FixVec;需要说明的是,从当前仓库源码结构看,v3.0.0 将 README 中的概念命名落实为一套泛型抽象:标量对应FloatNumbertrait(libs/i_float/src/float/number.rs),2D 几何对应FloatPoint、FloatRect、FloatPointMath与整数版IntPoint(float/point.rs、float/rect.rs、float/vector.rs、int/point.rs)。阅读 README 示例时,可将其视为这套泛型体系的"定点数形态"。
三、FixFloat 原理:10 位小数位与精度边界
FixFloat的核心思想是用整数存储数值,其中固定的一部分二进制位表示小数部分。当前实现中,小数部分占用10 位,因此最小分辨率为1/1024 ≈ 0.001。
按 README 给出的表示规则,数值value的定点存储值为value × 1024:
| 实际数值 | 计算过程 | 定点存储值 |
|---|---|---|
| ≈ 0.001 | 1 / 1024 | 1 |
| 0.25 | 256 / 1024 | 256 |
| 1 | 1024 / 1024 | 1024 |
| 1.5 | (1024 + 512) / 1024 | 1536 |
| 2.25 | (2048 + 256) / 1024 | 2304 |
README 同时给出两个关键边界:
- 可表示范围:
2^21 - 1到-2^21 + 1,即约 ±2097151; - 最适宜区间:
1,000,000到-1,000,000,此区间内精度约 0.01。
理解这一边界很重要:定点数精度与取值范围此消彼长。小数位固定为 10 位后,能承载的整数位有限,超出适宜区间后绝对误差会随数值增大而放大。因此在几何应用中,应当先把坐标数据规整到合理尺度,再进入定点计算。
FixFloat以i64作为底层存储(README 明确说明),从而在保留浮点级精度的同时保证各平台行为一致。典型的算术用法如下:
let a = FixFloat::new_number(1); let b = FixFloat::new_number(2); let c = a + b; // 定点加法,结果确定从源码佐证的角度看,FloatNumber trait 以f32、f64两个实现定义了统一的标量数学接口,涵盖sqrt、log2、sin/cos/tan、sin_cos、acos/asin、绝对值与极值,以及截断/四舍五入两类类型转换(to_i16/to_i32/to_i64/to_f32/to_f64与to_round_i*系列)。任何自定义的定点标量类型只要实现该 trait,即可无缝接入上层几何算法,这正是"用 FixFloat 替代裸 i32/i64"的可扩展形态。
四、FixVec:二维定点向量运算
FixVec表示 2D 定点向量,README 给出的示例:
let a = FixVec::new_number(1, 1); let b = FixVec::new_number(1, -1); let c = a + b; // 向量加法在源码中,这套能力对应两个层面:
FloatPoint<T>(float/point.rs):泛型二维点结构,实现Add、Sub、Neg、Mul<T>(标量缩放)、AddAssign运算符,并提供dot_product(点积)、cross_product(叉积)、sqr_length、length、normalize、zero等方法,还实现了Display便于调试输出;FloatPointMath<P>(float/vector.rs):以静态方法形式提供与具体点类型解耦的通用向量运算:add、sub、scale、sqr_length、length、normalize、dot_product、cross_product。
其中FloatPointCompatibletrait(float/compatible.rs)要求实现from_xy、x()、y()与关联标量类型Scalar,原生[T; 2]数组即实现了它——因此FloatPointMath能直接操作[f64; 2]这样的轻量坐标,测试用例(vector.rs 内嵌 tests)也验证了这一点。
五、FixAngle:定点角度与三角函数
FixAngle提供定点角度相关的三角函数与角度换算能力。README 示例演示了从弧度构造角度并取正弦的完整链路:
let fix_angle = FixAngle::new_from_radians_f64(angle); // 由 f64 弧度构造定点角度 let fix_sin = fix_angle.sin(); // 定点正弦 let i64_sin = fix_sin.double(); // 取底层 i64 值三角函数正是定点数最典型的应用场景:用查表或整数多项式逼近替换硬件浮点函数,换取平台无关的确定性结果。在FloatNumbertrait 中,正弦、余弦、正切、sin_cos与反三角函数acos/asin均被列入统一接口(number.rs),为定点角度实现预留了标准入口。
六、安装与工程集成
在 Cargo 工程中引入:
[dependencies] i_float = "3.0.0"i_float提供如下特性开关(见 Cargo.toml):
| Feature | 默认 | 作用 |
|---|---|---|
core | 开 | 启用整数模块(int)、适配器(adapter)与三角形工具(triangle),并隐式启用float_pt |
float_pt | 随core开启 | 启用浮点标量与定点兼容模块(FloatNumber、FloatPointCompatible) |
glam | 关 | 提供与glam向量库的双向互转(需glam >= 0.27) |
serde | 关 | 为FloatPoint、IntPoint等结构派生Serialize/Deserialize |
得益于no-std定位与edition = "2024",它可在嵌入式、wasm 等受限环境使用;extern crate alloc(lib.rs)表明仅依赖alloc层。
6.1 与 glam 的互操作
启用glam特性后,integration/glam.rs 为glam::Vec2(f32)、glam::DVec2(f64)实现FloatPointCompatible,并提供From<FloatPoint<f32>> for glam::Vec2、From<glam::Vec2> for FloatPoint<f32>(f64 同理)以及IntPoint → glam::IVec2的转换。这使得现有图形代码可以在浮点向量与定点几何之间自由切换,无需重写算法主体。
6.2 FloatPointAdapter:浮点与整数的安全桥梁
在实际几何流程中,往往需要在浮点输入与定点/整数内核之间转换坐标。adapter.rs 中的FloatPointAdapter<P, I>解决了这个问题:它根据输入包围盒自动计算 2 的幂缩放系数(预留SCALE_SAFETY_BITS = 3位安全位,防止整数溢出),通过float_to_int/int_to_float完成双向转换,并支持with_scale、try_with_scale指定/校验用户缩放。缩放参数校验会返回ScaleTooLarge、ScaleNonPositive、ScaleNotFinite三类错误;调试构建下,越界点转换会触发 panic 提示,帮助尽早暴露数据问题。该适配器的往返一致性已由 adapter.rs 内嵌 tests 覆盖,包括 i64 大尺度场景与四舍五入规则。
6.3 Triangle 工具:基于叉积的几何判定
整数侧还提供Triangle(triangle.rs)静态工具:通过叉积求三角形二倍面积(area_two),派生is_clockwise、is_cw_or_line、is_line、clock_order等方向判定,以及is_contain/is_contain_exclude_borders点包含测试。叉积使用宽整数(T::Wide)累乘,避免了乘积累加时的溢出,这是它在多边形算法中安全可用的关键。
七、确定性计算的典型应用:i_overlay
i_float不是孤立存在的:从源码依赖看,i_overlay(多边形布尔运算库)在其 Cargo.toml 中依赖i_float,并在 boolean.rs、builder.rs、sweep.rs、predicate.rs 等核心模块中广泛使用IntPoint与整数算术。这构成了完整的确定性几何技术栈:i_float提供确定性的数值与几何原语,i_overlay在其之上实现并集、交集、差集等布尔运算,从而让裁剪、填充、栅格化等算法在跨平台场景下输出一致结果。
八、实战要点小结
- 范围意识:把数据控制在一百万元以内,精度可达 0.01;远离
2^21边界使用,避免精度劣化。 - 接口统一:把标量与点类型泛型化(实现
FloatNumber/FloatPointCompatible),可在 f32、f64 与定点类型间一键切换。 - 善用适配器:
FloatPointAdapter自动选择安全缩放,替代手写坐标缩放,降低溢出风险。 - 宽整数防溢出:向量/三角形的叉积、点积使用
T::Wide宽类型,避免中间结果溢出破坏确定性。 - 按需开启特性:无外部依赖场景用默认
core;需要与glam混用或序列化时,开启glam、serde。
结语
以 libs/i_float/README.md 为纲领,本文把FixFloat的定点表示、FixVec的向量运算与FixAngle的角度工具,逐一映射到 i_float 源码 的泛型抽象、运算符实现与测试用例上。确定性是 Makepad 多后端渲染与几何处理可靠性的基石,而i_float正是这块基石的数学内核。若需深入,建议从 float/point.rs、int/point.rs 与 adapter.rs 开始研读,并对照 i_overlay 观察它在真实布尔运算管线中的使用方式。
- 前端
- UI组件
- 3D渲染
- 跨平台
- 游戏开发
【免费下载链接】makepad
Makepad is a creative software development platform for Rust that compiles to wasm/webGL, osx/metal, windows/dx11 linux/opengl
相关推荐
PixiJS数学库与几何运算
PixiJS数学库与几何运算 PixiJS提供了强大的数学扩展模块 math extras 和几何运算能力,专门为Point和Rectangle对象提供了丰富的
前端图形学tbox数学库:定点数运算在嵌入式系统中的应用
tbox数学库:定点数运算在嵌入式系统中的应用 嵌入式开发的精度困境:为何浮点数成了绊脚石? 在嵌入式系统开发中,你是否经常面临这样的困境:传感器采集的物理量需
跨平台并发编程异步编程TBOOX/TBOX数学计算库:定点数运算与随机数生成
TBOOX/TBOX数学计算库:定点数运算与随机数生成 痛点:嵌入式与高性能场景下的数学计算挑战 在嵌入式系统、游戏开发、实时控制系统等场景中,传统的浮点数运算
后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考