[][src]Crate vector2math

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

Scalars

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

  • u8-u128
  • usize
  • i8-i128
  • isize
  • f32
  • f64
  • Any type that implements Scalar

f32 and f64 implement FloatingScalar, which gives some additional operations only applicable to floating-point numbers.

Each scalar type has an associated module that has type definitions for standard geometric types using that scalar.

For example, instead of writing

let square = <[f32; 4]>::square([0.0; 2], 1.0);

You can instead write

let square = f32::Rect::square([0.0; 2], 1.0);

Vectors

Vectors can be of the following forms:

  • [T; 2]
  • (T, T)
  • Any type that implements Vector2

Many 2D Vector operations are supported.

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));
assert_eq!(2, a.dot(b));

Vectors that implement FloatingVector2 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(f64::TAU / 8.0, [0.0; 2]);
let rotation_solution = [2f64.powf(0.5) / 2.0; 2];
assert!(rotation_calculation.sub(rotation_solution).mag() < std::f64::EPSILON);

Rectangles

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 Pair 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());
assert!(rect.contains([3, 5]));
assert_eq!([1, 2, 2, 6], rect.move_right_bound(-2));
let corners = rect.corners();
assert_eq!(corners[0], [1, 2]);
assert_eq!(corners[1], [5, 2]);
assert_eq!(corners[2], [5, 8]);
assert_eq!(corners[3], [1, 8]);

Circles

A few types can be used to define circles:

  • ([T; 2], T)
  • ((T, T), T)
  • Any pair of types where the first implements FloatingVector2 and the second is the vector's Scalar type.
use vector2math::*;
use std::f64;

let circle = ([2.0, 3.0], 4.0);
assert!((circle.circumference() - 25.132_741_228_718_345).abs() < f64::EPSILON);
assert!((circle.area() - 50.265_482_457_436_69).abs() < f64::EPSILON);
assert!(circle.contains([0.0, 1.0]));
assert!(!circle.contains([5.0, 6.0]));

Mapping

Vector, rectangle, and circle 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());

let weird_rect = [(0.0, 1.0), (2.0, 5.0)];
let normal_rectf32: [f32; 4] = weird_rect.map();
let normal_rectf64: [f64; 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);

let pair_circlef32 = ((0.0, 1.0), 2.0);
let array_circlef32 = ([0.0, 1.0], 2.0);
assert_eq!(((0.0, 1.0), 2.0), array_circlef32.map::<((f64, f64), f64)>());

Transforms

The Transform trait is used to define 2D vector transforms. This crate implements Transform for all types that implement Pair where the Pair's Item implments Trio where the Trio's Item implements FloatingScalar. This type range includes everything from [[f32; 3]; 2] to (f64, f64, f64, f64, f64, f64). Transforms can be chained and applied to vectors.

use vector2math::*;

let dis = [1.0; 2];
let rot = f32::TAU / 4.0;
let sc = [2.0; 2];

let transform = f32::Trans::new().translate(dis).rotate(rot).scale(sc);

let v = [3.0, 5.0];
let v1 = v.transform(transform);
let v2 = v.add(dis).rotate(rot).mul2(sc);

assert_eq!(v1, v2);

Implementing traits

Implementing these 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());

Modules

f32

Standard geometric types for a scalar type

f64

Standard geometric types for a scalar type

i8

Standard geometric types for a scalar type

i16

Standard geometric types for a scalar type

i32

Standard geometric types for a scalar type

i64

Standard geometric types for a scalar type

i128

Standard geometric types for a scalar type

isize

Standard geometric types for a scalar type

simdsimd

Simd standard types

u8

Standard geometric types for a scalar type

u16

Standard geometric types for a scalar type

u32

Standard geometric types for a scalar type

u64

Standard geometric types for a scalar type

u128

Standard geometric types for a scalar type

usize

Standard geometric types for a scalar type

Traits

Abs

Trait for retrieving an absolute value of a number

Circle

Trait for manipulating circles

FloatingScalar

Trait for floating-point scalar numbers

FloatingVector2

Trait for manipulating floating-point 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

Transform

Trait for defining vector transformations

Trig

Trait for trigonometric operations

Trio

Trait for defining a group of 3 items of the same type.

Vector2

Trait for manipulating 2D vectors

ZeroOneTwo

Trait for defining small-number constants

Type Definitions

Chain2

An iterator over two items

Chain3

An iterator over three items