From dbdf225ded7dac1325145d3f0cc933490a0e13df Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 12 Aug 2022 14:04:15 +0200 Subject: [PATCH 1/7] Refactor --- crates/fj-kernel/src/algorithms/cast_ray/edge.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/cast_ray/edge.rs b/crates/fj-kernel/src/algorithms/cast_ray/edge.rs index e7e88a62a..23dd8a35c 100644 --- a/crates/fj-kernel/src/algorithms/cast_ray/edge.rs +++ b/crates/fj-kernel/src/algorithms/cast_ray/edge.rs @@ -2,15 +2,12 @@ use fj_math::Segment; use crate::objects::{CurveKind, Edge}; -use super::CastRay; +use super::{CastRay, HorizontalRayToTheRight}; impl CastRay<2> for Edge { type Hit = as CastRay<2>>::Hit; - fn cast_ray( - &self, - ray: super::HorizontalRayToTheRight<2>, - ) -> Option { + fn cast_ray(&self, ray: HorizontalRayToTheRight<2>) -> Option { let line = match self.curve().kind() { CurveKind::Line(line) => line, CurveKind::Circle(_) => { From fb5961527df7176d44289c3deb202852fcb9c1d5 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 12 Aug 2022 14:09:42 +0200 Subject: [PATCH 2/7] Move `HorizontalRayToTheRight` to `intersect` This is the beginning of merging the `cast_ray` module into `intersect`. --- .../fj-kernel/src/algorithms/cast_ray/edge.rs | 7 ++++-- .../fj-kernel/src/algorithms/cast_ray/mod.rs | 23 +------------------ .../src/algorithms/intersect/face_point.rs | 4 ++-- .../fj-kernel/src/algorithms/intersect/mod.rs | 23 +++++++++++++++++++ .../src/algorithms/triangulate/polygon.rs | 5 +++- 5 files changed, 35 insertions(+), 27 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/cast_ray/edge.rs b/crates/fj-kernel/src/algorithms/cast_ray/edge.rs index 23dd8a35c..2845423cb 100644 --- a/crates/fj-kernel/src/algorithms/cast_ray/edge.rs +++ b/crates/fj-kernel/src/algorithms/cast_ray/edge.rs @@ -1,8 +1,11 @@ use fj_math::Segment; -use crate::objects::{CurveKind, Edge}; +use crate::{ + algorithms::intersect::HorizontalRayToTheRight, + objects::{CurveKind, Edge}, +}; -use super::{CastRay, HorizontalRayToTheRight}; +use super::CastRay; impl CastRay<2> for Edge { type Hit = as CastRay<2>>::Hit; diff --git a/crates/fj-kernel/src/algorithms/cast_ray/mod.rs b/crates/fj-kernel/src/algorithms/cast_ray/mod.rs index 707355d13..64aed063d 100644 --- a/crates/fj-kernel/src/algorithms/cast_ray/mod.rs +++ b/crates/fj-kernel/src/algorithms/cast_ray/mod.rs @@ -5,7 +5,7 @@ mod segment; pub use self::segment::RaySegmentHit; -use fj_math::Point; +use super::intersect::HorizontalRayToTheRight; /// Implemented by types that support ray casting /// @@ -23,24 +23,3 @@ pub trait CastRay { /// Cast a ray against `self` fn cast_ray(&self, ray: HorizontalRayToTheRight) -> Option; } - -/// 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. -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct HorizontalRayToTheRight { - /// The point where the ray originates - pub origin: Point, -} - -impl From

for HorizontalRayToTheRight -where - P: Into>, -{ - fn from(point: P) -> Self { - Self { - origin: point.into(), - } - } -} diff --git a/crates/fj-kernel/src/algorithms/intersect/face_point.rs b/crates/fj-kernel/src/algorithms/intersect/face_point.rs index acc873221..dbda9a7be 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_point.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_point.rs @@ -3,11 +3,11 @@ use fj_math::Point; use crate::{ - algorithms::cast_ray::{CastRay, HorizontalRayToTheRight, RaySegmentHit}, + algorithms::cast_ray::{CastRay, RaySegmentHit}, objects::Face, }; -use super::Intersect; +use super::{HorizontalRayToTheRight, Intersect}; impl Intersect for (&Face, &Point<2>) { type Intersection = FacePointIntersection; diff --git a/crates/fj-kernel/src/algorithms/intersect/mod.rs b/crates/fj-kernel/src/algorithms/intersect/mod.rs index 9cb251191..6d6e4bdfa 100644 --- a/crates/fj-kernel/src/algorithms/intersect/mod.rs +++ b/crates/fj-kernel/src/algorithms/intersect/mod.rs @@ -8,6 +8,8 @@ mod face_face; mod line_segment; mod surface_surface; +use fj_math::Point; + pub use self::{ curve_edge::CurveEdgeIntersection, curve_face::{CurveFaceIntersection, CurveFaceIntersectionInterval}, @@ -29,3 +31,24 @@ pub trait Intersect { /// Compute the intersection between a tuple of objects fn intersect(self) -> Option; } + +/// 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. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub struct HorizontalRayToTheRight { + /// The point where the ray originates + pub origin: Point, +} + +impl From

for HorizontalRayToTheRight +where + P: Into>, +{ + fn from(point: P) -> Self { + Self { + origin: point.into(), + } + } +} diff --git a/crates/fj-kernel/src/algorithms/triangulate/polygon.rs b/crates/fj-kernel/src/algorithms/triangulate/polygon.rs index 081f076d0..7080c9ea6 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/polygon.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/polygon.rs @@ -2,7 +2,10 @@ use fj_interop::debug::{DebugInfo, TriangleEdgeCheck}; use fj_math::{Point, PolyChain, Segment}; use crate::{ - algorithms::cast_ray::{CastRay, HorizontalRayToTheRight, RaySegmentHit}, + algorithms::{ + cast_ray::{CastRay, RaySegmentHit}, + intersect::HorizontalRayToTheRight, + }, objects::Surface, }; From 5f4e458e9b5f849dc4f3de21cefa286fd8da49ce Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 12 Aug 2022 14:17:36 +0200 Subject: [PATCH 3/7] Migrate ray/segment intersection to `intersect` --- .../fj-kernel/src/algorithms/cast_ray/edge.rs | 8 +-- .../fj-kernel/src/algorithms/cast_ray/mod.rs | 3 -- .../src/algorithms/intersect/face_point.rs | 7 +-- .../fj-kernel/src/algorithms/intersect/mod.rs | 1 + .../segment.rs => intersect/ray_segment.rs} | 50 ++++++++++--------- .../src/algorithms/triangulate/polygon.rs | 13 ++--- 6 files changed, 42 insertions(+), 40 deletions(-) rename crates/fj-kernel/src/algorithms/{cast_ray/segment.rs => intersect/ray_segment.rs} (77%) diff --git a/crates/fj-kernel/src/algorithms/cast_ray/edge.rs b/crates/fj-kernel/src/algorithms/cast_ray/edge.rs index 2845423cb..4a688094d 100644 --- a/crates/fj-kernel/src/algorithms/cast_ray/edge.rs +++ b/crates/fj-kernel/src/algorithms/cast_ray/edge.rs @@ -1,14 +1,16 @@ use fj_math::Segment; use crate::{ - algorithms::intersect::HorizontalRayToTheRight, + algorithms::intersect::{ + ray_segment::RaySegmentHit, HorizontalRayToTheRight, Intersect, + }, objects::{CurveKind, Edge}, }; use super::CastRay; impl CastRay<2> for Edge { - type Hit = as CastRay<2>>::Hit; + type Hit = RaySegmentHit; fn cast_ray(&self, ray: HorizontalRayToTheRight<2>) -> Option { let line = match self.curve().kind() { @@ -24,6 +26,6 @@ impl CastRay<2> for Edge { }); let segment = Segment::from_points(points); - segment.cast_ray(ray) + (&ray, &segment).intersect() } } diff --git a/crates/fj-kernel/src/algorithms/cast_ray/mod.rs b/crates/fj-kernel/src/algorithms/cast_ray/mod.rs index 64aed063d..e51237571 100644 --- a/crates/fj-kernel/src/algorithms/cast_ray/mod.rs +++ b/crates/fj-kernel/src/algorithms/cast_ray/mod.rs @@ -1,9 +1,6 @@ //! Ray casting mod edge; -mod segment; - -pub use self::segment::RaySegmentHit; use super::intersect::HorizontalRayToTheRight; diff --git a/crates/fj-kernel/src/algorithms/intersect/face_point.rs b/crates/fj-kernel/src/algorithms/intersect/face_point.rs index dbda9a7be..a60863494 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_point.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_point.rs @@ -2,12 +2,9 @@ use fj_math::Point; -use crate::{ - algorithms::cast_ray::{CastRay, RaySegmentHit}, - objects::Face, -}; +use crate::{algorithms::cast_ray::CastRay, objects::Face}; -use super::{HorizontalRayToTheRight, Intersect}; +use super::{ray_segment::RaySegmentHit, HorizontalRayToTheRight, Intersect}; impl Intersect for (&Face, &Point<2>) { type Intersection = FacePointIntersection; diff --git a/crates/fj-kernel/src/algorithms/intersect/mod.rs b/crates/fj-kernel/src/algorithms/intersect/mod.rs index 6d6e4bdfa..29b69dc49 100644 --- a/crates/fj-kernel/src/algorithms/intersect/mod.rs +++ b/crates/fj-kernel/src/algorithms/intersect/mod.rs @@ -1,6 +1,7 @@ //! Intersection algorithms pub mod face_point; +pub mod ray_segment; mod curve_edge; mod curve_face; diff --git a/crates/fj-kernel/src/algorithms/cast_ray/segment.rs b/crates/fj-kernel/src/algorithms/intersect/ray_segment.rs similarity index 77% rename from crates/fj-kernel/src/algorithms/cast_ray/segment.rs rename to crates/fj-kernel/src/algorithms/intersect/ray_segment.rs index e0fcdebe6..68d8a47db 100644 --- a/crates/fj-kernel/src/algorithms/cast_ray/segment.rs +++ b/crates/fj-kernel/src/algorithms/intersect/ray_segment.rs @@ -1,15 +1,16 @@ +//! Intersection between a ray and a line segment in 2D + use fj_math::Segment; -use super::{CastRay, HorizontalRayToTheRight}; +use super::{HorizontalRayToTheRight, Intersect}; + +impl Intersect for (&HorizontalRayToTheRight<2>, &Segment<2>) { + type Intersection = RaySegmentHit; -impl CastRay<2> for Segment<2> { - type Hit = RaySegmentHit; + fn intersect(self) -> Option { + let (ray, segment) = self; - fn cast_ray( - &self, - ray: HorizontalRayToTheRight<2>, - ) -> Option { - let [a, b] = self.points(); + let [a, b] = segment.points(); let [lower, upper] = if a.v <= b.v { [a, b] } else { [b, a] }; let right = if a.u > b.u { a } else { b }; @@ -82,7 +83,7 @@ pub enum RaySegmentHit { mod tests { use fj_math::Segment; - use crate::algorithms::cast_ray::CastRay; + use crate::algorithms::intersect::Intersect; use super::{HorizontalRayToTheRight, RaySegmentHit}; @@ -94,10 +95,10 @@ mod tests { let above = Segment::from([[1., 3.], [1., 4.]]); let same_level = Segment::from([[1., 1.], [1., 3.]]); - assert!(below.cast_ray(ray).is_none()); - assert!(above.cast_ray(ray).is_none()); + assert!((&ray, &below).intersect().is_none()); + assert!((&ray, &above).intersect().is_none()); assert!(matches!( - same_level.cast_ray(ray), + (&ray, &same_level).intersect(), Some(RaySegmentHit::Segment) )); } @@ -107,7 +108,7 @@ mod tests { let ray = HorizontalRayToTheRight::from([1., 2.]); let same_level = Segment::from([[0., 1.], [0., 3.]]); - assert!(same_level.cast_ray(ray).is_none()); + assert!((&ray, &same_level).intersect().is_none()); } #[test] @@ -120,17 +121,17 @@ mod tests { let hit_upper = Segment::from([[0., 0.], [2., 1.]]); let hit_lower = Segment::from([[0., 2.], [2., 1.]]); - assert!(no_hit.cast_ray(ray).is_none()); + assert!((&ray, &no_hit).intersect().is_none()); assert!(matches!( - hit_segment.cast_ray(ray), + (&ray, &hit_segment).intersect(), Some(RaySegmentHit::Segment) )); assert!(matches!( - hit_upper.cast_ray(ray), + (&ray, &hit_upper).intersect(), Some(RaySegmentHit::UpperVertex), )); assert!(matches!( - hit_lower.cast_ray(ray), + (&ray, &hit_lower).intersect(), Some(RaySegmentHit::LowerVertex), )); } @@ -144,15 +145,15 @@ mod tests { let hit_lower = Segment::from([[1., 1.], [2., 2.]]); assert!(matches!( - hit_segment.cast_ray(ray), + (&ray, &hit_segment).intersect(), Some(RaySegmentHit::Segment) )); assert!(matches!( - hit_upper.cast_ray(ray), + (&ray, &hit_upper).intersect(), Some(RaySegmentHit::UpperVertex), )); assert!(matches!( - hit_lower.cast_ray(ray), + (&ray, &hit_lower).intersect(), Some(RaySegmentHit::LowerVertex), )); } @@ -165,11 +166,14 @@ mod tests { let overlapping = Segment::from([[1., 0.], [3., 0.]]); let right = Segment::from([[3., 0.], [4., 0.]]); - assert!(left.cast_ray(ray).is_none()); + assert!((&ray, &left).intersect().is_none()); + assert!(matches!( + (&ray, &overlapping).intersect(), + Some(RaySegmentHit::Parallel) + )); assert!(matches!( - overlapping.cast_ray(ray), + (&ray, &right).intersect(), Some(RaySegmentHit::Parallel) )); - assert!(matches!(right.cast_ray(ray), Some(RaySegmentHit::Parallel))); } } diff --git a/crates/fj-kernel/src/algorithms/triangulate/polygon.rs b/crates/fj-kernel/src/algorithms/triangulate/polygon.rs index 7080c9ea6..442a6efb3 100644 --- a/crates/fj-kernel/src/algorithms/triangulate/polygon.rs +++ b/crates/fj-kernel/src/algorithms/triangulate/polygon.rs @@ -2,9 +2,8 @@ use fj_interop::debug::{DebugInfo, TriangleEdgeCheck}; use fj_math::{Point, PolyChain, Segment}; use crate::{ - algorithms::{ - cast_ray::{CastRay, RaySegmentHit}, - intersect::HorizontalRayToTheRight, + algorithms::intersect::{ + ray_segment::RaySegmentHit, HorizontalRayToTheRight, Intersect, }, objects::Surface, }; @@ -164,11 +163,13 @@ impl Polygon { // first segment. The logic in the loop properly takes care of that, // as long as we initialize the `previous_hit` variable with the // result of the last segment. - let mut previous_hit = - edges.last().copied().and_then(|edge| edge.cast_ray(ray)); + let mut previous_hit = edges + .last() + .copied() + .and_then(|edge| (&ray, &edge).intersect()); for edge in edges { - let hit = edge.cast_ray(ray); + let hit = (&ray, &edge).intersect(); let count_hit = match (hit, previous_hit) { (Some(RaySegmentHit::Segment), _) => { From 29ac257a328d0592c229b9ac662f52ea99a8ea06 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 12 Aug 2022 14:18:33 +0200 Subject: [PATCH 4/7] Update enum name --- .../fj-kernel/src/algorithms/cast_ray/edge.rs | 4 +-- .../src/algorithms/intersect/face_point.rs | 16 ++++++---- .../src/algorithms/intersect/ray_segment.rs | 32 +++++++++---------- .../src/algorithms/triangulate/polygon.rs | 14 ++++---- 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/crates/fj-kernel/src/algorithms/cast_ray/edge.rs b/crates/fj-kernel/src/algorithms/cast_ray/edge.rs index 4a688094d..caae1e816 100644 --- a/crates/fj-kernel/src/algorithms/cast_ray/edge.rs +++ b/crates/fj-kernel/src/algorithms/cast_ray/edge.rs @@ -2,7 +2,7 @@ use fj_math::Segment; use crate::{ algorithms::intersect::{ - ray_segment::RaySegmentHit, HorizontalRayToTheRight, Intersect, + ray_segment::RaySegmentIntersection, HorizontalRayToTheRight, Intersect, }, objects::{CurveKind, Edge}, }; @@ -10,7 +10,7 @@ use crate::{ use super::CastRay; impl CastRay<2> for Edge { - type Hit = RaySegmentHit; + type Hit = RaySegmentIntersection; fn cast_ray(&self, ray: HorizontalRayToTheRight<2>) -> Option { let line = match self.curve().kind() { diff --git a/crates/fj-kernel/src/algorithms/intersect/face_point.rs b/crates/fj-kernel/src/algorithms/intersect/face_point.rs index a60863494..01193bab1 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_point.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_point.rs @@ -4,7 +4,9 @@ use fj_math::Point; use crate::{algorithms::cast_ray::CastRay, objects::Face}; -use super::{ray_segment::RaySegmentHit, HorizontalRayToTheRight, Intersect}; +use super::{ + ray_segment::RaySegmentIntersection, HorizontalRayToTheRight, Intersect, +}; impl Intersect for (&Face, &Point<2>) { type Intersection = FacePointIntersection; @@ -32,17 +34,17 @@ impl Intersect for (&Face, &Point<2>) { let hit = edge.cast_ray(ray); let count_hit = match (hit, previous_hit) { - (Some(RaySegmentHit::Segment), _) => { + (Some(RaySegmentIntersection::Segment), _) => { // We're hitting a segment right-on. Clear case. true } ( - Some(RaySegmentHit::UpperVertex), - Some(RaySegmentHit::LowerVertex), + Some(RaySegmentIntersection::UpperVertex), + Some(RaySegmentIntersection::LowerVertex), ) | ( - Some(RaySegmentHit::LowerVertex), - Some(RaySegmentHit::UpperVertex), + Some(RaySegmentIntersection::LowerVertex), + Some(RaySegmentIntersection::UpperVertex), ) => { // If we're hitting a vertex, only count it if we've hit // the other kind of vertex right before. @@ -59,7 +61,7 @@ impl Intersect for (&Face, &Point<2>) { // passing through anything. true } - (Some(RaySegmentHit::Parallel), _) => { + (Some(RaySegmentIntersection::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/intersect/ray_segment.rs b/crates/fj-kernel/src/algorithms/intersect/ray_segment.rs index 68d8a47db..1443d0a30 100644 --- a/crates/fj-kernel/src/algorithms/intersect/ray_segment.rs +++ b/crates/fj-kernel/src/algorithms/intersect/ray_segment.rs @@ -5,7 +5,7 @@ use fj_math::Segment; use super::{HorizontalRayToTheRight, Intersect}; impl Intersect for (&HorizontalRayToTheRight<2>, &Segment<2>) { - type Intersection = RaySegmentHit; + type Intersection = RaySegmentIntersection; fn intersect(self) -> Option { let (ray, segment) = self; @@ -30,7 +30,7 @@ impl Intersect for (&HorizontalRayToTheRight<2>, &Segment<2>) { return None; } - return Some(RaySegmentHit::Parallel); + return Some(RaySegmentIntersection::Parallel); } let pa = robust::Coord { @@ -50,13 +50,13 @@ impl Intersect for (&HorizontalRayToTheRight<2>, &Segment<2>) { // ray starts on the line or left of it if ray.origin.v == upper.v { - return Some(RaySegmentHit::UpperVertex); + return Some(RaySegmentIntersection::UpperVertex); } if ray.origin.v == lower.v { - return Some(RaySegmentHit::LowerVertex); + return Some(RaySegmentIntersection::LowerVertex); } - return Some(RaySegmentHit::Segment); + return Some(RaySegmentIntersection::Segment); } None @@ -65,7 +65,7 @@ impl Intersect for (&HorizontalRayToTheRight<2>, &Segment<2>) { /// A hit between a ray and a line segment #[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum RaySegmentHit { +pub enum RaySegmentIntersection { /// The ray hit the segment itself Segment, @@ -85,7 +85,7 @@ mod tests { use crate::algorithms::intersect::Intersect; - use super::{HorizontalRayToTheRight, RaySegmentHit}; + use super::{HorizontalRayToTheRight, RaySegmentIntersection}; #[test] fn hits_segment_right() { @@ -99,7 +99,7 @@ mod tests { assert!((&ray, &above).intersect().is_none()); assert!(matches!( (&ray, &same_level).intersect(), - Some(RaySegmentHit::Segment) + Some(RaySegmentIntersection::Segment) )); } @@ -124,15 +124,15 @@ mod tests { assert!((&ray, &no_hit).intersect().is_none()); assert!(matches!( (&ray, &hit_segment).intersect(), - Some(RaySegmentHit::Segment) + Some(RaySegmentIntersection::Segment) )); assert!(matches!( (&ray, &hit_upper).intersect(), - Some(RaySegmentHit::UpperVertex), + Some(RaySegmentIntersection::UpperVertex), )); assert!(matches!( (&ray, &hit_lower).intersect(), - Some(RaySegmentHit::LowerVertex), + Some(RaySegmentIntersection::LowerVertex), )); } @@ -146,15 +146,15 @@ mod tests { assert!(matches!( (&ray, &hit_segment).intersect(), - Some(RaySegmentHit::Segment) + Some(RaySegmentIntersection::Segment) )); assert!(matches!( (&ray, &hit_upper).intersect(), - Some(RaySegmentHit::UpperVertex), + Some(RaySegmentIntersection::UpperVertex), )); assert!(matches!( (&ray, &hit_lower).intersect(), - Some(RaySegmentHit::LowerVertex), + Some(RaySegmentIntersection::LowerVertex), )); } @@ -169,11 +169,11 @@ mod tests { assert!((&ray, &left).intersect().is_none()); assert!(matches!( (&ray, &overlapping).intersect(), - Some(RaySegmentHit::Parallel) + Some(RaySegmentIntersection::Parallel) )); assert!(matches!( (&ray, &right).intersect(), - Some(RaySegmentHit::Parallel) + Some(RaySegmentIntersection::Parallel) )); } } diff --git a/crates/fj-kernel/src/algorithms/triangulate/polygon.rs b/crates/fj-kernel/src/algorithms/triangulate/polygon.rs index 442a6efb3..563512e7e 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::{ algorithms::intersect::{ - ray_segment::RaySegmentHit, HorizontalRayToTheRight, Intersect, + ray_segment::RaySegmentIntersection, HorizontalRayToTheRight, Intersect, }, objects::Surface, }; @@ -172,17 +172,17 @@ impl Polygon { let hit = (&ray, &edge).intersect(); let count_hit = match (hit, previous_hit) { - (Some(RaySegmentHit::Segment), _) => { + (Some(RaySegmentIntersection::Segment), _) => { // We're hitting a segment right-on. Clear case. true } ( - Some(RaySegmentHit::UpperVertex), - Some(RaySegmentHit::LowerVertex), + Some(RaySegmentIntersection::UpperVertex), + Some(RaySegmentIntersection::LowerVertex), ) | ( - Some(RaySegmentHit::LowerVertex), - Some(RaySegmentHit::UpperVertex), + Some(RaySegmentIntersection::LowerVertex), + Some(RaySegmentIntersection::UpperVertex), ) => { // If we're hitting a vertex, only count it if we've hit // the other kind of vertex right before. @@ -199,7 +199,7 @@ impl Polygon { // passing through anything. true } - (Some(RaySegmentHit::Parallel), _) => { + (Some(RaySegmentIntersection::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 From 9e0c54a4689a2937f7a5419765ccdf853c2e934a Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 12 Aug 2022 14:18:47 +0200 Subject: [PATCH 5/7] Update doc comment --- crates/fj-kernel/src/algorithms/intersect/ray_segment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-kernel/src/algorithms/intersect/ray_segment.rs b/crates/fj-kernel/src/algorithms/intersect/ray_segment.rs index 1443d0a30..a864fd12a 100644 --- a/crates/fj-kernel/src/algorithms/intersect/ray_segment.rs +++ b/crates/fj-kernel/src/algorithms/intersect/ray_segment.rs @@ -63,7 +63,7 @@ impl Intersect for (&HorizontalRayToTheRight<2>, &Segment<2>) { } } -/// A hit between a ray and a line segment +/// An intersection between a ray and a line segment #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum RaySegmentIntersection { /// The ray hit the segment itself From 3c784aacd27af2d544da883ca1f6968b49e40902 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 12 Aug 2022 14:47:53 +0200 Subject: [PATCH 6/7] Migrate ray/edge intersection to `intersect` --- .../fj-kernel/src/algorithms/cast_ray/edge.rs | 31 ----------------- .../fj-kernel/src/algorithms/cast_ray/mod.rs | 2 -- .../src/algorithms/intersect/face_point.rs | 6 ++-- .../fj-kernel/src/algorithms/intersect/mod.rs | 1 + .../src/algorithms/intersect/ray_edge.rs | 33 +++++++++++++++++++ 5 files changed, 37 insertions(+), 36 deletions(-) delete mode 100644 crates/fj-kernel/src/algorithms/cast_ray/edge.rs create mode 100644 crates/fj-kernel/src/algorithms/intersect/ray_edge.rs diff --git a/crates/fj-kernel/src/algorithms/cast_ray/edge.rs b/crates/fj-kernel/src/algorithms/cast_ray/edge.rs deleted file mode 100644 index caae1e816..000000000 --- a/crates/fj-kernel/src/algorithms/cast_ray/edge.rs +++ /dev/null @@ -1,31 +0,0 @@ -use fj_math::Segment; - -use crate::{ - algorithms::intersect::{ - ray_segment::RaySegmentIntersection, HorizontalRayToTheRight, Intersect, - }, - objects::{CurveKind, Edge}, -}; - -use super::CastRay; - -impl CastRay<2> for Edge { - type Hit = RaySegmentIntersection; - - fn cast_ray(&self, ray: HorizontalRayToTheRight<2>) -> Option { - let line = match self.curve().kind() { - CurveKind::Line(line) => line, - CurveKind::Circle(_) => { - todo!("Casting rays against circles is not supported yet") - } - }; - - let points = self.vertices().expect_vertices().map(|vertex| { - let point = vertex.position(); - line.point_from_line_coords(point) - }); - let segment = Segment::from_points(points); - - (&ray, &segment).intersect() - } -} diff --git a/crates/fj-kernel/src/algorithms/cast_ray/mod.rs b/crates/fj-kernel/src/algorithms/cast_ray/mod.rs index e51237571..4b7057059 100644 --- a/crates/fj-kernel/src/algorithms/cast_ray/mod.rs +++ b/crates/fj-kernel/src/algorithms/cast_ray/mod.rs @@ -1,7 +1,5 @@ //! Ray casting -mod edge; - use super::intersect::HorizontalRayToTheRight; /// Implemented by types that support ray casting diff --git a/crates/fj-kernel/src/algorithms/intersect/face_point.rs b/crates/fj-kernel/src/algorithms/intersect/face_point.rs index 01193bab1..fdfe5f975 100644 --- a/crates/fj-kernel/src/algorithms/intersect/face_point.rs +++ b/crates/fj-kernel/src/algorithms/intersect/face_point.rs @@ -2,7 +2,7 @@ use fj_math::Point; -use crate::{algorithms::cast_ray::CastRay, objects::Face}; +use crate::objects::Face; use super::{ ray_segment::RaySegmentIntersection, HorizontalRayToTheRight, Intersect, @@ -28,10 +28,10 @@ impl Intersect for (&Face, &Point<2>) { .edges() .last() .copied() - .and_then(|edge| edge.cast_ray(ray)); + .and_then(|edge| (&ray, &edge).intersect()); for edge in cycle.edges() { - let hit = edge.cast_ray(ray); + let hit = (&ray, edge).intersect(); let count_hit = match (hit, previous_hit) { (Some(RaySegmentIntersection::Segment), _) => { diff --git a/crates/fj-kernel/src/algorithms/intersect/mod.rs b/crates/fj-kernel/src/algorithms/intersect/mod.rs index 29b69dc49..b20889f2e 100644 --- a/crates/fj-kernel/src/algorithms/intersect/mod.rs +++ b/crates/fj-kernel/src/algorithms/intersect/mod.rs @@ -1,6 +1,7 @@ //! Intersection algorithms pub mod face_point; +pub mod ray_edge; pub mod ray_segment; mod curve_edge; diff --git a/crates/fj-kernel/src/algorithms/intersect/ray_edge.rs b/crates/fj-kernel/src/algorithms/intersect/ray_edge.rs new file mode 100644 index 000000000..784300f1a --- /dev/null +++ b/crates/fj-kernel/src/algorithms/intersect/ray_edge.rs @@ -0,0 +1,33 @@ +//! Intersection between a ray and an edge in 2D + +use fj_math::Segment; + +use crate::{ + algorithms::intersect::{HorizontalRayToTheRight, Intersect}, + objects::{CurveKind, Edge}, +}; + +use super::ray_segment::RaySegmentIntersection; + +impl Intersect for (&HorizontalRayToTheRight<2>, &Edge) { + type Intersection = RaySegmentIntersection; + + fn intersect(self) -> Option { + let (ray, edge) = self; + + let line = match edge.curve().kind() { + CurveKind::Line(line) => line, + CurveKind::Circle(_) => { + todo!("Casting rays against circles is not supported yet") + } + }; + + let points = edge.vertices().expect_vertices().map(|vertex| { + let point = vertex.position(); + line.point_from_line_coords(point) + }); + let segment = Segment::from_points(points); + + (ray, &segment).intersect() + } +} From 36c55d70a10cb43ff64644eee06f4ba8416176ec Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Fri, 12 Aug 2022 14:48:23 +0200 Subject: [PATCH 7/7] Remove unused code --- .../fj-kernel/src/algorithms/cast_ray/mod.rs | 20 ------------------- crates/fj-kernel/src/algorithms/mod.rs | 1 - 2 files changed, 21 deletions(-) delete mode 100644 crates/fj-kernel/src/algorithms/cast_ray/mod.rs diff --git a/crates/fj-kernel/src/algorithms/cast_ray/mod.rs b/crates/fj-kernel/src/algorithms/cast_ray/mod.rs deleted file mode 100644 index 4b7057059..000000000 --- a/crates/fj-kernel/src/algorithms/cast_ray/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! Ray casting - -use super::intersect::HorizontalRayToTheRight; - -/// Implemented by types that support ray casting -/// -/// # Implementation Note -/// -/// This is basically a more limited version of [`Intersect`]. It probably makes -/// sense to migrate all of this trait's implementations to [`Intersect`] and -/// remove this trait. -/// -/// [`Intersect`]: super::intersect::Intersect -pub trait CastRay { - /// The type that describes a hit of the ray on the implementing type - type Hit; - - /// Cast a ray against `self` - fn cast_ray(&self, ray: HorizontalRayToTheRight) -> Option; -} diff --git a/crates/fj-kernel/src/algorithms/mod.rs b/crates/fj-kernel/src/algorithms/mod.rs index 98c7a549e..b7f7b63ce 100644 --- a/crates/fj-kernel/src/algorithms/mod.rs +++ b/crates/fj-kernel/src/algorithms/mod.rs @@ -9,7 +9,6 @@ mod sweep; mod transform; mod triangulate; -pub mod cast_ray; pub mod intersect; pub use self::{