Module truster::matrix [−][src]
Expand description
A 2D transformation matrix for points and vectors. For now, only floating point matrices are supported. Generics may come in the future.
Examples
Initialize a new Matrix with new:
let m = Matrix::new(&[ 1.0, 2.0, 3.0, 4.0, 5.5, 6.5, 7.5, 8.5, 9.0, 10.0, 11.0, 12.0, 13.5, 14.5, 15.5, 16.5, ]); let output = format!("{}", m); assert_eq!(output, "/1 2 3 4\\ |5.5 6.5 7.5 8.5| |9 10 11 12| \\13.5 14.5 15.5 16.5/")
Individual values can be accessed and mutated by index:
let m = Matrix::new(&[ 1.0, 2.0, 3.0, 4.0, 5.5, 6.5, 7.5, 8.5, 9.0, 10.0, 11.0, 12.0, 13.5, 14.5, 15.5, 16.5, ]); assert_eq!(m[[0, 0]], 1.0); assert_eq!(m[[0, 3]], 4.0); assert_eq!(m[[1, 0]], 5.5); assert_eq!(m[[1, 2]], 7.5); assert_eq!(m[[2, 2]], 11.0); assert_eq!(m[[3, 0]], 13.5); assert_eq!(m[[3, 2]], 15.5);
Matrices can be multiplied together:
let m1 = Matrix::new(&[ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, ]); let m2 = Matrix::new(&[ -2.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0, -1.0, 4.0, 3.0, 6.0, 5.0, 1.0, 2.0, 7.0, 8.0, ]); assert_eq!(m1 * &m2, Matrix::new(&[ 20.0, 22.0, 50.0, 48.0, 44.0, 54.0, 114.0, 108.0, 40.0, 58.0, 110.0, 102.0, 16.0, 26.0, 46.0, 42.0, ]));
You can also multiply matrices with tuples to get their transform:
use truster::tuple::Tuple; let m = Matrix::new(&[ 1.0, 2.0, 3.0, 4.0, 2.0, 4.0, 4.0, 2.0, 8.0, 6.0, 4.0, 1.0, 0.0, 0.0, 0.0, 1.0, ]); let p = Tuple::point(1.0, 2.0, 3.0); assert_eq!(&m * p, Tuple::point(18.0, 24.0, 33.0));
Take the transpose of a matrix with Matrix::transpose:
let m = Matrix::new(&[ 1.0, 2.0, 3.0, 4.0, 12.0, 42.0, 69.0, 37.0, 21.0, 24.0, 96.0, 73.0, -1.0, -2.0, -3.0, -4.0, ]); assert_eq!(m.transpose(), Matrix::new(&[ 1.0, 12.0, 21.0, -1.0, 2.0, 42.0, 24.0, -2.0, 3.0, 69.0, 96.0, -3.0, 4.0, 37.0, 73.0, -4.0, ]));
Take the inverse of a matrix with Matrix::inverse:
let m1 = Matrix::new(&[ 3.0, -9.0, 7.0, 3.0, 3.0, -8.0, 2.0, -9.0, -4.0, 4.0, 4.0, 1.0, -6.0, 5.0, -1.0, 1.0, ]); let m2 = Matrix::new(&[ 8.0, 2.0, 2.0, 2.0, 3.0, -1.0, 7.0, 0.0, 7.0, 0.0, 5.0, 4.0, 6.0, -2.0, 0.0, 5.0, ]); let m3 = m1.clone() * &m2; // m3 * &m2.inverse() == m1 // approximately (floating points)
Transformations
This library is meant for using matrices as transformations, so all common transformations can be used directly.
The supported transformations are:
- Translation
use truster::tuple::Tuple; let t = Matrix::translation(5.0, -3.0, 2.0); let p = Tuple::point(-3.0, 4.0, 5.0); assert_eq!(&t * p, Tuple::point(2.0, 1.0, 7.0)); // vectors stay unchanged. let t = Matrix::translation(5.0, -3.0, 2.0); let v = Tuple::vector(-3.0, 4.0, 5.0); assert_eq!(&t * v, v);
- Scaling
use truster::tuple::Tuple; let t = Matrix::scaling(2.0, 3.0, 4.0); let p = Tuple::point(-4.0, 6.0, 8.0); assert_eq!(&t * p, Tuple::point(-8.0, 18.0, 32.0));
- Rotation around X axis.
use truster::tuple::Tuple; use std::f64::consts::PI; let t = Matrix::rotation_x(PI / 2.0); let p = Tuple::point(0.0, 1.0, 0.0); // &t * p == Tuple::point(0.0, 0.0, 1.0) // approximately
- Rotation around Y axis.
use truster::tuple::Tuple; use std::f64::consts::PI; let t = Matrix::rotation_y(PI / 2.0); let p = Tuple::point(0.0, 0.0, 1.0); // &t * p == Tuple::point(1.0, 0.0, 0.0) // approximately
- Rotation around Z axis.
use truster::tuple::Tuple; use std::f64::consts::PI; let t = Matrix::rotation_z(PI / 2.0); let p = Tuple::point(0.0, 1.0, 0.0); // &t * p == Tuple::point(-1.0, 0.0, 0.0) // approximately
- Shearing
use truster::tuple::Tuple; let t = Matrix::shearing(0.0, 1.0, 0.0, 0.0, 0.0, 0.0); let p = Tuple::point(2.0, 3.0, 4.0); assert_eq!(&t * p, Tuple::point(6.0, 3.0, 4.0));
Transformations can be chained together by multiplying:
use truster::tuple::Tuple; use std::f64::consts::PI; let p = Tuple::point(1.0, 0.0, 1.0); let a = Matrix::rotation_x(PI / 2.0); let b = Matrix::scaling(5.0, 5.0, 5.0); let c = Matrix::translation(10.0, 5.0, 7.0); let p2 = &a*p; let p3 = &b*p2; let p4 = &c*p3; let t = c * &b * &a; assert_eq!(&t*p, p4);