25个版本 (破坏性更新)
0.19.0 | 2024年6月23日 |
---|---|
0.18.0 | 2023年1月14日 |
0.17.0 | 2022年4月30日 |
0.16.0 | 2022年1月2日 |
0.2.0 | 2018年10月22日 |
#729 in 数学
10,182 monthly downloads
用于 72 个包(直接使用53个)
2MB
39K SLoC
线性代数库 用于Rust编程语言。
lib.rs
:
nalgebra-glm − 简化模式的nalgebra
nalgebra-glm 是一个类似于GLM的接口,用于 nalgebra 通用线性代数库。 GLM 本身是一个流行的C++线性代数库,主要针对计算机图形。因此 nalgebra-glm 从GLM中汲取灵感,定义了一个简单易用的API,适用于简单的图形应用程序。
nalgebra-glm 的所有类型都是 nalgebra 类型别名的别名。因此,两者之间具有完全无缝的互操作性。
入门
首先,你应该查看官方的 GLM API文档,因为 nalgebra-glm 实现了其中大部分功能。要将 nalgebra-glm 添加到你的项目中,你应该将其添加到你的 Crates.toml
文件中作为依赖项。
[dependencies]
nalgebra-glm = "0.3"
然后,你应该在你的 lib.rs
或 main.rs
文件中添加一个 extern crate
语句。强烈建议你将 glm
添加为一个包别名,这样你将能够使用模块前缀 glm::
调用 nalgebra-glm 的函数。例如,你将编写 glm::rotate(...)
而不是更冗长的 nalgebra_glm::rotate(...)
。
extern crate nalgebra_glm as glm;
特性概述
nalgebra-glm 支持了 C++ GLM 库中大多数线性代数相关功能。从数学的角度来看,它支持所有常见的变换,如旋转、平移、缩放、剪切和投影,但在齐次坐标中进行操作。这意味着所有 2D 变换都表示为 3x3 矩阵,所有 3D 变换都表示为 4x4 矩阵。这比 nalgebra 的 变换类型 在计算效率和内存效率方面较低,但它的优点是使用起来更简单。
与 GLM 的主要区别
虽然 nalgebra-glm 遵循 C++ GLM 库的功能路线,但仍然存在许多区别,它们大多是语法上的。主要区别包括
- 所有函数名称都使用
snake_case
,这是 Rust 的约定。 - 所有类型名称都使用
CamelCase
,这是 Rust 的约定。 - 除了标量之外,所有函数参数都是通过引用传递的。
- 最通用的向量和矩阵类型是
TMat
和TVec
,而不是mat
和vec
。 - 一些功能尚未实现,将来应该添加。特别是,没有打包函数可用。
- 一些功能尚未实现,并且永远不会实现。这包括与颜色空间相关的函数和最近点计算。对于这些,应使用其他 crate。例如,最近点计算可以由 ncollide 项目处理。
此外,由于 Rust 不允许函数重载,所有函数都必须有一个独特的名称。以下是 nalgebra-glm 随意选择的几个规则
- 操作在 2D 中的函数通常以
2d
后缀结尾,例如,glm::rotate2d()
用于 2D,而glm::rotate()
用于 3D。 - 操作在向量上的函数通常以
_vec
后缀结尾,可能后跟向量的维度,例如glm::rotate_vec2()
。 - 所有与四元数相关的函数都以前缀
quat_
开始,例如glm::quat_dot(q1, q2)
。 - 所有转换函数都有唯一的名称,如 以下 所述。
向量和矩阵构造
可以使用几种方法构造向量、矩阵和四元数
- 使用与它们类型相同的函数名。例如,
glm::vec3(x, y, z)
将创建一个 3D 向量。 - 使用
::new
构造函数。例如,Vec3::new(x, y, z)
将创建一个 3D 向量。 - 使用以
make_
为前缀的函数从切片构建一个向量或矩阵。例如,使用glm::make_vec3(&[x, y, z])
将创建一个三维向量。请注意,使用此类函数构建矩阵时,其组件在切片中需要以列主序排列。 - 使用几何构造函数。例如,使用
glm::rotation(angle, axis)
将从角度(以弧度为单位)和轴构建一个 4x4 的齐次旋转矩阵。 - 使用下一节中描述的混洗和转换。
混洗
向量混洗是 nalgebra 本身的原生功能。因此,您也可以在 nalgebra-glm 的所有向量中使用它。混洗作为方法得到支持,并且仅在维度 3 内有效,即您只能引用 x
、y
和 z
这些组件,并且只能使用此技术创建 2D 或 3D 向量。以下是一些示例,假设 v
是具有浮点组件的向量
v.xx()
等同于glm::vec2(v.x, v.x)
以及Vec2::new(v.x, v.x)
。v.zx()
等同于glm::vec2(v.z, v.x)
以及Vec2::new(v.z, v.x)
。v.yxz()
等同于glm::vec3(v.y, v.x, v.z)
以及Vec3::new(v.y, v.x, v.z)
。v.zzy()
等价于glm::vec3(v.z, v.z, v.y)
以及Vec3::new(v.z, v.z, v.y)
。
从 x
、y
和 z
中选择两个或三个组件的组合都将有效。
转换
将一种代数类型转换为另一种类型通常很有用。在 nalgebra-glm
中,转换类型主要有两种方法
- 使用形式为
type1_to_type2
的函数,以便将type1
的实例转换为type2
的实例。例如glm::mat3_to_mat4(m)
将 3x3 矩阵m
转换为 4x4 矩阵,通过在右侧添加一列和左侧添加一行实现。这些现在行和列填充为 0,除了对角元素设置为 1。 - 使用
convert
、try_convert
或convert_unchecked
中的一个函数。这些函数直接从 nalgebra 重导出,并且非常灵活
convert
函数可以将任何类型(特别是来自 nalgebra 的几何类型如Isometry3
)转换为等效但更通用的另一种代数类型。例如,let sim: Similarity3<_> = na::convert(isometry)
将Isometry3
转换为Similarity3
。此外,let mat: Mat4 = glm::convert(isometry)
将Isometry3
转换为 4x4 矩阵。这也会转换标量类型,因此:let mat: DMat4 = glm::convert(m)
其中m: Mat4
将有效。然而,转换不会双向进行;你不能使用glm::convert
将Matrix4
转换为Isometry3
,因为这可能导致意外结果,如果矩阵不符合等距的要求。- 如果你仍然需要这种转换,可以使用
try_convert
,它将测试正在转换的对象是否符合目标类型的代数要求。如果不满足要求,将返回None
。 - 《convert_unchecked`函数将忽略这些测试,并始终执行转换,即使这会破坏目标类型的不可变性。必须谨慎使用!实际上,这是将`nalgebra-glm`生成的同质变换和`nalgebra`的特定变换类型(如`Isometry3`)之间进行转换的推荐方法。只是要小心确保你的转换是有意义的。
我应该使用nalgebra还是nalgebra-glm?
这取决于你的喜好和背景。`nalgebra`在整体上更强大,因为它允许更强的类型,并且远远超出了简单的计算机图形数学。然而,对于那些不熟悉变换的抽象数学概念的人来说,它有一个学习曲线。而`nalgebra-glm`具有更直观的函数,并受益于互联网上现有的各种针对原始C++ GLM库的教程。
总的来说,如果你已经熟悉C++ GLM库,或者熟悉使用齐次坐标(如3D变换的4D矩阵),那么使用`nalgebra-glm`会更有成功的机会。如果你更倾向于更严谨的变换处理,具有类型级别的限制,那么请选择`nalgebra`。如果你需要动态大小的矩阵,也应该选择`nalgebra`。
请注意,`nalgebra-glm`只是`nalgebra`的另一种API。因此,你可以非常有效地使用两者并从它们的优势中受益:当数学严谨性不是那么重要时使用`nalgebra-glm`,当需要更丰富的类型和更强大的线性代数运算(如矩阵分解和切片)时使用`nalgebra`本身。只是记住,所有`nalgebra-glm`的类型都只是`nalgebra`类型的别名,并请记住,可以将`Isometry3`转换为`Mat4`,反之亦然(见转换部分)。
依赖项
~0.8-2MB
~48K SLoC