transform-matrix 0.1.1

Easy transformation matrices
Documentation
pub type Matrix = [[f32; 4]; 4];

pub fn identity() -> Matrix {
    [
        [1.0, 0.0, 0.0, 0.0],
        [0.0, 1.0, 0.0, 0.0],
        [0.0, 0.0, 1.0, 0.0],
        [0.0, 0.0, 0.0, 1.0],
    ]
}

pub fn translate(x: f32, y: f32, z: f32) -> Matrix {
    [
        [1.0, 0.0, 0.0, 0.0],
        [0.0, 1.0, 0.0, 0.0],
        [0.0, 0.0, 1.0, 0.0],
        [x, y, z, 1.0],
    ]
}

pub fn scale(x: f32, y: f32, z: f32) -> Matrix {
    [
        [x, 0.0, 0.0, 0.0],
        [0.0, y, 0.0, 0.0],
        [0.0, 0.0, z, 0.0],
        [0.0, 0.0, 0.0, 1.0],
    ]
}

pub fn rotate_x(angle: f32) -> Matrix {
    let radians = angle.to_radians();
    let sin = radians.sin();
    let cos = radians.cos();
    [
        [1.0, 0.0, 0.0, 0.0],
        [0.0, cos, sin, 0.0],
        [0.0, -sin, cos, 0.0],
        [0.0, 0.0, 0.0, 1.0],
    ]
}

pub fn rotate_y(angle: f32) -> Matrix {
    let radians = angle.to_radians();
    let sin = radians.sin();
    let cos = radians.cos();
    [
        [cos, 0.0, -sin, 0.0],
        [0.0, 1.0, 0.0, 0.0],
        [sin, 0.0, cos, 0.0],
        [0.0, 0.0, 0.0, 1.0],
    ]
}

pub fn rotate_z(angle: f32) -> Matrix {
    let radians = angle.to_radians();
    let sin = radians.sin();
    let cos = radians.cos();
    [
        [cos, -sin, 0.0, 0.0],
        [sin, cos, 0.0, 0.0],
        [0.0, 0.0, 1.0, 0.0],
        [0.0, 0.0, 0.0, 1.0],
    ]
}

pub fn orthographic(width: f32, height: f32, depth: f32) -> Matrix {
    let x = 2.0 / width;
    let y = -2.0 / height;
    let z = -2.0 / depth;
    [
        [x, 0.0, 0.0, 0.0],
        [0.0, y, 0.0, 0.0],
        [0.0, 0.0, z, 0.0],
        [-1.0, 1.0, -1.0, 1.0],
    ]
}

#[allow(clippy::needless_range_loop)]
pub fn multiply(m1: Matrix, m2: Matrix) -> Matrix {
    let mut result = [[0.0; 4]; 4];
    for i in 0..4 {
        for j in 0..4 {
            for k in 0..4 {
                result[i][j] += m1[i][k] * m2[k][j];
            }
        }
    }
    result
}

#[test]
fn is_identity() {
    assert_eq!(
        identity(),
        [
            [1.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, 0.0],
            [0.0, 0.0, 0.0, 1.0]
        ]
    );
}

#[test]
fn is_translate() {
    assert_eq!(
        translate(15.5, 7.8, 9.0),
        [
            [1.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, 0.0],
            [15.5, 7.8, 9.0, 1.0]
        ]
    );
}

#[test]
fn is_scale() {
    assert_eq!(
        scale(4.0, 7.1, 8.2),
        [
            [4.0, 0.0, 0.0, 0.0],
            [0.0, 7.1, 0.0, 0.0],
            [0.0, 0.0, 8.2, 0.0],
            [0.0, 0.0, 0.0, 1.0]
        ]
    );
}

#[test]
fn is_rotate_x() {
    let zero = 0.000_000_043_711_39;

    assert_eq!(
        rotate_x(90.0),
        [
            [1.0, 0.0, 0.0, 0.0],
            [0.0, -zero, 1.0, 0.0],
            [0.0, -1.0, -zero, 0.0],
            [0.0, 0.0, 0.0, 1.0]
        ]
    );
}

#[test]
fn is_rotate_y() {
    let zero = 0.000_000_043_711_39;

    assert_eq!(
        rotate_y(90.0),
        [
            [-zero, 0.0, -1.0, 0.0],
            [0.0, 1.0, 0.0, 0.0],
            [1.0, 0.0, -zero, 0.0],
            [0.0, 0.0, 0.0, 1.0]
        ]
    );
}

#[test]
fn is_rotate_z() {
    let zero = 0.000_000_043_711_39;

    assert_eq!(
        rotate_z(90.0),
        [
            [-zero, -1.0, 0.0, 0.0],
            [1.0, -zero, 0.0, 0.0],
            [0.0, 0.0, 1.0, 0.0],
            [0.0, 0.0, 0.0, 1.0]
        ]
    );
}

#[test]
fn is_orthographic() {
    assert_eq!(
        orthographic(10.0, 5.0, 1.0),
        [
            [0.2, 0.0, 0.0, 0.0],
            [0.0, -0.4, 0.0, 0.0],
            [0.0, 0.0, -2.0, 0.0],
            [-1.0, 1.0, -1.0, 1.0]
        ]
    );
}

#[test]
fn is_multiplied() {
    let a = translate(3.0, 4.0, 5.0);
    let b = scale(6.0, 7.0, 8.0);
    assert_eq!(
        multiply(a, b),
        [
            [6.0, 0.0, 0.0, 0.0],
            [0.0, 7.0, 0.0, 0.0],
            [0.0, 0.0, 8.0, 0.0],
            [18.0, 28.0, 40.0, 1.0]
        ]
    );
}