diff --git a/crates/fj-core/src/algorithms/approx/curve/segment.rs b/crates/fj-core/src/algorithms/approx/curve/segment.rs index 631a8923d..171a31ec0 100644 --- a/crates/fj-core/src/algorithms/approx/curve/segment.rs +++ b/crates/fj-core/src/algorithms/approx/curve/segment.rs @@ -99,13 +99,7 @@ impl CurveApproxSegment { ); assert!(other.is_normalized(), "Can't merge non-normalized segment."); - let [self_min, self_max] = self.boundary.inner; - let [other_min, other_max] = other.boundary.inner; - - let min = cmp::min(self_min, other_min); - let max = cmp::max(self_max, other_max); - - self.boundary.inner = [min, max]; + self.boundary = self.boundary.union(other.boundary); self.points.retain(|point| { // Only retain points that don't overlap with the other segment, or diff --git a/crates/fj-core/src/geometry/boundary.rs b/crates/fj-core/src/geometry/boundary.rs index d86a4eb84..7580e0b71 100644 --- a/crates/fj-core/src/geometry/boundary.rs +++ b/crates/fj-core/src/geometry/boundary.rs @@ -98,6 +98,32 @@ impl CurveBoundary> { Self { inner: [min, max] } } + + /// Create the union of this boundary and another + /// + /// The result will be normalized. + /// + /// # Panics + /// + /// Panics, if the two boundaries don't overlap (touching counts as + /// overlapping). + pub fn union(self, other: Self) -> Self { + let self_ = self.normalize(); + let other = other.normalize(); + + assert!( + self.overlaps(&other), + "Can't merge boundaries that don't at least touch" + ); + + let [self_min, self_max] = self_.inner; + let [other_min, other_max] = other.inner; + + let min = cmp::min(self_min, other_min); + let max = cmp::max(self_max, other_max); + + Self { inner: [min, max] } + } } impl From<[S; 2]> for CurveBoundary