# gfxmath-vec3
A simple 3D math library to compute 3 dimensional vectors.
- [Usage](#usage)
* [Vec3](#vec3)
* [Operators](#operators)
- [Cross Product](#cross-product)
- [Dot Product](#dot-product)
- [Known Limitations](#known-limitations)
* [Left-Hand Primitives](#left-hand-primitives)
* [Hash Implementation](#hash-implementation)
- [License](#license)
# Usage
## Vec3
Vec3 uses the standard { x, y, z } coordinate system. We can obtain the coefficients
for each axis by calling its member.
The structure of Vec3 is as follows:
```rust
pub struct Vec3<T> {
pub x: T,
pub y: T,
pub z: T
}
```
The creation of a Vec3 objection can be done via multiple ways.
```rust
use gfxmath_vec3::Vec3;
// Standard construction
let v = Vec3 { x: 3.0, y: 1.0, z: 0.5 };
// Using `new` function
let v = Vec3::new(3.0, 1.0, 0.5);
// Using tuples
let v: Vec3<f32> = (3.0, 4.0, 9.0).into();
// Using macros
use gfxmath_vec3::vec3;
let v = vec3!(3.0, 4.0, 9.0);
assert_eq!(3.0, v.x);
assert_eq!(1.0, v.y);
assert_eq!(0.5, v.z);
```
## Operators
Common mathematical operators are implemented for Vec3.
* `+` , `+=`
* `-` , `-=`
* `*` , `*=`
* `/` , `/=`
```rust
// Reminder: Rust automatically infers floats to `f64` and integers to `i64`.
let v1 = Vec2::new(3.0, 9.0, 2.5);
let v2 = Vec2::new(4.0, 5.0, 3.0);
let res = v1 + v2;
assert_eq!( 7.0, res.x);
assert_eq!(14.0, res.y);
assert_eq!( 5.5, res.z);
```
### Cross Product
```rust
use gfxmath_vec3::ops::Cross;
use gfxmath_vec3::Vec3;
let a = Vec3::new(1.0, 3.0, 2.5);
let b = Vec3::all(2.0);
let res = a.cross(b);
assert_eq!(1.0, res.x);
assert_eq!(3.0, res.y);
assert_eq!(-4.0, res.z);
```
### Dot Product
```rust
use gfxmath_vec3::{Vec3, ops::Dot};
let a = Vec3::new(3.0, 4.0, 5.0);
let b = Vec3::new(2.0, 1.0, 3.0);
let res = a.dot(b);
assert_eq!(25.0, res);
```
# Known Limitations
## Left-Hand Primitives
One caveat is that operators where the Left-Hand side is a primitive has limited support. This is due to restrictions for trait implementations. `impl <T> Add<Vec3<T>> for T` is illegal within Rust syntax (due to the trailing `T`) because the implementation must be for a known type for non-local traits and types. Since `Add` is from the `core` package and `T` (the type to be implemented for) is not derived from a local trait, this is not possible.
At the time of this writing, primitives that work on the Left-Hand Side for common operators are `f32`, `f64`, `i32`, and `i64`.
```rust
// Works
let lhs: f32 = 4.0;
let rhs = Vec3::<f32>::new(3.0, 4.0, 2.5);
let res = lhs + rhs;
// NOT SUPPORTED!!
let lhs: u32 = 4;
let rhs = Vec3::<u32>::new(3, 4, 2);
let res = lhs + rhs;
```
## Hash Implementation
Currently, Hash implementations are limited for the following types:
- `f32`
- `f64`
- `i32`
- `i64`
- `u32`
- `u64`