#point #geometry #multidimensional #coordinate #points #graphics

no-std point-nd

A simple and flexible no-std struct to model points on axes of any dimensions

8 releases (4 breaking)

0.5.0 May 17, 2022
0.4.1 Mar 13, 2022
0.3.0 Mar 11, 2022
0.2.1 Mar 10, 2022
0.1.1 Mar 9, 2022

#556 in Data structures

Download history 10/week @ 2024-02-26 80/week @ 2024-04-01

80 downloads per month

MIT/Apache

50KB
612 lines

PointND

A simple and flexible no-std struct to model points on axes of any dimensions

Compatibility

This crate was designed to be no_std and wasm compatible, and has been tested in those environments.

This crate uses constant generics, it is recommended for use with a Rust version of at least 1.51.

Basic Usage

As PointND dereferences to a slice, all methods implemented for slices are available with this

Making a Point

// Creating a 2D point from a given array
let arr = [0,1];
let p = PointND::new(arr);

// Creating a 3D point from values of a given slice
let vec = vec![0, 1, 2];
let p = PointND::<_, 3>::from_slice(&vec);

// Creating a 4D point with all values set to 5
let p = PointND::<_, 4>::fill(5);

Querying Values and Properties

If the dimensions of the point are within 1..=4, it is recommended to use the convenience getters for accessing values.

let p = PointND::new([0, 1]);

// As the point has 2 dimensions, we can access
//  it's values with the x() and y() methods
let x: &i32 = p.x();
let y = p.y();

assert_eq!(*x, arr[0]);
assert_eq!(*y, arr[1]);

// If the point had 3 dimensions, we could use the above and:
//  let z = p.z();
// Or with 4 dimensions, the above and:
//  let w = p.w();

The above methods are not implemented for PointND's with more than 4 dimensions.

We must use indexing instead. See the documentation for other crates which make direct indexing easier

let p = PointND::new([0,1,2,3,4,5]);

// ERROR: Not implemented for PointND of 6 dimensions
// let x = p.x();

let x: i32 = p[0];
let y_to_z = p[1..3];

To get the dimensions of a point, use the dims method.

let p = PointND::new([0, 1, 2, 3]);

let dims: usize = p.dims();
assert_eq!(dims, 4);

Transforming Values

If the dimensions of the point are within 1..=4, it is recommended to use the convenience setters for setting values.

let mut p = PointND::new([0, 1]);

// As the point has 2 dimensions, we can set
//  it's values with the set_x() and set_y() methods
// There are set_z() and set_w() methods available for
//  points with 3 and 4 dimensions respectively
p.set_x(-10);
p.set_y(-20);

The above methods are not implemented for PointND's with more than 4 dimensions.

We must use indexing instead.

let p = PointND::new([0,1,2,3,4]);

// ERROR: Not implemented for PointND of 5 dimensions
// p.set_x(1200);

p[0] = 1200;

Complex transformations can be made via functions passed to the apply, apply_vals, apply_dims and apply_point methods.

See the documentation for more info.

let add_ten = |i: i32| i + 10;
let double  = |i: i32| i * 2;
let sum     = |a: i32, b: i32| a + b;

let p1 = PointND::new([0,1,2,3,4,5]);
let p2 = PointND::new([0,1,2,3,4,5])
         // Adds ten to each item
         .apply(add_ten)
         // Doubles items at indexes 0, 1 and 2
         .apply_dims(&[0,1,2], double)
         // Adds items in p2 to respective items in p1
         .apply_point(p1, sum);

Iterating

Iterating over a PointND is as easy as:

let mut p = PointND::new([0,1]);

for _ in p.iter()      { /* Do stuff     */ }
for _ in p.iter_mut()  { /* Change stuff */ }
for _ in p.into_iter() { /* Move stuff (unless items implement Copy) */ }

Contributing

Any suggestions for the codebase, documentation, README (or anything) are more than welcome!

If there are any problems or queries, please submit an issue in our GitHub repo.

API Changes

Breaking API changes are still a possibility in the future. However, as of v0.5.0 this has become far less likely and future major releases (if any) will most likely add functionality instead of revamping existing ones.

The full changelog can be found in our GitHub repo.

Our GitHub repo is always a few steps ahead of the version available on crates.io, so it may be worth checking for sweet new features and bugfixes.

License

This crate is available under the MIT and/or Apache2.0 licenses.

Dependencies