90 lines
2.4 KiB
Rust
90 lines
2.4 KiB
Rust
use crate::matrix::Matrix;
|
|
use crate::structs::Tuple;
|
|
|
|
|
|
impl Matrix {
|
|
pub fn translation(x: f32, y: f32, z: f32) -> Self {
|
|
Matrix::from_array([
|
|
[1.0, 0.0, 0.0, x ],
|
|
[0.0, 1.0, 0.0, y ],
|
|
[0.0, 0.0, 1.0, z ],
|
|
[0.0, 0.0, 0.0, 1.0],
|
|
])
|
|
}
|
|
|
|
pub fn scaling(x: f32, y: f32, z: f32) -> Self {
|
|
Matrix::from_array([
|
|
[ 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],
|
|
])
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn multiply_by_a_translations_matrix() {
|
|
let transform = Matrix::translation(5.0, -3.0, 2.0);
|
|
let p = Tuple::point(-3.0, 4.0, 5.0);
|
|
|
|
|
|
let expected_point = Tuple::point(2.0, 1.0, 7.0);
|
|
|
|
let translated_point = &p * &transform;
|
|
|
|
assert_eq!(expected_point, translated_point);
|
|
}
|
|
|
|
#[test]
|
|
fn multiply_by_the_inverse_of_a_translation_matrix() {
|
|
let transform = Matrix::translation(5.0, -3.0, 2.0);
|
|
let inv = transform.inverse();
|
|
let p = Tuple::point(-3.0, 4.0, 5.0);
|
|
|
|
let expected_point = Tuple::point(-8.0, 7.0, 3.0);
|
|
assert_eq!(&inv * &p, expected_point);
|
|
}
|
|
|
|
#[test]
|
|
fn translation_does_not_affect_vectors() {
|
|
let transform = Matrix::translation(5.0, -3.0, 2.0);
|
|
let v = Tuple::vector(-3.0, 4.0, 5.0);
|
|
|
|
assert_eq!(&transform * &v, v);
|
|
}
|
|
|
|
#[test]
|
|
fn scaling_matrix_applied_to_point() {
|
|
let transform = Matrix::scaling(2.0, 3.0, 4.0);
|
|
let p = Tuple::point(-4.0, 6.0, 8.0);
|
|
let expected = Tuple::point(-8.0, 18.0, 32.0);
|
|
assert_eq!(&transform * &p, expected);
|
|
}
|
|
|
|
#[test]
|
|
fn scaling_matrix_apled_to_vector() {
|
|
let transform = Matrix::scaling(2.0, 3.0, 4.0);
|
|
let v = Tuple::vector(-4.0, 6.0, 8.0);
|
|
assert_eq!(&transform * &v, Tuple::vector(-8.0, 18.0, 32.0));
|
|
}
|
|
|
|
#[test]
|
|
fn multiplying_inverse_of_scaling_matrix() {
|
|
let transform = Matrix::scaling(2.0, 3.0, 4.0);
|
|
let inv = transform.inverse();
|
|
let v = Tuple::vector(-4.0, 6.0, 8.0);
|
|
assert_eq!(&inv * &v, Tuple::vector(-2.0, 2.0, 2.0));
|
|
}
|
|
|
|
#[test]
|
|
fn reflection_is_scaling_by_a_negative_value() {
|
|
let transform = Matrix::scaling(-1.0, 1.0, 1.0);
|
|
let p = Tuple::point(2.0, 3.0, 4.0);
|
|
assert_eq!(&transform * &p, Tuple::point(-2.0, 3.0, 4.0));
|
|
}
|
|
}
|