[][src]Crate vector2math

This crate provides traits for doing 2D vector geometry operations using standard types

Usage

Simple vector math is implemented for vectors with the following scalar types:

  • u8-u128
  • usize
  • i8-i128
  • isize
  • f32
  • f64
  • Any type that implements one or more of this crate's Scalar traits

Vectors can be of the following forms:

  • [T; 2]
  • (T, T)
  • Any type that implements one or more of this crate's Vector2 traits

Many 2D Vector operations are supported. Vectors do not necessarily need to be the same type to allow operation. They need only have the same Scalar type. The output type will be the same as the first argument.

use vector2math::*;

let a = [2, 6];
let b = (4, -1);
assert_eq!(2, a.x());
assert_eq!(-1, b.y());
assert_eq!([-2, -6], a.neg());
assert_eq!([6, 5], a.add(b));
assert_eq!([-2, 7], a.sub(b));
assert_eq!((12, -3), b.mul(3));
assert_eq!((8, -6), b.mul2(a));
assert_eq!([1, 3], a.div(2));
assert_eq!([0, -6], a.div2(b));

Floating-point vectors have additional operations:

use vector2math::*;

assert_eq!(5.0, [3.0, 4.0].mag());
assert_eq!(10.0, [-1.0, -2.0].dist([5.0, 6.0]));
let rotation_calculation = [1.0, 0.0].rotate_about([0.0; 2], std::f64::consts::PI / 4.0);
let rotation_solution = [2f64.powf(0.5) / 2.0; 2];
assert!(rotation_calculation.sub(rotation_solution).mag() < std::f64::EPSILON);

Many types can be used to define axis-aligned rectangles:

  • [[T; 2]; 2]
  • [(T, T); 2]
  • ((T, T), (T, T))
  • ([T; 2], [T; 2])
  • [T; 4]
  • (T, T, T, T)
  • Any type that implements this crate's Pair trait where the associated Item type implements Vector2.
use vector2math::*;

let rect = [1i32, 2, 4, 6];
assert_eq!([1, 2], rect.top_left());
assert_eq!([4, 6], rect.size());
assert_eq!([3, 5], rect.center());
assert_eq!(20, rect.perimeter());
assert_eq!(24, rect.area());

Both vector and rectangle types can be easily mapped to different types:

use vector2math::*;

let arrayf32: [f32; 2] = [1.0, 2.0];
let arrayf64: [f64; 2] = arrayf32.map();
let pairf64: (f64, f64) = arrayf64.map();
let arrayi16: [i16; 2] = pairf64.map_with(|f| f as i16);
assert_eq!(arrayf32, arrayi16.map::<[f32; 2]>());

let weird_rect = [(0.0, 1.0), (2.0, 5.0)];
let normal_rectf32: [f32; 4] = weird_rect.map();
let normal_rectf64: [f32; 4] = normal_rectf32.map();
let normal_rectu8: [u8; 4] = normal_rectf32.map_with(|f| f as u8);
assert_eq!([0, 1, 2, 5], normal_rectu8);

Implementing Vector2 and Rectangle traits for your own types is simple. Just make sure that your type is Copy

use vector2math::*;

#[derive(Clone, Copy)]
struct MyVector {
    x: f64,
    y: f64,
}

impl Vector2 for MyVector {
    type Scalar = f64;
    fn new(x: f64, y: f64) -> Self {
        MyVector { x, y }
    }
    fn x(self) -> f64 {
        self.x
    }
    fn y(self) -> f64 {
        self.y
    }
}

#[derive(Clone, Copy)]
struct MyRectangle {
    top_left: MyVector,
    size: MyVector,
}

impl Rectangle for MyRectangle {
    type Scalar = f64;
    type Vector = MyVector;
    fn new(top_left: MyVector, size: MyVector) -> Self {
        MyRectangle { top_left, size }
    }
    fn top_left(self) -> MyVector {
        self.top_left
    }
    fn size(self) -> MyVector {
        self.size
    }
}

let rect: MyRectangle = [1, 2, 3, 4].map();
assert_eq!(12.0, rect.area());
assert_eq!(6.0, rect.bottom());

Traits

Cos

Trait for getting the cosine of a number

FloatingScalar

Trait for floating-point scalar numbers

FloatingVector2

Trait for manipulating floating-point 2D vectors

NegScalar

Trait for scalars that can be negated

NegVector2

Trait for manipulating negatable 2D vectors

Pair

Trait for defining a pair of items of the same type.

Pow

Trait for raising numbers to a power

Rectangle

Trait for manipulating axis-aligned rectangles

Scalar

Trait for math with scalar numbers

Sin

Trait for getting the sine of a number

Vector2

Trait for manipulating 2D vectors

ZeroOneTwo

Trait for defining small-number constants