## 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 Mar 13, 2022 Mar 11, 2022 Mar 10, 2022 Mar 9, 2022

#420 in Data structures

MIT/Apache

49KB
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.

``````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.

``````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
// 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.

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