matrices: implement Matrix4x4:rotation_[xyz]
This commit is contained in:
parent
f792d1a626
commit
245b02b443
@ -283,6 +283,117 @@ impl Matrix4x4 {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a 4x4 matrix representing a rotation around the x-axis.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::f32::consts::PI;
|
||||||
|
///
|
||||||
|
/// use float_cmp::approx_eq;
|
||||||
|
///
|
||||||
|
/// use rtchallenge::{matrices::Matrix4x4, tuples::Tuple};
|
||||||
|
///
|
||||||
|
/// // A scaling matrix applied to a point.
|
||||||
|
/// let p = Tuple::point(0., 1., 0.);
|
||||||
|
/// let half_quarter = Matrix4x4::rotation_x(PI / 4.);
|
||||||
|
/// let full_quarter = Matrix4x4::rotation_x(PI / 2.);
|
||||||
|
///
|
||||||
|
/// assert_eq!(
|
||||||
|
/// half_quarter * p,
|
||||||
|
/// Tuple::point(0., 2_f32.sqrt() / 2., 2_f32.sqrt() / 2.)
|
||||||
|
/// );
|
||||||
|
/// assert!(approx_eq!(
|
||||||
|
/// Tuple,
|
||||||
|
/// full_quarter * p,
|
||||||
|
/// Tuple::point(0., 0., 1.),
|
||||||
|
/// epsilon = 0.0001
|
||||||
|
/// ));
|
||||||
|
/// ```
|
||||||
|
pub fn rotation_x(radians: f32) -> Matrix4x4 {
|
||||||
|
let r = radians;
|
||||||
|
Matrix4x4::new(
|
||||||
|
[1., 0., 0., 0.],
|
||||||
|
[0., r.cos(), -r.sin(), 0.],
|
||||||
|
[0., r.sin(), r.cos(), 0.],
|
||||||
|
[0., 0., 0., 1.],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a 4x4 matrix representing a rotation around the y-axis.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::f32::consts::PI;
|
||||||
|
///
|
||||||
|
/// use float_cmp::approx_eq;
|
||||||
|
///
|
||||||
|
/// use rtchallenge::{matrices::Matrix4x4, tuples::Tuple};
|
||||||
|
///
|
||||||
|
/// // A scaling matrix applied to a point.
|
||||||
|
/// let p = Tuple::point(0., 0., 1.);
|
||||||
|
/// let half_quarter = Matrix4x4::rotation_y(PI / 4.);
|
||||||
|
/// let full_quarter = Matrix4x4::rotation_y(PI / 2.);
|
||||||
|
///
|
||||||
|
/// assert_eq!(
|
||||||
|
/// half_quarter * p,
|
||||||
|
/// Tuple::point(2_f32.sqrt() / 2., 0., 2_f32.sqrt() / 2.)
|
||||||
|
/// );
|
||||||
|
/// assert!(approx_eq!(
|
||||||
|
/// Tuple,
|
||||||
|
/// full_quarter * p,
|
||||||
|
/// Tuple::point(1., 0., 0.,),
|
||||||
|
/// epsilon = 0.0001
|
||||||
|
/// ));
|
||||||
|
/// ```
|
||||||
|
pub fn rotation_y(radians: f32) -> Matrix4x4 {
|
||||||
|
let r = radians;
|
||||||
|
Matrix4x4::new(
|
||||||
|
[r.cos(), 0., r.sin(), 0.],
|
||||||
|
[0., 1., 0., 0.],
|
||||||
|
[-r.sin(), 0., r.cos(), 0.],
|
||||||
|
[0., 0., 0., 1.],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a 4x4 matrix representing a rotation around the z-axis.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::f32::consts::PI;
|
||||||
|
///
|
||||||
|
/// use float_cmp::approx_eq;
|
||||||
|
///
|
||||||
|
/// use rtchallenge::{matrices::Matrix4x4, tuples::Tuple};
|
||||||
|
///
|
||||||
|
/// // A scaling matrix applied to a point.
|
||||||
|
/// let p = Tuple::point(0., 1., 0.);
|
||||||
|
/// let half_quarter = Matrix4x4::rotation_z(PI / 4.);
|
||||||
|
/// let full_quarter = Matrix4x4::rotation_z(PI / 2.);
|
||||||
|
///
|
||||||
|
/// assert_eq!(
|
||||||
|
/// half_quarter * p,
|
||||||
|
/// Tuple::point(-2_f32.sqrt() / 2., 2_f32.sqrt() / 2., 0.)
|
||||||
|
/// );
|
||||||
|
/// assert!(approx_eq!(
|
||||||
|
/// Tuple,
|
||||||
|
/// full_quarter * p,
|
||||||
|
/// Tuple::point(-1., 0., 0.,),
|
||||||
|
/// epsilon = 0.0001
|
||||||
|
/// ));
|
||||||
|
/// ```
|
||||||
|
pub fn rotation_z(radians: f32) -> Matrix4x4 {
|
||||||
|
let r = radians;
|
||||||
|
Matrix4x4::new(
|
||||||
|
[r.cos(), -r.sin(), 0., 0.],
|
||||||
|
[r.sin(), r.cos(), 0., 0.],
|
||||||
|
[0., 0., 1., 0.],
|
||||||
|
[0., 0., 0., 1.],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Transpose self, returning a new matrix that has been reflected across the diagonal.
|
/// Transpose self, returning a new matrix that has been reflected across the diagonal.
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
use std::ops::{Add, Div, Mul, Neg, Sub};
|
use std::ops::{Add, Div, Mul, Neg, Sub};
|
||||||
|
|
||||||
|
use float_cmp::{ApproxEq, F32Margin};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
pub struct Tuple {
|
pub struct Tuple {
|
||||||
pub x: f32,
|
pub x: f32,
|
||||||
@ -43,6 +45,40 @@ impl Tuple {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ApproxEq for Tuple {
|
||||||
|
type Margin = F32Margin;
|
||||||
|
|
||||||
|
/// Implement float_cmp::ApproxEq for Tuple
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// use float_cmp::approx_eq;
|
||||||
|
/// use rtchallenge::tuples::Tuple;
|
||||||
|
///
|
||||||
|
/// assert!(approx_eq!(
|
||||||
|
/// Tuple,
|
||||||
|
/// Tuple::point(1., 1., 0.),
|
||||||
|
/// Tuple::point(1., 1., 0.),
|
||||||
|
/// ulps = 1
|
||||||
|
/// ));
|
||||||
|
///
|
||||||
|
/// assert!(approx_eq!(
|
||||||
|
/// Tuple,
|
||||||
|
/// Tuple::vector(1., 1., 0.),
|
||||||
|
/// Tuple::vector(1., 1., 0.),
|
||||||
|
/// ulps = 1
|
||||||
|
/// ));
|
||||||
|
/// ```
|
||||||
|
fn approx_eq<T: Into<Self::Margin>>(self, t2: Self, margin: T) -> bool {
|
||||||
|
let t = self;
|
||||||
|
let margin = margin.into();
|
||||||
|
t.x.approx_eq(t2.x, margin)
|
||||||
|
&& t.y.approx_eq(t2.y, margin)
|
||||||
|
&& t.z.approx_eq(t2.z, margin)
|
||||||
|
&& t.w.approx_eq(t2.w, margin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Add for Tuple {
|
impl Add for Tuple {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn add(self, other: Self) -> Self {
|
fn add(self, other: Self) -> Self {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user