fj_core/algorithms/approx/
cycle.rs1use fj_math::Segment;
6
7use crate::{geometry::SurfaceGeometry, objects::Cycle, Core};
8
9use super::{
10 edge::{HalfEdgeApprox, HalfEdgeApproxCache},
11 Approx, ApproxPoint, Tolerance,
12};
13
14impl Approx for (&Cycle, &SurfaceGeometry) {
15 type Approximation = CycleApprox;
16 type Cache = HalfEdgeApproxCache;
17
18 fn approx_with_cache(
19 self,
20 tolerance: impl Into<Tolerance>,
21 cache: &mut Self::Cache,
22 core: &mut Core,
23 ) -> Self::Approximation {
24 let (cycle, surface) = self;
25 let tolerance = tolerance.into();
26
27 let half_edges = cycle
28 .half_edges()
29 .iter()
30 .map(|half_edge| {
31 (half_edge, surface).approx_with_cache(tolerance, cache, core)
32 })
33 .collect();
34
35 CycleApprox { half_edges }
36 }
37}
38
39#[derive(Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
41pub struct CycleApprox {
42 pub half_edges: Vec<HalfEdgeApprox>,
44}
45
46impl CycleApprox {
47 pub fn points(&self) -> Vec<ApproxPoint<2>> {
49 let mut points = Vec::new();
50
51 for approx in &self.half_edges {
52 points.extend(approx.points.iter().copied());
53 }
54
55 if let Some(point) = points.first() {
56 points.push(*point);
57 }
58
59 points
60 }
61
62 pub fn segments(&self) -> Vec<Segment<3>> {
64 let mut segments = Vec::new();
65
66 for segment in self.points().windows(2) {
67 let segment = [&segment[0], &segment[1]];
70
71 segments
72 .push(Segment::from(segment.map(|point| point.global_form)));
73 }
74
75 segments
76 }
77}