fj_kernel/operations/build/
edge.rs1use fj_interop::ext::ArrayExt;
2use fj_math::{Arc, Point, Scalar};
3
4use crate::{
5 geometry::curve::Curve,
6 objects::{GlobalEdge, HalfEdge, Surface, Vertex},
7 operations::Insert,
8 services::Services,
9};
10
11pub trait BuildHalfEdge {
13 fn unjoined(
15 curve: Curve,
16 boundary: [Point<1>; 2],
17 services: &mut Services,
18 ) -> HalfEdge {
19 let start_vertex = Vertex::new().insert(services);
20 let global_form = GlobalEdge::new().insert(services);
21
22 HalfEdge::new(curve, boundary, start_vertex, global_form)
23 }
24
25 fn arc(
31 start: impl Into<Point<2>>,
32 end: impl Into<Point<2>>,
33 angle_rad: impl Into<Scalar>,
34 services: &mut Services,
35 ) -> HalfEdge {
36 let angle_rad = angle_rad.into();
37 if angle_rad <= -Scalar::TAU || angle_rad >= Scalar::TAU {
38 panic!("arc angle must be in the range (-2pi, 2pi) radians");
39 }
40
41 let arc = Arc::from_endpoints_and_angle(start, end, angle_rad);
42
43 let curve =
44 Curve::circle_from_center_and_radius(arc.center, arc.radius);
45 let boundary =
46 [arc.start_angle, arc.end_angle].map(|coord| Point::from([coord]));
47
48 HalfEdge::unjoined(curve, boundary, services)
49 }
50
51 fn circle(radius: impl Into<Scalar>, services: &mut Services) -> HalfEdge {
53 let curve = Curve::circle_from_radius(radius);
54 let boundary =
55 [Scalar::ZERO, Scalar::TAU].map(|coord| Point::from([coord]));
56
57 HalfEdge::unjoined(curve, boundary, services)
58 }
59
60 fn line_segment(
62 points_surface: [impl Into<Point<2>>; 2],
63 boundary: Option<[Point<1>; 2]>,
64 services: &mut Services,
65 ) -> HalfEdge {
66 let boundary =
67 boundary.unwrap_or_else(|| [[0.], [1.]].map(Point::from));
68 let curve = Curve::line_from_points_with_coords(
69 boundary.zip_ext(points_surface),
70 );
71
72 HalfEdge::unjoined(curve, boundary, services)
73 }
74
75 fn line_segment_from_global_points(
77 points_global: [impl Into<Point<3>>; 2],
78 surface: &Surface,
79 boundary: Option<[Point<1>; 2]>,
80 services: &mut Services,
81 ) -> HalfEdge {
82 let points_surface = points_global
83 .map(|point| surface.geometry().project_global_point(point));
84 HalfEdge::line_segment(points_surface, boundary, services)
85 }
86}
87
88impl BuildHalfEdge for HalfEdge {}