Expand description

vector

A simple and convenient 3D vector library without excessive use of external dependencies. If other vector crates are swiss-army knives, math_vector is a spoon; safe, intuitive, and convenient. As an added bonus, you won’t run into any excursions with the law using this library thanks to the awfully permissive Unlicense.

The only type in this crate is Vector, which is highly generic; shifting functionality depending upon the traits implemented by its internal components’ types.

Example

use math_vector::Vector;

fn main() {
    // Vectors have fields X and Y, these can be of any type
    let v1: Vector<i32> = Vector { x: 10, y: 5 , z: 3 };

    // Alternatively you can use new(..) to condense instantiation
    let v2: Vector<f64> = Vector::new(13.0, 11.5, 9.0);

    // There are two ways to cast between Vectors, depending on the source
    // and target types.
    //
    // If the target type has a implementation of From<SourceType>, then you
    // can either use source.into_vec() or Vector::from_vec(source).
    assert_eq!(Vector::new(10.0, 5.0, 3.0), v1.into_vec());
    assert_eq!(Vector::new(10.0, 5.0, 3.0), Vector::from_vec(v1));

    // If there is no From or Into implementation, then you're out of luck
    // unless you are using specific primitives, such as i32 and f64. In
    // this case you can use specialized functions, as shown below:
    assert_eq!(Vector::new(13, 11, 9), v2.as_i32s());

    // The full list of interoperable primitives is as follows:
    //   - i32, i64, isize
    //   - u32, u64, usize
    //   - f32, f64

    // As primitives generally implement From/Into for lossless casts,
    // an as_Ts() function is not available for those types, and
    // from(..)/into() should be favoured.
    //
    // Casts between signed and unsigned primitives will perform bounds
    // checking, so casting the vector (-10.0, 2.0, 11) to a Vector<u32> will
    // result in the vector (0, 2, 11).

    // For types with an Add and Mul implementation, the functions dot() and
    // length_squared() are available. For access to length(), normalize(),
    // or angle() however, you must be using either Vector<f32> or
    // Vector<f64>.
    let _v1_len_sq = v1.length_squared();
    let v2_len = v2.length();
    let v2_dir = v2.normalize();
    println!("{} {} {}", v2_dir.x, v2_dir.y, v2_dir.z);

    // Assuming the operator traits are implemented for the types involved,
    // you can add and subtract Vectors from one-another, as well as
    // multiply and divide them with scalar values.
    assert_eq!(v2.is_close(v2_dir * v2_len), true);
    assert_eq!(Vector::new(23.0, 16.5, 12.0),  v2 + v1.into_vec()) ;

    // If you feel the need to multiply or divide individual components of
    // vectors with the same type, you can use mul_components(...) or
    // div_components(...) provided that their types can be multiplied or
    // divided.

    // For any Vector<T>, there is an implementation of
    // From<(T, T)> and From<[T; 2]>
    let v4: Vector<f64> = Vector::new(1.5, 2.3, 3.1);
    assert_eq!(v4, (1.5, 2.3, 3.1).into());
    assert_eq!(v4, [1.5, 2.3, 3.1].into());

    // Additionally, there is an Into<(T, T, T)> implementation for any types
    // that the vector components have their own Into implementations for
    assert_eq!((1.5, 2.3, 3.1), v4.into());

    // If you want the normal of a vector you can just call normal()
    let v5 = Vector::new(-10.0, -2.3, 0.0);
    assert_eq!(Vector::new(2.3, -10.0, 0.0), v5.normal());

    // You can get a vector consisting of only the x, y or z axis
    // component of a vector by calling abscissa() or ordinate() or applicate()
    // respectively
    let v6 = Vector::new(12.3, 83.2, -42.6);
    assert_eq!(Vector::new(12.3, 0.0, 0.0), v6.abscissa());
    assert_eq!(Vector::new(0.0, 83.2, 0.0), v6.ordinate());
    assert_eq!(Vector::new(0.0, 0.0, -42.6), v6.applicate());
}

Structs

A 3D vector, containing an x, y and a z component. While many types can be used for a Vector’s components, the traits they implement determine what functions are available.