在Rust中声明2D,3D矢量类型的惯用方法?

时间:2016-08-31 03:40:27

标签: types rust linear-algebra

我正在寻找一些在空间中使用2D和3D点或方向的小型库(矢量/矩阵感中的矢量,而不是Rust Vec)。< / p>

Rust不会在此处施加规则,因此您可以制作浮动元组或带struct成员的新x, y, z元组。或单个data: [f64; 3]成员。

我想在此处定义类型而非使用[f64; 3]的原因是,我可以声明lengthnormalized等方法,{{1} },Add运营商。

什么是宣布小型2D-3D固定大小数据类型的良好基础?

请注意,虽然有很好的现有库,但我想编写自己的库,因为它只需要一些基本操作,我想了解内部发生的事情。

3 个答案:

答案 0 :(得分:6)

这个问题非常广泛并且没有明确表达您想要的最佳方式。这很大程度上取决于你打算用它做什么。

与其他答案相比,我建议采用略有不同的解决方案:使用带有x, y, z组件的结构,并在最大范围内使用强类型

矢量可用于表示许多事物(点,颜色......);你在谈论太空中的2D和3D点。首先要注意的是点向和向量向量之间的差异。 Here是math.stackexchange的一个很好的答案,可以很好地解释这个主题。

这种差异可以反映在类型系统中以捕获逻辑错误。这正是cgmath正在做的事情。所以我说你实际上想要两种类型定义如下:

struct Point3 {
    pub x: f32,
    pub y: f32,
    pub z: f32,
}
  • 为什么没有元组结构或数组?编写v.x的语义比v.0v[0]更清晰。如果你有一个矢量类型来表示任意数据,后两种情况是合适的。但正如我所提到的,我认为强打字是一个很好的选择,我们应该相应选择好名字。
  • 为什么pub为什么不呢?如果你在谈论空间中的点或方向,则没有无效的向量(忽略此处的NaN浮点值)。因此,限制对字段的访问并不是真正的理由。
  • 为什么f32好问题......实际上你应该使用一个类型参数,但是你需要有某种特质限制......

......这让我得出了你的结论,你不会喜欢:我认为这样做是正确的,并且是&#34;惯用的&#34;在这种情况下需要一些工作。这项工作由cgmath等图书馆正确完成。这个cgmath库特别有一个非常好的API设计,IMO。大多数功能都是通过特征(如VectorSpace)来实现的,这些特征反映了它背后的一些数学。我也想为自己的项目自己编写矢量类型,但我最终确信使用经过良好测试,设计良好的库。

所以怎么做&#34;对&#34;?几乎cgmath如何做到:

  • 强力打字
  • 正确命名
  • 具有抽象特征的大部分功能

答案 1 :(得分:2)

我建议定义一个 newtype ,即一个包含单个成员的元组结构。

struct Vector3D([f64; 3]); // wraps an array
struct Vector3D((f64, f64, f64)); // wraps a 3-tuple

可以使用它们的位置(从零开始)作为字段的名称来访问元组结构的字段。例如,如果您的变量v类型为Vector3D,则v.0将评估为内部字段。您可以选择公开或不公开此字段;要公开,请在字段类型名称之前添加关键字pub

struct Vector3D(pub [f64; 3]);

请注意,此新Vector3D不会从包装类型继承任何方法或特征;您可以在此类型上提供您喜欢的任何API。

答案 2 :(得分:1)

像弗朗西斯说的那样,你可以使用包装类型,但如果你不需要它与其他类型真正区别并且能够利用现有类型的方法,你可以使用类型别名:

type Vector3D = (f64, f64, f64);

type Vector3D = [f64; 3];