From fe20bc4fba1b5b96b67cdb6f817078bd496af44e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 2 Aug 2022 12:59:37 +0200 Subject: [PATCH 1/8] Refactor This minimizes the diff of an upcoming change. --- crates/fj-kernel/src/algorithms/intersection/curve_face.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/algorithms/intersection/curve_face.rs b/crates/fj-kernel/src/algorithms/intersection/curve_face.rs index 54f2117f4..d42d1e8fd 100644 --- a/crates/fj-kernel/src/algorithms/intersection/curve_face.rs +++ b/crates/fj-kernel/src/algorithms/intersection/curve_face.rs @@ -148,6 +148,8 @@ mod tests { #[test] fn compute() { + let surface = Surface::xy_plane(); + let curve = CurveKind::Line(Line { origin: Point::from([-3., 0.]), direction: Vector::from([1., 0.]), @@ -168,7 +170,6 @@ mod tests { [-1., 1.], ]; - let surface = Surface::xy_plane(); let face = Face::build(surface) .polygon_from_points(exterior) .with_hole(interior); From a519f905381e60a3af1e45be83db22e61f3fd45c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 2 Aug 2022 13:49:09 +0200 Subject: [PATCH 2/8] Use `Curve` in `CurveFaceIntersection` --- .../src/algorithms/intersection/curve_face.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/intersection/curve_face.rs b/crates/fj-kernel/src/algorithms/intersection/curve_face.rs index d42d1e8fd..c93ce7153 100644 --- a/crates/fj-kernel/src/algorithms/intersection/curve_face.rs +++ b/crates/fj-kernel/src/algorithms/intersection/curve_face.rs @@ -4,7 +4,7 @@ use fj_math::Point; use crate::{ algorithms::intersection::CurveEdgeIntersection, - objects::{CurveKind, Face}, + objects::{Curve, Face}, }; /// The intersections between a curve and a [`Face`], in curve coordinates @@ -28,7 +28,7 @@ impl CurveFaceIntersectionList { } /// Compute the intersections between a curve and a [`Face`] - pub fn compute(curve: &CurveKind<2>, face: &Face) -> Self { + pub fn compute(curve: &Curve, face: &Face) -> Self { let edges = face.all_cycles().flat_map(|cycle| { let edges: Vec<_> = cycle.edges().cloned().collect(); edges @@ -37,7 +37,8 @@ impl CurveFaceIntersectionList { let mut intersections = Vec::new(); for edge in edges { - let intersection = CurveEdgeIntersection::compute(curve, &edge); + let intersection = + CurveEdgeIntersection::compute(curve.kind(), &edge); if let Some(intersection) = intersection { match intersection { @@ -140,9 +141,7 @@ pub type CurveFaceIntersection = [Point<1>; 2]; #[cfg(test)] mod tests { - use fj_math::{Line, Point, Vector}; - - use crate::objects::{CurveKind, Face, Surface}; + use crate::objects::{Curve, Face, Surface}; use super::CurveFaceIntersectionList; @@ -150,10 +149,8 @@ mod tests { fn compute() { let surface = Surface::xy_plane(); - let curve = CurveKind::Line(Line { - origin: Point::from([-3., 0.]), - direction: Vector::from([1., 0.]), - }); + let curve = + Curve::build(surface).line_from_points([[-3., 0.], [-2., 0.]]); #[rustfmt::skip] let exterior = [ From d4c15b883dffdf9447e2d5ce9741b6e98b578987 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 2 Aug 2022 13:50:58 +0200 Subject: [PATCH 3/8] Use `Curve` in `CurveEdgeIntersection` --- .../src/algorithms/intersection/curve_edge.rs | 14 +++++++------- .../src/algorithms/intersection/curve_face.rs | 3 +-- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/intersection/curve_edge.rs b/crates/fj-kernel/src/algorithms/intersection/curve_edge.rs index 22841cb67..06db7730b 100644 --- a/crates/fj-kernel/src/algorithms/intersection/curve_edge.rs +++ b/crates/fj-kernel/src/algorithms/intersection/curve_edge.rs @@ -1,6 +1,6 @@ use fj_math::{Point, Segment}; -use crate::objects::{CurveKind, Edge}; +use crate::objects::{Curve, CurveKind, Edge}; use super::LineSegmentIntersection; @@ -28,8 +28,8 @@ impl CurveEdgeIntersection { /// Currently, only intersections between lines and line segments can be /// computed. Panics, if a different type of curve or [`Edge`] is /// passed. - pub fn compute(curve: &CurveKind<2>, edge: &Edge) -> Option { - let curve_as_line = match curve { + pub fn compute(curve: &Curve, edge: &Edge) -> Option { + let curve_as_line = match curve.kind() { CurveKind::Line(line) => line, _ => todo!("Curve-edge intersection only supports lines"), }; @@ -87,7 +87,7 @@ mod tests { let edge = Edge::build() .line_segment_from_points(&surface, [[1., -1.], [1., 1.]]); - let intersection = CurveEdgeIntersection::compute(curve.kind(), &edge); + let intersection = CurveEdgeIntersection::compute(&curve, &edge); assert_eq!( intersection, @@ -104,7 +104,7 @@ mod tests { let edge = Edge::build() .line_segment_from_points(&surface, [[-1., -1.], [-1., 1.]]); - let intersection = CurveEdgeIntersection::compute(curve.kind(), &edge); + let intersection = CurveEdgeIntersection::compute(&curve, &edge); assert_eq!( intersection, @@ -121,7 +121,7 @@ mod tests { let edge = Edge::build() .line_segment_from_points(&surface, [[-1., -1.], [1., -1.]]); - let intersection = CurveEdgeIntersection::compute(curve.kind(), &edge); + let intersection = CurveEdgeIntersection::compute(&curve, &edge); assert!(intersection.is_none()); } @@ -133,7 +133,7 @@ mod tests { let edge = Edge::build() .line_segment_from_points(&surface, [[-1., 0.], [1., 0.]]); - let intersection = CurveEdgeIntersection::compute(curve.kind(), &edge); + let intersection = CurveEdgeIntersection::compute(&curve, &edge); assert_eq!( intersection, diff --git a/crates/fj-kernel/src/algorithms/intersection/curve_face.rs b/crates/fj-kernel/src/algorithms/intersection/curve_face.rs index c93ce7153..ad4926718 100644 --- a/crates/fj-kernel/src/algorithms/intersection/curve_face.rs +++ b/crates/fj-kernel/src/algorithms/intersection/curve_face.rs @@ -37,8 +37,7 @@ impl CurveFaceIntersectionList { let mut intersections = Vec::new(); for edge in edges { - let intersection = - CurveEdgeIntersection::compute(curve.kind(), &edge); + let intersection = CurveEdgeIntersection::compute(curve, &edge); if let Some(intersection) = intersection { match intersection { From 6c38b6268006a4aa17cc3156d740f63e43b217ec Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 2 Aug 2022 13:51:13 +0200 Subject: [PATCH 4/8] Update doc comments --- crates/fj-kernel/src/algorithms/intersection/curve_edge.rs | 4 ++-- crates/fj-kernel/src/algorithms/intersection/curve_face.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/intersection/curve_edge.rs b/crates/fj-kernel/src/algorithms/intersection/curve_edge.rs index 06db7730b..177037ef2 100644 --- a/crates/fj-kernel/src/algorithms/intersection/curve_edge.rs +++ b/crates/fj-kernel/src/algorithms/intersection/curve_edge.rs @@ -4,7 +4,7 @@ use crate::objects::{Curve, CurveKind, Edge}; use super::LineSegmentIntersection; -/// The intersection between a curve and an [`Edge`], in curve coordinates +/// The intersection between a [`Curve`] and an [`Edge`], in curve coordinates #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub enum CurveEdgeIntersection { /// The curve and edge intersect at a point @@ -26,7 +26,7 @@ impl CurveEdgeIntersection { /// # Panics /// /// Currently, only intersections between lines and line segments can be - /// computed. Panics, if a different type of curve or [`Edge`] is + /// computed. Panics, if a different type of [`Curve`] or [`Edge`] is /// passed. pub fn compute(curve: &Curve, edge: &Edge) -> Option { let curve_as_line = match curve.kind() { diff --git a/crates/fj-kernel/src/algorithms/intersection/curve_face.rs b/crates/fj-kernel/src/algorithms/intersection/curve_face.rs index ad4926718..cbbf730fe 100644 --- a/crates/fj-kernel/src/algorithms/intersection/curve_face.rs +++ b/crates/fj-kernel/src/algorithms/intersection/curve_face.rs @@ -7,7 +7,7 @@ use crate::{ objects::{Curve, Face}, }; -/// The intersections between a curve and a [`Face`], in curve coordinates +/// The intersections between a [`Curve`] and a [`Face`], in curve coordinates #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct CurveFaceIntersectionList { intervals: Vec, @@ -27,7 +27,7 @@ impl CurveFaceIntersectionList { Self { intervals } } - /// Compute the intersections between a curve and a [`Face`] + /// Compute the intersections between a [`Curve`] and a [`Face`] pub fn compute(curve: &Curve, face: &Face) -> Self { let edges = face.all_cycles().flat_map(|cycle| { let edges: Vec<_> = cycle.edges().cloned().collect(); From 9cd775f4659bb0bfcf364ea2a5a5f0794871d864 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 2 Aug 2022 13:53:20 +0200 Subject: [PATCH 5/8] Simplify function signature --- .../src/algorithms/intersection/surface_surface.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs b/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs index 46122ee73..93b7e15e6 100644 --- a/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs +++ b/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs @@ -14,7 +14,7 @@ pub struct SurfaceSurfaceIntersection { impl SurfaceSurfaceIntersection { /// Compute the intersection between two surfaces - pub fn compute(a: &Surface, b: &Surface) -> Option { + pub fn compute([a, b]: [&Surface; 2]) -> Option { // Algorithm from Real-Time Collision Detection by Christer Ericson. See // section 5.4.4, Intersection of Two Planes. // @@ -154,12 +154,12 @@ mod tests { let xz = Surface::xz_plane(); // Coincident and parallel planes don't have an intersection curve. - assert_eq!(SurfaceSurfaceIntersection::compute(&xy, &xy), None); + assert_eq!(SurfaceSurfaceIntersection::compute([&xy, &xy]), None); assert_eq!( - SurfaceSurfaceIntersection::compute( + SurfaceSurfaceIntersection::compute([ &xy, &xy.transform(&Transform::translation([0., 0., 1.])) - ), + ]), None, ); @@ -167,7 +167,7 @@ mod tests { let expected_xz = Curve::build(xz).u_axis(); assert_eq!( - SurfaceSurfaceIntersection::compute(&xy, &xz), + SurfaceSurfaceIntersection::compute([&xy, &xz]), Some(SurfaceSurfaceIntersection { local_intersection_curves: [ *expected_xy.kind(), From 36bbf95be77960bf6d2400f5b19b88285713f913 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 2 Aug 2022 13:57:20 +0200 Subject: [PATCH 6/8] Derive `Copy` for private struct --- crates/fj-kernel/src/algorithms/intersection/surface_surface.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs b/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs index 93b7e15e6..750f79f83 100644 --- a/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs +++ b/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs @@ -60,6 +60,7 @@ impl SurfaceSurfaceIntersection { } /// A plane in parametric form +#[derive(Clone, Copy)] struct PlaneParametric { pub origin: Point<3>, pub u: Vector<3>, From ba608268f857214ef797676c3db247917425f65f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 2 Aug 2022 13:57:32 +0200 Subject: [PATCH 7/8] Refactor --- .../algorithms/intersection/surface_surface.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs b/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs index 750f79f83..d4074a3b9 100644 --- a/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs +++ b/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs @@ -14,18 +14,17 @@ pub struct SurfaceSurfaceIntersection { impl SurfaceSurfaceIntersection { /// Compute the intersection between two surfaces - pub fn compute([a, b]: [&Surface; 2]) -> Option { + pub fn compute(surfaces: [&Surface; 2]) -> Option { // Algorithm from Real-Time Collision Detection by Christer Ericson. See // section 5.4.4, Intersection of Two Planes. // // Adaptations were made to get the intersection curves in local // coordinates for each surface. - let a_parametric = PlaneParametric::extract_from_surface(a); - let b_parametric = PlaneParametric::extract_from_surface(b); - - let a = PlaneConstantNormal::from_parametric_plane(&a_parametric); - let b = PlaneConstantNormal::from_parametric_plane(&b_parametric); + let planes_parametric = + surfaces.map(PlaneParametric::extract_from_surface); + let [a, b] = planes_parametric + .map(|plane| PlaneConstantNormal::from_parametric_plane(&plane)); let direction = a.normal.cross(&b.normal); @@ -48,12 +47,12 @@ impl SurfaceSurfaceIntersection { let line = Line { origin, direction }; - let curve_a = project_line_into_plane(&line, &a_parametric); - let curve_b = project_line_into_plane(&line, &b_parametric); + let curves = planes_parametric + .map(|plane| project_line_into_plane(&line, &plane)); let curve_global = CurveKind::Line(Line { origin, direction }); Some(Self { - local_intersection_curves: [curve_a, curve_b], + local_intersection_curves: curves, global_intersection_curve: curve_global, }) } From 964a2b446d77f257c0dcfbd601094daaa82feda7 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 2 Aug 2022 14:00:26 +0200 Subject: [PATCH 8/8] Simplify `SurfaceSurfaceIntersection` --- .../intersection/surface_surface.rs | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs b/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs index d4074a3b9..48241de2f 100644 --- a/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs +++ b/crates/fj-kernel/src/algorithms/intersection/surface_surface.rs @@ -1,15 +1,12 @@ use fj_math::{Line, Point, Scalar, Vector}; -use crate::objects::{CurveKind, Surface}; +use crate::objects::{Curve, CurveKind, GlobalCurve, Surface}; /// The intersection between two surfaces #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] pub struct SurfaceSurfaceIntersection { - /// The intersection curves, in the coordinates of the input surfaces - pub local_intersection_curves: [CurveKind<2>; 2], - - /// The intersection curve, in global coordinates - pub global_intersection_curve: CurveKind<3>, + /// The intersection curves + pub intersection_curves: [Curve; 2], } impl SurfaceSurfaceIntersection { @@ -47,13 +44,15 @@ impl SurfaceSurfaceIntersection { let line = Line { origin, direction }; - let curves = planes_parametric - .map(|plane| project_line_into_plane(&line, &plane)); - let curve_global = CurveKind::Line(Line { origin, direction }); + let curves = planes_parametric.map(|plane| { + let local = project_line_into_plane(&line, &plane); + let global = CurveKind::Line(Line { origin, direction }); + + Curve::new(local, GlobalCurve::from_kind(global)) + }); Some(Self { - local_intersection_curves: curves, - global_intersection_curve: curve_global, + intersection_curves: curves, }) } } @@ -169,11 +168,7 @@ mod tests { assert_eq!( SurfaceSurfaceIntersection::compute([&xy, &xz]), Some(SurfaceSurfaceIntersection { - local_intersection_curves: [ - *expected_xy.kind(), - *expected_xz.kind() - ], - global_intersection_curve: *expected_xy.global().kind(), + intersection_curves: [expected_xy, expected_xz], }) ); }