1use fj_math::{Circle, Line, Point, Scalar, Transform, Vector};
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
9pub enum SurfacePath {
10 Circle(Circle<2>),
12
13 Line(Line<2>),
15}
16
17impl SurfacePath {
18 pub fn circle_from_center_and_radius(
20 center: impl Into<Point<2>>,
21 radius: impl Into<Scalar>,
22 ) -> Self {
23 Self::Circle(Circle::from_center_and_radius(center, radius))
24 }
25
26 pub fn u_axis() -> Self {
28 let a = Point::origin();
29 let b = a + Vector::unit_u();
30
31 let (self_, _) = Self::line_from_points([a, b]);
32 self_
33 }
34
35 pub fn v_axis() -> Self {
37 let a = Point::origin();
38 let b = a + Vector::unit_v();
39
40 let (self_, _) = Self::line_from_points([a, b]);
41 self_
42 }
43
44 pub fn line_from_points(
48 points: [impl Into<Point<2>>; 2],
49 ) -> (Self, [Point<1>; 2]) {
50 let (line, coords) = Line::from_points(points);
51 (Self::Line(line), coords)
52 }
53
54 pub fn line_from_points_with_coords(
56 points: [(impl Into<Point<1>>, impl Into<Point<2>>); 2],
57 ) -> Self {
58 Self::Line(Line::from_points_with_line_coords(points))
59 }
60
61 pub fn point_from_path_coords(
63 &self,
64 point: impl Into<Point<1>>,
65 ) -> Point<2> {
66 match self {
67 Self::Circle(circle) => circle.point_from_circle_coords(point),
68 Self::Line(line) => line.point_from_line_coords(point),
69 }
70 }
71
72 #[must_use]
74 pub fn reverse(self) -> Self {
75 match self {
76 Self::Circle(circle) => Self::Circle(circle.reverse()),
77 Self::Line(line) => Self::Line(line.reverse()),
78 }
79 }
80}
81
82#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
84pub enum GlobalPath {
85 Circle(Circle<3>),
87
88 Line(Line<3>),
90}
91
92impl GlobalPath {
93 pub fn x_axis() -> Self {
95 Self::Line(Line::from_origin_and_direction(
96 Point::origin(),
97 Vector::unit_x(),
98 ))
99 }
100
101 pub fn y_axis() -> Self {
103 Self::Line(Line::from_origin_and_direction(
104 Point::origin(),
105 Vector::unit_y(),
106 ))
107 }
108
109 pub fn z_axis() -> Self {
111 Self::Line(Line::from_origin_and_direction(
112 Point::origin(),
113 Vector::unit_z(),
114 ))
115 }
116
117 pub fn circle_from_radius(radius: impl Into<Scalar>) -> Self {
119 let radius = radius.into();
120
121 Self::Circle(Circle::from_center_and_radius(Point::origin(), radius))
122 }
123
124 pub fn line_from_points(
128 points: [impl Into<Point<3>>; 2],
129 ) -> (Self, [Point<1>; 2]) {
130 let (line, coords) = Line::from_points(points);
131 (Self::Line(line), coords)
132 }
133
134 pub fn origin(&self) -> Point<3> {
136 match self {
137 Self::Circle(circle) => circle.center() + circle.a(),
138 Self::Line(line) => line.origin(),
139 }
140 }
141
142 pub fn point_from_path_coords(
144 &self,
145 point: impl Into<Point<1>>,
146 ) -> Point<3> {
147 match self {
148 Self::Circle(circle) => circle.point_from_circle_coords(point),
149 Self::Line(line) => line.point_from_line_coords(point),
150 }
151 }
152
153 pub fn vector_from_path_coords(
155 &self,
156 vector: impl Into<Vector<1>>,
157 ) -> Vector<3> {
158 match self {
159 Self::Circle(circle) => circle.vector_from_circle_coords(vector),
160 Self::Line(line) => line.vector_from_line_coords(vector),
161 }
162 }
163
164 #[must_use]
166 pub fn transform(self, transform: &Transform) -> Self {
167 match self {
168 Self::Circle(curve) => {
169 Self::Circle(transform.transform_circle(&curve))
170 }
171 Self::Line(curve) => Self::Line(transform.transform_line(&curve)),
172 }
173 }
174}