diff --git a/crates/fj-math/src/transform.rs b/crates/fj-math/src/transform.rs index 164044f12..2827adf6f 100644 --- a/crates/fj-math/src/transform.rs +++ b/crates/fj-math/src/transform.rs @@ -2,7 +2,7 @@ use std::ops; use nalgebra::Perspective3; -use crate::Scalar; +use crate::{Line, Scalar}; use super::{Aabb, Point, Segment, Triangle, Vector}; @@ -55,6 +55,14 @@ impl Transform { Vector::from(self.0.transform_vector(&vector.to_na())) } + /// Transform the given line + pub fn transform_line(&self, line: &Line<3>) -> Line<3> { + Line { + origin: self.transform_point(&line.origin), + direction: self.transform_vector(&line.direction), + } + } + /// Transform the given segment pub fn transform_segment(&self, segment: &Segment<3>) -> Segment<3> { let [a, b] = &segment.points(); @@ -124,3 +132,33 @@ impl ops::Mul for Transform { Self(self.0.mul(rhs.0)) } } + +#[cfg(test)] +mod tests { + use approx::assert_abs_diff_eq; + + use crate::{Line, Point, Scalar, Vector}; + + use super::Transform; + + #[test] + fn transform() { + let line = Line { + origin: Point::from([1., 0., 0.]), + direction: Vector::from([0., 1., 0.]), + }; + + let transform = Transform::translation([1., 2., 3.]) + * Transform::rotation(Vector::unit_z() * (Scalar::PI / 2.)); + let line = transform.transform_line(&line); + + assert_abs_diff_eq!( + line, + Line { + origin: Point::from([1., 3., 3.]), + direction: Vector::from([-1., 0., 0.]), + }, + epsilon = 1e-8, + ); + } +}