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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use fj_interop::ext::ArrayExt;
use fj_math::{Arc, Point, Scalar};
use crate::{
geometry::curve::Curve,
insert::Insert,
objects::{GlobalEdge, HalfEdge, Objects, Vertex},
services::Service,
storage::Handle,
};
pub struct HalfEdgeBuilder {
curve: Curve,
boundary: [Point<1>; 2],
start_vertex: Option<Handle<Vertex>>,
global_form: Option<Handle<GlobalEdge>>,
}
impl HalfEdgeBuilder {
pub fn new(curve: Curve, boundary: [Point<1>; 2]) -> Self {
Self {
curve,
boundary,
start_vertex: None,
global_form: None,
}
}
pub fn arc(
start: impl Into<Point<2>>,
end: impl Into<Point<2>>,
angle_rad: impl Into<Scalar>,
) -> Self {
let angle_rad = angle_rad.into();
if angle_rad <= -Scalar::TAU || angle_rad >= Scalar::TAU {
panic!("arc angle must be in the range (-2pi, 2pi) radians");
}
let arc = Arc::from_endpoints_and_angle(start, end, angle_rad);
let curve =
Curve::circle_from_center_and_radius(arc.center, arc.radius);
let boundary =
[arc.start_angle, arc.end_angle].map(|coord| Point::from([coord]));
Self::new(curve, boundary)
}
pub fn circle(radius: impl Into<Scalar>) -> Self {
let curve = Curve::circle_from_radius(radius);
let boundary =
[Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));
Self::new(curve, boundary)
}
pub fn line_segment(
points_surface: [impl Into<Point<2>>; 2],
boundary: Option<[Point<1>; 2]>,
) -> Self {
let boundary =
boundary.unwrap_or_else(|| [[0.], [1.]].map(Point::from));
let curve = Curve::line_from_points_with_coords(
boundary.zip_ext(points_surface),
);
Self::new(curve, boundary)
}
pub fn with_start_vertex(mut self, start_vertex: Handle<Vertex>) -> Self {
self.start_vertex = Some(start_vertex);
self
}
pub fn with_global_form(mut self, global_form: Handle<GlobalEdge>) -> Self {
self.global_form = Some(global_form);
self
}
pub fn build(self, objects: &mut Service<Objects>) -> HalfEdge {
HalfEdge::new(
self.curve,
self.boundary,
self.start_vertex
.unwrap_or_else(|| Vertex::new().insert(objects)),
self.global_form
.unwrap_or_else(|| GlobalEdge::new().insert(objects)),
)
}
}