Hi I am trying to get into Rust by implementing a small library for vector calculations.
I am mainly asking to point out whether I chose a valid approach. I also am interested in comments on the overall details I might have missed or got the wrong way.
So for my Vec3
implementation I basically declared a custom type which is an array of length 3. Afterwards I am simply implementing Traits
for this type. For now I only implemented it for f32
.
pub type Vec3<T = f32> = [T; 3];
pub trait Vector3<T> {
/// Creates a new Vec3 with its values initialized to `[0.0, 0.0, 0.0]`.
fn new() -> Self;
/// Creates a new `Vec3` based on the given `x`, `y` and `z` values.
fn from_values(x: f32, y: f32, z: f32) -> Vec3<T>;
/// Calculates the scalar dot product of two `Vec3`'s.
fn dot(a: Vec3<T>, b: Vec3<T>) -> f32;
/// Performs multiplication between two `Vec3`.
fn multiply(self, a: Vec3) -> Vec3;
/// Calculates the sum of two `Vec3` components.Vec3
fn add(self, a: Vec3) -> Vec3;
/// Scales a `Vec3` by a scalar value.
fn scale(self, x: f32) -> Vec3;
}
impl Vector3<f32> for Vec3<f32> {
/// Creates a new Vec3 with its values initialized to `[0.0, 0.0, 0.0]`.
///
/// ```
/// use glMatrix_rs::vec3::*;
///
/// let result = Vec3::new();
/// assert_eq!([0.0, 0.0, 0.0], result);
/// ```
fn new() -> Vec3<f32> {
[0.0, 0.0, 0.0]
}
/// Creates a new `Vec3` based on the given `x`, `y` and `z` values.
///
/// ### Arguments
///
/// * `x` - The first vector component.
/// * `y` - The second vector component.
/// * `z` - The third vector component.
///
/// ```
/// use glMatrix_rs::vec3::*;
///
/// let result = Vec3::from_values(0.0, 1.0, 2.0);
/// assert_eq!([0.0, 1.0, 2.0], result);
/// ```
fn from_values(x: f32, y: f32, z: f32) -> Vec3 {
[x, y, z]
}
/// Calculates the scalar dot product of two `Vec3`'s.
///
/// ### Arguments
///
/// * `a` - The first vector for `dot` calculation.
/// * `b` - The second vector for `dot` calculation.
///
/// ```
/// use glMatrix_rs::vec3::*;
/// let a = Vec3::from_values(2.0, 2.0, 2.0);
/// let b = Vec3::from_values(2.0, 2.0, 2.0);
/// assert_eq!(12.0, Vec3::dot(a, b));
/// ```
fn dot(a: Vec3, b: Vec3) -> f32 {
a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
}
/// Performs multiplication between two `Vec3`.
///
/// ### Arguments
///
/// * `a` - Vector by which `self` will be multiplied.
///
/// ```
/// use glMatrix_rs::vec3::*;
/// let mut out = Vec3::new();
/// let a = Vec3::from_values(1.0, 2.0, 3.0);
/// let b = Vec3::from_values(2.0, 2.0, 2.0);
/// assert_eq!([2.0, 4.0, 6.0], a.multiply(b));
/// ```
fn multiply(self, a: Vec3) -> Vec3 {
[self[0] * a[0], self[1] * a[1], self[2] * a[2]]
}
/// Calculates the sum of two `Vec3` components.Vec3
///
/// ### Arguments
///
/// * `a` - Vector which will be added to `self`.
///
/// ```
/// use glMatrix_rs::vec3::*;
/// let x = Vec3::from_values(1.0, 2.0, 3.0);
/// let a = Vec3::from_values(3.0, 2.0, 1.0);
/// assert_eq!([4.0, 4.0, 4.0], x.add(a));
/// ```
fn add(self, a: Vec3) -> Vec3 {
[self[0] + a[0], self[1] + a[1], self[2] + a[2]]
}
/// Scales a `Vec3` by a scalar value.
///
/// ### Arguments
///
/// * `x` - Scalar value by which the vector will be scaled.
///
/// ```
/// use glMatrix_rs::vec3::*;
/// let a = Vec3::from_values(1.0, 2.0, 3.0);
/// assert_eq!([2.0, 4.0, 6.0], a.scale(2.0));
/// ```
fn scale(self, x: f32) -> Vec3 {
[self[0] * x, self[1] * x, self[2] * x]
}
}
You can clone, build
and test
it any time from my GitHub repository.