truck_geometry/specifieds/
plane.rs1use super::*;
2
3impl Plane {
4 #[inline(always)]
6 pub const fn new(origin: Point3, one: Point3, another: Point3) -> Plane {
7 Plane {
8 o: origin,
9 p: one,
10 q: another,
11 }
12 }
13 #[inline(always)]
15 pub const fn origin(&self) -> Point3 { self.o }
16 #[inline(always)]
18 pub fn u_axis(&self) -> Vector3 { self.p - self.o }
19 #[inline(always)]
21 pub fn v_axis(&self) -> Vector3 { self.q - self.o }
22 #[inline(always)]
34 pub fn normal(&self) -> Vector3 { self.u_axis().cross(self.v_axis()).normalize() }
35 #[inline(always)]
54 pub fn get_parameter(&self, pt: Point3) -> Vector3 {
55 let a = self.u_axis();
56 let b = self.v_axis();
57 let c = self.normal();
58 let mat = Matrix3::from_cols(a, b, c).invert().unwrap();
59 mat * (pt - self.o)
60 }
61 #[inline(always)]
84 pub fn into_bspline(&self) -> BSplineSurface<Point3> {
85 let o = self.o;
86 let p = self.p;
87 let q = self.q;
88 BSplineSurface::debug_new(
89 (KnotVec::bezier_knot(1), KnotVec::bezier_knot(1)),
90 vec![vec![o, q], vec![p, p + (q - o)]],
91 )
92 }
93 #[inline(always)]
116 pub fn into_nurbs(&self) -> NurbsSurface<Vector4> {
117 let o = self.o.to_homogeneous();
118 let p = self.p.to_homogeneous();
119 let q = self.q.to_homogeneous();
120 NurbsSurface::new(BSplineSurface::debug_new(
121 (KnotVec::bezier_knot(1), KnotVec::bezier_knot(1)),
122 vec![vec![o, q], vec![p, p + q - o]],
123 ))
124 }
125}
126
127impl ParametricSurface for Plane {
128 type Point = Point3;
129 type Vector = Vector3;
130 #[inline(always)]
131 fn subs(&self, u: f64, v: f64) -> Point3 {
132 self.o + u * (self.p - self.o) + v * (self.q - self.o)
133 }
134 #[inline(always)]
135 fn uder(&self, _: f64, _: f64) -> Vector3 { self.p - self.o }
136 #[inline(always)]
137 fn vder(&self, _: f64, _: f64) -> Vector3 { self.q - self.o }
138 #[inline(always)]
139 fn uuder(&self, _: f64, _: f64) -> Vector3 { Vector3::zero() }
140 #[inline(always)]
141 fn uvder(&self, _: f64, _: f64) -> Vector3 { Vector3::zero() }
142 #[inline(always)]
143 fn vvder(&self, _: f64, _: f64) -> Vector3 { Vector3::zero() }
144 #[inline(always)]
146 fn parameter_range(&self) -> (ParameterRange, ParameterRange) {
147 let range = (Bound::Included(0.0), Bound::Included(1.0));
148 (range, range)
149 }
150}
151
152impl ParametricSurface3D for Plane {
153 #[inline(always)]
154 fn normal(&self, _: f64, _: f64) -> Vector3 { self.normal() }
155}
156
157impl BoundedSurface for Plane {}
158
159impl Invertible for Plane {
160 #[inline(always)]
161 fn inverse(&self) -> Self {
162 Plane {
163 o: self.o,
164 p: self.q,
165 q: self.p,
166 }
167 }
168 #[inline(always)]
169 fn invert(&mut self) { *self = self.inverse(); }
170}
171
172impl IncludeCurve<BSplineCurve<Point3>> for Plane {
173 #[inline(always)]
174 fn include(&self, curve: &BSplineCurve<Point3>) -> bool {
175 let origin = self.origin();
176 let normal = self.normal();
177 curve
178 .control_points()
179 .iter()
180 .all(|pt| (pt - origin).dot(normal).so_small())
181 }
182}
183
184impl IncludeCurve<NurbsCurve<Vector4>> for Plane {
185 fn include(&self, curve: &NurbsCurve<Vector4>) -> bool {
186 let origin = self.origin();
187 let normal = self.normal();
188 let (s, e) = (curve.front(), curve.back());
189 if !(s - origin).dot(normal).so_small() || !(e - origin).dot(normal).so_small() {
190 return false;
191 }
192 curve.non_rationalized().control_points().iter().all(|pt| {
193 if pt[3].so_small() {
194 true
195 } else {
196 let pt = Point3::from_homogeneous(*pt);
197 (pt - origin).dot(normal).so_small()
198 }
199 })
200 }
201}
202
203impl ParameterDivision2D for Plane {
204 #[inline(always)]
205 fn parameter_division(&self, range: ((f64, f64), (f64, f64)), _: f64) -> (Vec<f64>, Vec<f64>) {
206 (vec![range.0 .0, range.0 .1], vec![range.1 .0, range.1 .1])
207 }
208}
209
210impl<T: Transform3<Scalar = f64>> Transformed<T> for Plane {
211 #[inline(always)]
212 fn transform_by(&mut self, trans: T) {
213 self.o = trans.transform_point(self.o);
214 self.p = trans.transform_point(self.p);
215 self.q = trans.transform_point(self.q);
216 }
217 #[inline(always)]
218 fn transformed(&self, trans: T) -> Self {
219 Plane {
220 o: trans.transform_point(self.o),
221 p: trans.transform_point(self.p),
222 q: trans.transform_point(self.q),
223 }
224 }
225}
226
227impl SearchParameter<D2> for Plane {
228 type Point = Point3;
229 #[inline(always)]
230 fn search_parameter<H: Into<SPHint2D>>(
231 &self,
232 point: Point3,
233 _: H,
234 _: usize,
235 ) -> Option<(f64, f64)> {
236 let v = self.get_parameter(point);
237 match v[2].so_small() {
238 true => Some((v[0], v[1])),
239 false => None,
240 }
241 }
242}
243
244impl SearchNearestParameter<D2> for Plane {
245 type Point = Point3;
246 #[inline(always)]
247 fn search_nearest_parameter<H: Into<SPHint2D>>(
248 &self,
249 point: Point3,
250 _: H,
251 _: usize,
252 ) -> Option<(f64, f64)> {
253 let v = self.get_parameter(point);
254 Some((v[0], v[1]))
255 }
256}