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.