Skip to content

Commit

Permalink
Merge pull request #1160 from hannobraun/plane
Browse files Browse the repository at this point in the history
Expand API of `Plane`
  • Loading branch information
hannobraun authored Sep 30, 2022
2 parents 37c3382 + d3f6b6b commit 2b32926
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 39 deletions.
54 changes: 25 additions & 29 deletions crates/fj-kernel/src/algorithms/intersect/ray_face.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Intersection between a ray and a face, in 3D
use fj_math::{Point, Scalar};
use fj_math::{Plane, Point, Scalar};

use crate::{
algorithms::intersect::face_point::FacePointIntersection,
Expand All @@ -16,25 +16,21 @@ impl Intersect for (&HorizontalRayToTheRight<3>, &Face) {
fn intersect(self) -> Option<Self::Intersection> {
let (ray, face) = self;

let (plane_origin, plane_direction_1, plane_direction_2) =
match face.surface().u() {
GlobalPath::Circle(_) => todo!(
"Casting a ray against a swept circle is not supported yet"
),
GlobalPath::Line(line) => {
(line.origin(), line.direction(), face.surface().v())
}
};

let plane_and_ray_are_parallel = {
let plane_normal = plane_direction_1.cross(&plane_direction_2);
plane_normal.dot(&ray.direction()) == Scalar::ZERO
let plane = match face.surface().u() {
GlobalPath::Circle(_) => todo!(
"Casting a ray against a swept circle is not supported yet"
),
GlobalPath::Line(line) => Plane::from_parametric(
line.origin(),
line.direction(),
face.surface().v(),
),
};

if plane_and_ray_are_parallel {
let a = plane_origin;
let b = plane_origin + plane_direction_1;
let c = plane_origin + plane_direction_2;
if plane.is_parallel_to_vector(&ray.direction()) {
let a = plane.origin();
let b = plane.origin() + plane.u();
let c = plane.origin() + plane.v();
let d = ray.origin;

let [a, b, c, d] = [a, b, c, d]
Expand Down Expand Up @@ -63,8 +59,8 @@ impl Intersect for (&HorizontalRayToTheRight<3>, &Face) {
// We already handled the case of the ray and plane being parallel
// above. The following assertion should thus never be triggered.
assert_ne!(
plane_direction_1.y * plane_direction_2.z,
plane_direction_1.z * plane_direction_2.y,
plane.u().y * plane.v().z,
plane.u().z * plane.v().y,
"Plane and ray are parallel; should have been ruled out previously"
);

Expand All @@ -75,15 +71,15 @@ impl Intersect for (&HorizontalRayToTheRight<3>, &Face) {
let orx = ray.origin.x;
let ory = ray.origin.y;
let orz = ray.origin.z;
let opx = plane_origin.x;
let opy = plane_origin.y;
let opz = plane_origin.z;
let d1x = plane_direction_1.x;
let d1y = plane_direction_1.y;
let d1z = plane_direction_1.z;
let d2x = plane_direction_2.x;
let d2y = plane_direction_2.y;
let d2z = plane_direction_2.z;
let opx = plane.origin().x;
let opy = plane.origin().y;
let opz = plane.origin().z;
let d1x = plane.u().x;
let d1y = plane.u().y;
let d1z = plane.u().z;
let d2x = plane.v().x;
let d2y = plane.v().y;
let d2z = plane.v().z;

// Let's figure out where the intersection between the ray and the
// plane is. By equating the parametric equations of the ray and the
Expand Down
31 changes: 21 additions & 10 deletions crates/fj-math/src/plane.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ impl Plane {
self.v
}

/// Compute the normal of the plane
pub fn normal(&self) -> Vector<3> {
self.u().cross(&self.v()).normalize()
}

/// Convert the plane to three-point form
pub fn three_point_form(&self) -> [Point<3>; 3] {
let a = self.origin();
Expand All @@ -45,16 +50,25 @@ impl Plane {

/// Convert the plane to constant-normal form
pub fn constant_normal_form(&self) -> (Scalar, Vector<3>) {
let [a, b, c] = self.three_point_form();

// See Real-Time Collision Detection by Christer Ericson, section 3.6,
// Planes and Halfspaces.
let normal = (b - a).cross(&(c - a)).normalize();
let distance = normal.dot(&a.coords);
let normal = self.normal();
let distance = normal.dot(&self.origin().coords);

(distance, normal)
}

/// Determine whether the plane is parallel to the given vector
pub fn is_parallel_to_vector(&self, vector: &Vector<3>) -> bool {
self.normal().dot(vector) == Scalar::ZERO
}

/// Project a vector into the plane
pub fn project_vector(&self, vector: &Vector<3>) -> Vector<2> {
Vector::from([
self.u().scalar_projection_onto(vector),
self.v().scalar_projection_onto(vector),
])
}

/// Project a line into the plane
pub fn project_line(&self, line: &Line<3>) -> Line<2> {
let line_origin_relative_to_plane = line.origin() - self.origin();
Expand All @@ -67,10 +81,7 @@ impl Plane {
]),
};

let line_direction_in_plane = Vector::from([
self.u().scalar_projection_onto(&line.direction()),
self.v().scalar_projection_onto(&line.direction()),
]);
let line_direction_in_plane = self.project_vector(&line.direction());

Line::from_origin_and_direction(
line_origin_in_plane,
Expand Down

0 comments on commit 2b32926

Please sign in to comment.