From 1eeb53dc905766d429e31f1cbbe2b67d57f95855 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 5 Aug 2022 13:35:32 +0200 Subject: [PATCH 1/5] Fix typo in comment --- crates/fj-kernel/src/algorithms/triangulate/polygon.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/algorithms/triangulate/polygon.rs b/crates/fj-kernel/src/algorithms/triangulate/polygon.rs index f813a7a13..d01e8287c 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/polygon.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/polygon.rs @@ -103,7 +103,7 @@ impl Polygon { } } - // We haven't rules out that the triangle is a polygon hole. Since we + // We haven't ruled out that the triangle is a polygon hole. Since we // checked all its edges, this means we now know for certain that is is. if might_be_hole { return false; From eb6519b5f6c07f0a78b2ff25ac182e4aba479f03 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 5 Aug 2022 15:33:48 +0200 Subject: [PATCH 2/5] Document `ray` module --- crates/fj-kernel/src/algorithms/triangulate/ray.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/crates/fj-kernel/src/algorithms/triangulate/ray.rs b/crates/fj-kernel/src/algorithms/triangulate/ray.rs index e46cbb05c..c6ac8d672 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/ray.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/ray.rs @@ -1,10 +1,18 @@ +//! Ray casting + use fj_math::{Point, Segment}; +/// A horizontal ray that goes to the right +/// +/// For in-kernel use, we don't need anything more flexible, and being exactly +/// horizontal simplifies some calculations. pub struct HorizontalRayToTheRight { + /// The point where the ray originates pub origin: Point<2>, } impl HorizontalRayToTheRight { + /// Determine whether the ray hits the given line segment pub fn hits_segment(&self, segment: impl Into>) -> Option { let [a, b] = segment.into().points(); let [lower, upper] = if a.v <= b.v { [a, b] } else { [b, a] }; @@ -70,13 +78,19 @@ where } } +/// A hit between a ray and a line segment #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Hit { + /// The ray hit the segment itself Segment, + /// The ray hit the lower vertex of the segment LowerVertex, + + /// The ray hit the upper vertex of the segment UpperVertex, + /// The ray hit the whole segment, as it is parallel to the ray Parallel, } From 3a21afc8657ffb8795cdfd1581455d0a422e19f9 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 5 Aug 2022 15:38:41 +0200 Subject: [PATCH 3/5] Make struct name more specific --- .../src/algorithms/triangulate/polygon.rs | 16 ++++-- .../src/algorithms/triangulate/ray.rs | 50 +++++++++++++------ 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/triangulate/polygon.rs b/crates/fj-kernel/src/algorithms/triangulate/polygon.rs index d01e8287c..bc93c78ea 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/polygon.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/polygon.rs @@ -3,7 +3,7 @@ use fj_math::{Point, PolyChain, Segment}; use crate::objects::Surface; -use super::ray::{Hit, HorizontalRayToTheRight}; +use super::ray::{HorizontalRayToTheRight, RaySegmentHit}; pub struct Polygon { surface: Surface, @@ -162,12 +162,18 @@ impl Polygon { let hit = ray.hits_segment(edge); let count_hit = match (hit, previous_hit) { - (Some(Hit::Segment), _) => { + (Some(RaySegmentHit::Segment), _) => { // We're hitting a segment right-on. Clear case. true } - (Some(Hit::UpperVertex), Some(Hit::LowerVertex)) - | (Some(Hit::LowerVertex), Some(Hit::UpperVertex)) => { + ( + Some(RaySegmentHit::UpperVertex), + Some(RaySegmentHit::LowerVertex), + ) + | ( + Some(RaySegmentHit::LowerVertex), + Some(RaySegmentHit::UpperVertex), + ) => { // If we're hitting a vertex, only count it if we've hit // the other kind of vertex right before. // @@ -183,7 +189,7 @@ impl Polygon { // passing through anything. true } - (Some(Hit::Parallel), _) => { + (Some(RaySegmentHit::Parallel), _) => { // A parallel edge must be completely ignored. Its // presence won't change anything, so we can treat it as // if it wasn't there, and its neighbors were connected diff --git a/crates/fj-kernel/src/algorithms/triangulate/ray.rs b/crates/fj-kernel/src/algorithms/triangulate/ray.rs index c6ac8d672..4224eb9e0 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/ray.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/ray.rs @@ -13,7 +13,10 @@ pub struct HorizontalRayToTheRight { impl HorizontalRayToTheRight { /// Determine whether the ray hits the given line segment - pub fn hits_segment(&self, segment: impl Into>) -> Option { + pub fn hits_segment( + &self, + segment: impl Into>, + ) -> Option { let [a, b] = segment.into().points(); let [lower, upper] = if a.v <= b.v { [a, b] } else { [b, a] }; let right = if a.u > b.u { a } else { b }; @@ -34,7 +37,7 @@ impl HorizontalRayToTheRight { return None; } - return Some(Hit::Parallel); + return Some(RaySegmentHit::Parallel); } let pa = robust::Coord { @@ -54,13 +57,13 @@ impl HorizontalRayToTheRight { // ray starts on the line or left of it if self.origin.v == upper.v { - return Some(Hit::UpperVertex); + return Some(RaySegmentHit::UpperVertex); } if self.origin.v == lower.v { - return Some(Hit::LowerVertex); + return Some(RaySegmentHit::LowerVertex); } - return Some(Hit::Segment); + return Some(RaySegmentHit::Segment); } None @@ -80,7 +83,7 @@ where /// A hit between a ray and a line segment #[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum Hit { +pub enum RaySegmentHit { /// The ray hit the segment itself Segment, @@ -96,7 +99,7 @@ pub enum Hit { #[cfg(test)] mod tests { - use super::{Hit, HorizontalRayToTheRight}; + use super::{HorizontalRayToTheRight, RaySegmentHit}; #[test] fn hits_segment_right() { @@ -108,7 +111,10 @@ mod tests { assert!(ray.hits_segment(below).is_none()); assert!(ray.hits_segment(above).is_none()); - assert!(matches!(ray.hits_segment(same_level), Some(Hit::Segment))); + assert!(matches!( + ray.hits_segment(same_level), + Some(RaySegmentHit::Segment) + )); } #[test] @@ -130,14 +136,17 @@ mod tests { let hit_lower = [[0., 2.], [2., 1.]]; assert!(ray.hits_segment(no_hit).is_none()); - assert!(matches!(ray.hits_segment(hit_segment), Some(Hit::Segment))); + assert!(matches!( + ray.hits_segment(hit_segment), + Some(RaySegmentHit::Segment) + )); assert!(matches!( ray.hits_segment(hit_upper), - Some(Hit::UpperVertex), + Some(RaySegmentHit::UpperVertex), )); assert!(matches!( ray.hits_segment(hit_lower), - Some(Hit::LowerVertex), + Some(RaySegmentHit::LowerVertex), )); } @@ -149,14 +158,17 @@ mod tests { let hit_upper = [[0., 0.], [1., 1.]]; let hit_lower = [[1., 1.], [2., 2.]]; - assert!(matches!(ray.hits_segment(hit_segment), Some(Hit::Segment))); + assert!(matches!( + ray.hits_segment(hit_segment), + Some(RaySegmentHit::Segment) + )); assert!(matches!( ray.hits_segment(hit_upper), - Some(Hit::UpperVertex), + Some(RaySegmentHit::UpperVertex), )); assert!(matches!( ray.hits_segment(hit_lower), - Some(Hit::LowerVertex), + Some(RaySegmentHit::LowerVertex), )); } @@ -169,7 +181,13 @@ mod tests { let right = [[3., 0.], [4., 0.]]; assert!(ray.hits_segment(left).is_none()); - assert!(matches!(ray.hits_segment(overlapping), Some(Hit::Parallel))); - assert!(matches!(ray.hits_segment(right), Some(Hit::Parallel))); + assert!(matches!( + ray.hits_segment(overlapping), + Some(RaySegmentHit::Parallel) + )); + assert!(matches!( + ray.hits_segment(right), + Some(RaySegmentHit::Parallel) + )); } } From d24d1e43bb0b93dffb95832e4bbc2e1c47ceb71f Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 5 Aug 2022 15:28:11 +0200 Subject: [PATCH 4/5] Move ray casting code to `algorithms::ray_cast` This was formerly private. I have more plans for it, so I figured, why not move it to its own module within `algorithms`. --- crates/fj-kernel/src/algorithms/mod.rs | 1 + .../src/algorithms/{triangulate/ray.rs => ray_cast.rs} | 0 crates/fj-kernel/src/algorithms/triangulate/mod.rs | 1 - crates/fj-kernel/src/algorithms/triangulate/polygon.rs | 7 ++++--- 4 files changed, 5 insertions(+), 4 deletions(-) rename crates/fj-kernel/src/algorithms/{triangulate/ray.rs => ray_cast.rs} (100%) diff --git a/crates/fj-kernel/src/algorithms/mod.rs b/crates/fj-kernel/src/algorithms/mod.rs index 402d5ab9f..08319f8a7 100644 --- a/crates/fj-kernel/src/algorithms/mod.rs +++ b/crates/fj-kernel/src/algorithms/mod.rs @@ -10,6 +10,7 @@ mod transform; mod triangulate; pub mod intersection; +pub mod ray_cast; pub use self::{ approx::{CycleApprox, FaceApprox, InvalidTolerance, Tolerance}, diff --git a/crates/fj-kernel/src/algorithms/triangulate/ray.rs b/crates/fj-kernel/src/algorithms/ray_cast.rs similarity index 100% rename from crates/fj-kernel/src/algorithms/triangulate/ray.rs rename to crates/fj-kernel/src/algorithms/ray_cast.rs diff --git a/crates/fj-kernel/src/algorithms/triangulate/mod.rs b/crates/fj-kernel/src/algorithms/triangulate/mod.rs index 689c19992..27ddb01e8 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/mod.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/mod.rs @@ -1,6 +1,5 @@ mod delaunay; mod polygon; -mod ray; use fj_interop::{debug::DebugInfo, mesh::Mesh}; use fj_math::Point; diff --git a/crates/fj-kernel/src/algorithms/triangulate/polygon.rs b/crates/fj-kernel/src/algorithms/triangulate/polygon.rs index bc93c78ea..eac7d93e8 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/polygon.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/polygon.rs @@ -1,9 +1,10 @@ use fj_interop::debug::{DebugInfo, TriangleEdgeCheck}; use fj_math::{Point, PolyChain, Segment}; -use crate::objects::Surface; - -use super::ray::{HorizontalRayToTheRight, RaySegmentHit}; +use crate::{ + algorithms::ray_cast::{HorizontalRayToTheRight, RaySegmentHit}, + objects::Surface, +}; pub struct Polygon { surface: Surface, From dd8a32b1e1da584c000f32fb413364d053c04782 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 5 Aug 2022 15:40:27 +0200 Subject: [PATCH 5/5] Make struct generic over dimensionality --- crates/fj-kernel/src/algorithms/ray_cast.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/ray_cast.rs b/crates/fj-kernel/src/algorithms/ray_cast.rs index 4224eb9e0..89d9e6f51 100644 --- a/crates/fj-kernel/src/algorithms/ray_cast.rs +++ b/crates/fj-kernel/src/algorithms/ray_cast.rs @@ -6,12 +6,12 @@ use fj_math::{Point, Segment}; /// /// For in-kernel use, we don't need anything more flexible, and being exactly /// horizontal simplifies some calculations. -pub struct HorizontalRayToTheRight { +pub struct HorizontalRayToTheRight { /// The point where the ray originates - pub origin: Point<2>, + pub origin: Point, } -impl HorizontalRayToTheRight { +impl HorizontalRayToTheRight<2> { /// Determine whether the ray hits the given line segment pub fn hits_segment( &self, @@ -70,9 +70,9 @@ impl HorizontalRayToTheRight { } } -impl

From

for HorizontalRayToTheRight +impl From

for HorizontalRayToTheRight where - P: Into>, + P: Into>, { fn from(point: P) -> Self { Self {