From 83799a02a9d31cb2c3ded7de870c20a9f8c994f5 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Fri, 16 Jul 2021 16:38:40 -0700 Subject: [PATCH] matrices: implement Matrix4x4::shearing --- rtchallenge/src/matrices.rs | 47 ++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/rtchallenge/src/matrices.rs b/rtchallenge/src/matrices.rs index 5843ca9..d68fb80 100644 --- a/rtchallenge/src/matrices.rs +++ b/rtchallenge/src/matrices.rs @@ -1,9 +1,6 @@ use std::fmt; use std::ops::{Index, IndexMut, Mul}; -// Implement a PartialEq that does approx_eq internally. -//use float_cmp::{ApproxEq, F32Margin}; - use crate::tuples::Tuple; /// Value considered close enough for PartialEq implementations. @@ -402,6 +399,50 @@ impl Matrix4x4 { ], } } + /// Create a transform matrix that will shear (skew) points. + /// # Examples + /// + /// ``` + /// use rtchallenge::{matrices::Matrix4x4, tuples::Tuple}; + /// + /// // A shearing transform moves x in proportion to y. + /// let transform = Matrix4x4::shearing(1.,0.,0.,0.,0.,0.); + /// let p = Tuple::point(2.,3.,4.); + /// assert_eq!(transform * p, Tuple::point(5.,3.,4.)); + /// + /// // A shearing transform moves x in proportion to z. + /// let transform = Matrix4x4::shearing(0.,1.,0.,0.,0.,0.); + /// let p = Tuple::point(2.,3.,4.); + /// assert_eq!(transform * p, Tuple::point(6.,3.,4.)); + /// + /// // A shearing transform moves y in proportion to x. + /// let transform = Matrix4x4::shearing(0.,0.,1.,0.,0.,0.); + /// let p = Tuple::point(2.,3.,4.); + /// assert_eq!(transform * p, Tuple::point(2.,5.,4.)); + /// + /// // A shearing transform moves y in proportion to z. + /// let transform = Matrix4x4::shearing(0.,0.,0.,1.,0.,0.); + /// let p = Tuple::point(2.,3.,4.); + /// assert_eq!(transform * p, Tuple::point(2.,7.,4.)); + /// + /// // A shearing transform moves z in proportion to x. + /// let transform = Matrix4x4::shearing(0.,0.,0.,0.,1.,0.); + /// let p = Tuple::point(2.,3.,4.); + /// assert_eq!(transform * p, Tuple::point(2.,3.,6.)); + /// + /// // A shearing transform moves z in proportion to y. + /// let transform = Matrix4x4::shearing(0.,0.,0.,0.,0.,1.); + /// let p = Tuple::point(2.,3.,4.); + /// assert_eq!(transform * p, Tuple::point(2.,3.,7.)); + + pub fn shearing(xy: f32, xz: f32, yx: f32, yz: f32, zx: f32, zy: f32) -> Matrix4x4 { + Matrix4x4::new( + [1., xy, xz, 0.], + [yx, 1., yz, 0.], + [zx, zy, 1., 0.], + [0., 0., 0., 1.], + ) + } /// Returns a new matrix that is the inverse of self. If self is A, inverse returns A-1, where /// AA-1 = I.