diff --git a/crates/fj-core/src/algorithms/approx/curve.rs b/crates/fj-core/src/algorithms/approx/curve.rs new file mode 100644 index 000000000..b80419791 --- /dev/null +++ b/crates/fj-core/src/algorithms/approx/curve.rs @@ -0,0 +1,5 @@ +//! Curve approximation + +mod segment; + +pub use self::segment::CurveApproxSegment; diff --git a/crates/fj-core/src/algorithms/approx/curve/segment.rs b/crates/fj-core/src/algorithms/approx/curve/segment.rs new file mode 100644 index 000000000..d0d8fcb05 --- /dev/null +++ b/crates/fj-core/src/algorithms/approx/curve/segment.rs @@ -0,0 +1,50 @@ +use std::cmp; + +use fj_math::Point; + +use crate::{algorithms::approx::ApproxPoint, geometry::CurveBoundary}; + +/// A segment of a curve approximation +/// +/// A curve is potentially infinite (at least its local coordinate space is +/// infinite, even if the curve itself isn't; a circle is an example of that). +/// This means a curve can only be approximated locally, at a number of +/// segments. This struct represents on such segment. +#[derive(Clone, Debug, Eq, PartialEq, Hash)] +pub struct CurveApproxSegment { + /// The boundary within which this segment approximates the curve + pub boundary: CurveBoundary>, + + /// The points that approximate the curve segment + pub points: Vec>, +} + +impl CurveApproxSegment { + /// Reverse the orientation of the approximation + #[must_use] + pub fn reverse(mut self) -> Self { + self.boundary = self.boundary.reverse(); + self.points.reverse(); + self + } +} + +impl Ord for CurveApproxSegment { + fn cmp(&self, other: &Self) -> cmp::Ordering { + let [a_start, a_end] = self.boundary.inner; + let [b_start, b_end] = other.boundary.inner; + + let by_start = a_start.cmp(&b_start); + if by_start.is_ne() { + return by_start; + } + + a_end.cmp(&b_end) + } +} + +impl PartialOrd for CurveApproxSegment { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} diff --git a/crates/fj-core/src/algorithms/approx/edge.rs b/crates/fj-core/src/algorithms/approx/edge.rs index a66d02e78..4f1030f3a 100644 --- a/crates/fj-core/src/algorithms/approx/edge.rs +++ b/crates/fj-core/src/algorithms/approx/edge.rs @@ -15,7 +15,7 @@ use crate::{ storage::{Handle, HandleWrapper}, }; -use super::{Approx, ApproxPoint, Tolerance}; +use super::{curve::CurveApproxSegment, Approx, ApproxPoint, Tolerance}; impl Approx for (&HalfEdge, &Surface) { type Approximation = HalfEdgeApprox; @@ -143,7 +143,7 @@ fn approx_edge( surface: &Surface, boundary: CurveBoundary>, tolerance: impl Into, -) -> GlobalEdgeApprox { +) -> CurveApproxSegment { // There are different cases of varying complexity. Circles are the hard // part here, as they need to be approximated, while lines don't need to be. // @@ -211,7 +211,7 @@ fn approx_edge( ApproxPoint::new(point_curve, point_global) }) .collect(); - GlobalEdgeApprox { points } + CurveApproxSegment { boundary, points } } /// A cache for results of an approximation @@ -219,7 +219,7 @@ fn approx_edge( pub struct EdgeCache { edge_approx: BTreeMap< (HandleWrapper, CurveBoundary>), - GlobalEdgeApprox, + CurveApproxSegment, >, vertex_approx: BTreeMap, Point<3>>, } @@ -235,7 +235,7 @@ impl EdgeCache { &self, handle: Handle, boundary: CurveBoundary>, - ) -> Option { + ) -> Option { if let Some(approx) = self.edge_approx.get(&(handle.clone().into(), boundary)) { @@ -257,8 +257,8 @@ impl EdgeCache { &mut self, handle: Handle, boundary: CurveBoundary>, - approx: GlobalEdgeApprox, - ) -> GlobalEdgeApprox { + approx: CurveApproxSegment, + ) -> CurveApproxSegment { self.edge_approx .insert((handle.into(), boundary), approx.clone()) .unwrap_or(approx) @@ -279,21 +279,6 @@ impl EdgeCache { } } -/// An approximation of a [`GlobalEdge`] -#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)] -struct GlobalEdgeApprox { - /// The points that approximate the edge - points: Vec>, -} - -impl GlobalEdgeApprox { - /// Reverse the order of the approximation - fn reverse(mut self) -> Self { - self.points.reverse(); - self - } -} - #[cfg(test)] mod tests { use std::{f64::consts::TAU, ops::Deref}; diff --git a/crates/fj-core/src/algorithms/approx/mod.rs b/crates/fj-core/src/algorithms/approx/mod.rs index 7899320ea..236dfe751 100644 --- a/crates/fj-core/src/algorithms/approx/mod.rs +++ b/crates/fj-core/src/algorithms/approx/mod.rs @@ -1,5 +1,6 @@ //! Approximation of objects +pub mod curve; pub mod cycle; pub mod edge; pub mod face;