mirror of
https://github.com/hannobraun/Fornjot
synced 2025-08-12 20:26:08 +00:00
Merge pull request #1996 from hannobraun/approx
Refactor edge/curve representation
This commit is contained in:
commit
b42ad3dc07
5
crates/fj-core/src/algorithms/approx/curve.rs
Normal file
5
crates/fj-core/src/algorithms/approx/curve.rs
Normal file
@ -0,0 +1,5 @@
|
||||
//! Curve approximation
|
||||
|
||||
mod segment;
|
||||
|
||||
pub use self::segment::CurveApproxSegment;
|
50
crates/fj-core/src/algorithms/approx/curve/segment.rs
Normal file
50
crates/fj-core/src/algorithms/approx/curve/segment.rs
Normal file
@ -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<Point<1>>,
|
||||
|
||||
/// The points that approximate the curve segment
|
||||
pub points: Vec<ApproxPoint<1>>,
|
||||
}
|
||||
|
||||
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<cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
@ -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<Point<1>>,
|
||||
tolerance: impl Into<Tolerance>,
|
||||
) -> 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<GlobalEdge>, CurveBoundary<Point<1>>),
|
||||
GlobalEdgeApprox,
|
||||
CurveApproxSegment,
|
||||
>,
|
||||
vertex_approx: BTreeMap<HandleWrapper<Vertex>, Point<3>>,
|
||||
}
|
||||
@ -235,7 +235,7 @@ impl EdgeCache {
|
||||
&self,
|
||||
handle: Handle<GlobalEdge>,
|
||||
boundary: CurveBoundary<Point<1>>,
|
||||
) -> Option<GlobalEdgeApprox> {
|
||||
) -> Option<CurveApproxSegment> {
|
||||
if let Some(approx) =
|
||||
self.edge_approx.get(&(handle.clone().into(), boundary))
|
||||
{
|
||||
@ -257,8 +257,8 @@ impl EdgeCache {
|
||||
&mut self,
|
||||
handle: Handle<GlobalEdge>,
|
||||
boundary: CurveBoundary<Point<1>>,
|
||||
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<ApproxPoint<1>>,
|
||||
}
|
||||
|
||||
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};
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! Approximation of objects
|
||||
|
||||
pub mod curve;
|
||||
pub mod cycle;
|
||||
pub mod edge;
|
||||
pub mod face;
|
||||
|
Loading…
x
Reference in New Issue
Block a user