Search code examples
typesrustlinear-algebra

Idiomatic way to declare 2D, 3D vector types in Rust?


I'm looking to write some small library that use 2D and 3D points or directions in space
(vector in vector/matrix sense, not Rust's Vec).

Rust doesn't impose rules here, so you can make a tuple of floats, or a new struct with x, y, z members. or a single data: [f64; 3] member.

The reason I'd like to define a type here instead of using [f64; 3], is so I can declare methods such as length, normalized, also Add, Sub operators.

Whats a good basis to declare small 2D - 3D fixed sized data types on?


Note, while there are good existing libraries, I'd like to write my own since it only needs some basic operations, and I like to understand whats going on internally.


Solution

  • You should most certainly use a library for that! There are many good ones (see below) and they mostly don't occur any overhead, even if you don't use all the features. It will save you a lot of time, trust me.


    But for educational purposes, here are some thought on how I would approach designing such a library. What I would consider "idiomatic" in Rust.

    • Use a struct with x, y and z fields instead of an array or tuple. That makes it very natural to access these individual scalars, e.g. pos.x.

    • Implement all relevant operator overloads (e.g. std::ops), so that you can simply add and subtract vectors.

    • Provide useful and commonly used methods, like length and normalize.

    • Unless its for a very specific/narrow use case, you likely want to make the scalar type generic. You then likely want to use something like num_traits to add trait bounds.

    • You can also try to abstract over different dimensions via const generics, but that makes your job even harder.

    • Use strong typing! Rust is all about strong typing, so make use of that. For example, distinguish between point (location) and vector (displacement). And maybe also directions (normalized vectors). And while we're at it, also have separate types for points represented in homogeneous coordinates.

    But again, doing all that properly takes time and care. I did that once and ended up with lina, which I am very happy with. Though it's not very widely used yet and maybe uses too much strong typing for some people. But as I said there are many other good libraries: cgmath, nalgebra, glam, ultraviolet vek, and more!