# gfxmath-vec4 A simple 3D math library to compute 3 dimensional vectors. - [Usage](#usage) * [Vec4](#vec4) * [Operators](#operators) - [Cross Product](#cross-product) - [Dot Product](#dot-product) - [Normalize](#normalize) - [Known Limitations](#known-limitations) * [Left-Hand Primitives](#left-hand-primitives) * [Hash Implementation](#hash-implementation) - [License](#license) # Usage ## Vec4 Vec4 uses the `{ x, y, z }` coordinate system, with the trailing `w`. We can obtain the coefficients for each axis by calling its member. The structure of Vec4 is as follows: ```rust pub struct Vec4 { pub x: T, pub y: T, pub z: T, pub w: T } ``` Depending on the context, Vec4 could be used to represent different types of data. In graphics computing, it is common to use Vec4 to represent both point space and vectors, using the `w` to distinguish the two. For example, a `w` that equals to `0.0` would be considered as a vector while a non-zero value would be considered a point in 3D space. Other times, the `w` could be used to represent the scaling factor of the vector or point. In the case for colors, we could use `{ x, y, z, w }` to represent (red, green, blue, alpha). The creation of a Vec4 objection can be done via multiple ways. ```rust use gfxmath_vec4::Vec4; // Standard construction let v = Vec4 { x: 3.0, y: 1.0, z: 0.5, w: 4.2 }; // Using `new` function let v = Vec4::new(3.0, 1.0, 0.5, 4.2); // Using tuples let v: Vec4 = (3.0, 4.0, 9.0, 4.2).into(); // Using macros use gfxmath_vec4::vec4; let v = vec4!(3.0, 4.0, 9.0, 4.2); assert_eq!(3.0, v.x); assert_eq!(1.0, v.y); assert_eq!(0.5, v.z); assert_eq!(4.2, v.w); ``` ## Operators Common mathematical operators are implemented for Vec3. * `+` , `+=` * `-` , `-=` * `*` , `*=` * `/` , `/=` ```rust // Reminder: Rust automatically infers floats to `f64` and integers to `i64`. let v1 = Vec4::new(3.0, 9.0, 2.5, 1.0); let v2 = Vec4::new(4.0, 5.0, 3.0, 0.0); let res = v1 + v2; assert_eq!( 7.0, res.x); assert_eq!(14.0, res.y); assert_eq!( 5.5, res.z); assert_eq!( 1.0, res.w); ``` ### Cross Product The cross product returns a 3D vector with a zero `w` value. ```rust use gfxmath_vec4::ops::Cross; use gfxmath_vec4::Vec4; let a = Vec4::new(1.0, 3.0, 2.5, 9.0); let b = Vec4::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); assert_eq!( 0.0, res.w); ``` ### Dot Product The dot product of Vec4 only computes the dot product of the (x, y, z) component of the vector. ```rust use gfxmath_vec4::{Vec4, ops::Dot}; let a = Vec4::new(3.0, 4.0, 5.0, 3.0); let b = Vec4::new(2.0, 1.0, 3.0, 9.0); let res = a.dot(b); assert_eq!(25.0, res); ``` ### Normalize We can use `norm` from `gfxmath_vec4::ops::Norm` to normalize the vector. This may be subject to change in the future due to `norm` being a word used to represent the length of the vector. `Norm` was selected for compactness so it may be confusing for some people. ```rust use gfxmath_vec4::ops::Norm; use gfxmath_vec4::Vec4; let a = Vec4::::new(3.0, 4.0, 0.0, 0.0); let an = a.norm().unwrap(); assert_eq!(3.0/5.0, an.x); assert_eq!(4.0/5.0, an.y); assert_eq!(0.0, an.z); assert_eq!(0.0, an.w); // this should always be zero so that this object is represented as a vector ``` # 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 Add> 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 = Vec4::::new(3.0, 4.0, 2.5, 3.0); let res = lhs + rhs; // NOT SUPPORTED!! let lhs: u32 = 4; let rhs = Vec4::::new(3, 4, 2, 3); let res = lhs + rhs; ``` ## Hash Implementation Currently, Hash implementations are limited for the following types: - `f32` - `f64` - `i32` - `i64` - `u32` - `u64`