-
-
Notifications
You must be signed in to change notification settings - Fork 119
/
cycle.rs
83 lines (73 loc) · 2.27 KB
/
cycle.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use fj_math::Point;
use itertools::Itertools;
use crate::{
geometry::curve::Curve,
insert::Insert,
objects::{Cycle, HalfEdge, Objects},
services::Service,
storage::Handle,
};
use super::HalfEdgeBuilder;
/// Builder API for [`Cycle`]
#[derive(Default)]
pub struct CycleBuilder {
half_edges: Vec<HalfEdgeBuilder>,
}
impl CycleBuilder {
/// Create an instance of `CycleBuilder`
pub fn new() -> Self {
Self::default()
}
/// Add a half-edge to the cycle
pub fn add_half_edge(mut self, half_edge: HalfEdgeBuilder) -> Self {
self.half_edges.push(half_edge);
self
}
/// Create a cycle whose half-edges are connected to the provided half-edges
///
/// The half-edges of the new circle will be coincident with the provided
/// half-edges, but will point in the opposite direction.
///
/// Assumes that the provided half-edges, once translated into local
/// equivalents of this cycle, form a cycle themselves.
pub fn connect_to_edges<Es>(edges: Es) -> Self
where
Es: IntoIterator<Item = (Handle<HalfEdge>, Curve, [Point<1>; 2])>,
Es::IntoIter: Clone + ExactSizeIterator,
{
let half_edges = edges
.into_iter()
.circular_tuple_windows()
.map(|((prev, _, _), (_, curve, boundary))| {
HalfEdgeBuilder::new(curve, boundary)
.with_start_vertex(prev.start_vertex().clone())
})
.collect();
Self { half_edges }
}
/// Create a polygon
pub fn polygon<P, Ps>(points: Ps) -> Self
where
P: Into<Point<2>>,
Ps: IntoIterator<Item = P>,
Ps::IntoIter: Clone + ExactSizeIterator,
{
let half_edges = points
.into_iter()
.map(Into::into)
.circular_tuple_windows()
.map(|(start, end)| {
HalfEdgeBuilder::line_segment([start, end], None)
})
.collect();
Self { half_edges }
}
/// Build the cycle
pub fn build(self, objects: &mut Service<Objects>) -> Cycle {
let half_edges = self
.half_edges
.into_iter()
.map(|half_edge| half_edge.build(objects).insert(objects));
Cycle::new(half_edges)
}
}