vox_geometry_rust/point2.rs
1/*
2 * // Copyright (c) 2021 Feng Yang
3 * //
4 * // I am making my contributions/submissions to this project solely in my
5 * // personal capacity and am not conveying any rights to any intellectual
6 * // property of any third parties.
7 */
8
9use num::Float;
10use std::ops::{Index, IndexMut, AddAssign, SubAssign, MulAssign, DivAssign, Add, Neg, Sub, Mul, Div};
11use std::fmt::{Debug, Formatter, Result};
12
13///
14/// # 2-D point class.
15///
16/// This class defines simple 2-D point data.
17///
18/// - tparam T - Type of the element
19///
20pub struct Point2<T: Float> {
21 /// X (or the first) component of the point.
22 pub x: T,
23
24 /// Y (or the second) component of the point.
25 pub y: T,
26}
27
28/// Float-type 2D point.
29pub type Point2F = Point2<f32>;
30/// Double-type 2D point.
31pub type Point2D = Point2<f64>;
32
33/// # Constructors
34impl<T: Float> Point2<T> {
35 /// Constructs default point (0, 0).
36 /// ```
37 /// use vox_geometry_rust::point2::Point2F;
38 /// let vec = Point2F::new_default();
39 /// assert_eq!(0.0, vec.x);
40 /// assert_eq!(0.0, vec.y);
41 /// ```
42 pub fn new_default() -> Point2<T> {
43 return Point2 {
44 x: T::zero(),
45 y: T::zero(),
46 };
47 }
48
49 /// Constructs point with given parameters \p x_ and \p y_.
50 /// ```
51 /// use vox_geometry_rust::point2::Point2F;
52 /// let vec2 = Point2F::new(5.0, 3.0);
53 /// assert_eq!(5.0, vec2.x);
54 /// assert_eq!(3.0, vec2.y);
55 /// ```
56 pub fn new(x_: T, y_: T) -> Point2<T> {
57 return Point2 {
58 x: x_,
59 y: y_,
60 };
61 }
62
63 /// Constructs point with initializer list.
64 /// ```
65 /// use vox_geometry_rust::point2::Point2F;
66 /// let vec5 = Point2F::new_lst([7.0, 6.0]);
67 /// assert_eq!(7.0, vec5.x);
68 /// assert_eq!(6.0, vec5.y);
69 /// ```
70 pub fn new_lst(lst: [T; 2]) -> Point2<T> {
71 return Point2 {
72 x: lst[0],
73 y: lst[1],
74 };
75 }
76}
77
78/// # Basic setters
79impl<T: Float> Point2<T> {
80 /// Set both x and y components to **s**.
81 pub fn set_scalar(&mut self, s: T) {
82 self.x = s;
83 self.y = s;
84 }
85
86 /// Set x and y components with given parameters.
87 /// ```
88 /// use vox_geometry_rust::point2::Point2F;
89 /// let mut vec = Point2F::new_default();
90 /// vec.set_scalar2(4.0, 2.0);
91 /// assert_eq!(4.0, vec.x);
92 /// assert_eq!(2.0, vec.y);
93 /// ```
94 pub fn set_scalar2(&mut self, x: T, y: T) {
95 self.x = x;
96 self.y = y;
97 }
98
99 /// Set x and y components with given initializer list.
100 /// ```
101 /// use vox_geometry_rust::point2::Point2F;
102 /// let mut vec = Point2F::new_default();
103 /// let lst = [0.0, 5.0];
104 /// vec.set_lst(lst);
105 /// assert_eq!(0.0, vec.x);
106 /// assert_eq!(5.0, vec.y);
107 /// ```
108 pub fn set_lst(&mut self, lst: [T; 2]) {
109 self.x = lst[0];
110 self.y = lst[1];
111 }
112
113 /// Set x and y with other point **pt**.
114 /// ```
115 /// use vox_geometry_rust::point2::Point2F;
116 /// let mut vec = Point2F::new_default();
117 /// vec.set_self(Point2F::new(9.0, 8.0));
118 /// assert_eq!(9.0, vec.x);
119 /// assert_eq!(8.0, vec.y);
120 /// ```
121 pub fn set_self(&mut self, pt: Point2<T>) {
122 self.x = pt.x;
123 self.y = pt.y;
124 }
125
126 /// Set both x and y to zero.
127 /// ```
128 /// use vox_geometry_rust::point2::Point2F;
129 /// let mut vec = Point2F::new(3.0, 9.0);
130 /// vec.set_zero();
131 /// assert_eq!(0.0, vec.x);
132 /// assert_eq!(0.0, vec.y);
133 /// ```
134 pub fn set_zero(&mut self) {
135 self.x = T::zero();
136 self.y = T::zero();
137 }
138}
139
140/// # Binary operations: new instance = this (+) v
141impl<T: Float> Point2<T> {
142 /// Computes self + (v, v).
143 /// ```
144 /// use vox_geometry_rust::point2::Point2F;
145 /// let mut vec = Point2F::new(3.0, 9.0);
146 /// vec = vec.add_scalar(4.0);
147 /// assert_eq!(7.0, vec.x);
148 /// assert_eq!(13.0, vec.y);
149 /// ```
150 pub fn add_scalar(&self, v: T) -> Point2<T> {
151 return Point2::new(self.x + v, self.y + v);
152 }
153
154 /// Computes self + (v.x, v.y).
155 /// ```
156 /// use vox_geometry_rust::point2::Point2F;
157 /// let mut vec = Point2F::new(3.0, 9.0);
158 /// vec = vec.add_scalar(4.0);
159 /// vec = vec.add_vec(Point2F::new(-2.0, 1.0));
160 /// assert_eq!(5.0, vec.x);
161 /// assert_eq!(14.0, vec.y);
162 /// ```
163 pub fn add_vec(&self, v: Point2<T>) -> Point2<T> {
164 return Point2::new(self.x + v.x, self.y + v.y);
165 }
166
167 /// Computes self - (v, v).
168 /// ```
169 /// use vox_geometry_rust::point2::Point2F;
170 /// let mut vec = Point2F::new(3.0, 9.0);
171 /// vec = vec.add_scalar(4.0);
172 /// vec = vec.add_vec(Point2F::new(-2.0, 1.0));
173 /// vec = vec.sub_scalar(8.0);
174 /// assert_eq!(-3.0, vec.x);
175 /// assert_eq!(6.0, vec.y);
176 /// ```
177 pub fn sub_scalar(&self, v: T) -> Point2<T> {
178 return Point2::new(self.x - v, self.y - v);
179 }
180
181 /// Computes self - (v.x, v.y).
182 /// ```
183 /// use vox_geometry_rust::point2::Point2F;
184 /// let mut vec = Point2F::new(3.0, 9.0);
185 /// vec = vec.add_scalar(4.0);
186 /// vec = vec.add_vec(Point2F::new(-2.0, 1.0));
187 /// vec = vec.sub_scalar(8.0);
188 /// vec = vec.sub_vec(Point2F::new(-5.0, 3.0));
189 /// assert_eq!(2.0, vec.x);
190 /// assert_eq!(3.0, vec.y);
191 /// ```
192 pub fn sub_vec(&self, v: Point2<T>) -> Point2<T> {
193 return Point2::new(self.x - v.x, self.y - v.y);
194 }
195
196 /// Computes self * (v, v).
197 /// ```
198 /// use vox_geometry_rust::point2::Point2F;
199 /// let mut vec = Point2F::new(3.0, 9.0);
200 /// vec = vec.add_scalar(4.0);
201 /// vec = vec.add_vec(Point2F::new(-2.0, 1.0));
202 /// vec = vec.sub_scalar(8.0);
203 /// vec = vec.sub_vec(Point2F::new(-5.0, 3.0));
204 /// vec = vec.mul_scalar(2.0);
205 /// assert_eq!(4.0, vec.x);
206 /// assert_eq!(6.0, vec.y);
207 /// ```
208 pub fn mul_scalar(&self, v: T) -> Point2<T> {
209 return Point2::new(self.x * v, self.y * v);
210 }
211
212 /// Computes self * (v.x, v.y).
213 /// ```
214 /// use vox_geometry_rust::point2::Point2F;
215 /// let mut vec = Point2F::new(3.0, 9.0);
216 /// vec = vec.add_scalar(4.0);
217 /// vec = vec.add_vec(Point2F::new(-2.0, 1.0));
218 /// vec = vec.sub_scalar(8.0);
219 /// vec = vec.sub_vec(Point2F::new(-5.0, 3.0));
220 /// vec = vec.mul_scalar(2.0);
221 /// vec = vec.mul_vec(Point2F::new(3.0, -2.0));
222 /// assert_eq!(12.0, vec.x);
223 /// assert_eq!(-12.0, vec.y);
224 /// ```
225 pub fn mul_vec(&self, v: Point2<T>) -> Point2<T> {
226 return Point2::new(self.x * v.x, self.y * v.y);
227 }
228
229 /// Computes self / (v, v).
230 /// ```
231 /// use vox_geometry_rust::point2::Point2F;
232 /// let mut vec = Point2F::new(3.0, 9.0);
233 /// vec = vec.add_scalar(4.0);
234 /// vec = vec.add_vec(Point2F::new(-2.0, 1.0));
235 /// vec = vec.sub_scalar(8.0);
236 /// vec = vec.sub_vec(Point2F::new(-5.0, 3.0));
237 /// vec = vec.mul_scalar(2.0);
238 /// vec = vec.mul_vec(Point2F::new(3.0, -2.0));
239 /// vec = vec.div_scalar(4.0);
240 /// assert_eq!(3.0, vec.x);
241 /// assert_eq!(-3.0, vec.y);
242 /// ```
243 pub fn div_scalar(&self, v: T) -> Point2<T> {
244 return Point2::new(self.x / v, self.y / v);
245 }
246
247 /// Computes self / (v.x, v.y).
248 /// ```
249 /// use vox_geometry_rust::point2::Point2F;
250 /// let mut vec = Point2F::new(3.0, 9.0);
251 /// vec = vec.add_scalar(4.0);
252 /// vec = vec.add_vec(Point2F::new(-2.0, 1.0));
253 /// vec = vec.sub_scalar(8.0);
254 /// vec = vec.sub_vec(Point2F::new(-5.0, 3.0));
255 /// vec = vec.mul_scalar(2.0);
256 /// vec = vec.mul_vec(Point2F::new(3.0, -2.0));
257 /// vec = vec.div_scalar(4.0);
258 /// vec = vec.div_vec(Point2F::new(3.0, -1.0));
259 /// assert_eq!(1.0, vec.x);
260 /// assert_eq!(3.0, vec.y);
261 /// ```
262 pub fn div_vec(&self, v: Point2<T>) -> Point2<T> {
263 return Point2::new(self.x / v.x, self.y / v.y);
264 }
265}
266
267/// # Binary operations: new instance = v (+) this
268impl<T: Float> Point2<T> {
269 /// Computes (v, v) - self.
270 /// ```
271 /// use vox_geometry_rust::point2::Point2F;
272 /// let mut vec = Point2F::new(3.0, 9.0);
273 /// vec = vec.rsub_scalar(8.0);
274 /// assert_eq!(5.0, vec.x);
275 /// assert_eq!(-1.0, vec.y);
276 /// ```
277 pub fn rsub_scalar(&self, v: T) -> Point2<T> {
278 return Point2::new(v - self.x, v - self.y);
279 }
280
281 /// Computes (v.x, v.y) - self.
282 /// ```
283 /// use vox_geometry_rust::point2::Point2F;
284 /// let mut vec = Point2F::new(3.0, 9.0);
285 /// vec = vec.rsub_scalar(8.0);
286 /// vec = vec.rsub_vec(Point2F::new(-5.0, 3.0));
287 /// assert_eq!(-10.0, vec.x);
288 /// assert_eq!(4.0, vec.y);
289 /// ```
290 pub fn rsub_vec(&self, v: Point2<T>) -> Point2<T> {
291 return Point2::new(v.x - self.x, v.y - self.y);
292 }
293
294 /// Computes (v, v) / self.
295 /// ```
296 /// use vox_geometry_rust::point2::Point2F;
297 /// let mut vec = Point2F::new(-4.0, -3.0);
298 /// vec = vec.rdiv_scalar(12.0);
299 /// assert_eq!(-3.0, vec.x);
300 /// assert_eq!(vec.y, -4.0);
301 /// ```
302 pub fn rdiv_scalar(&self, v: T) -> Point2<T> {
303 return Point2::new(v / self.x, v / self.y);
304 }
305
306 /// Computes (v.x, v.y) / self.
307 /// ```
308 /// use vox_geometry_rust::point2::Point2F;
309 /// let mut vec = Point2F::new(-4.0, -3.0);
310 /// vec = vec.rdiv_scalar(12.0);
311 /// vec = vec.rdiv_vec(Point2F::new(3.0, -16.0));
312 /// assert_eq!(-1.0, vec.x);
313 /// assert_eq!(4.0, vec.y);
314 /// ```
315 pub fn rdiv_vec(&self, v: Point2<T>) -> Point2<T> {
316 return Point2::new(v.x / self.x, v.y / self.y);
317 }
318}
319
320/// # Augmented operations: this (+)= v
321impl<T: Float> Point2<T> {
322 /// Computes self += (v, v).
323 /// ```
324 /// use vox_geometry_rust::point2::Point2F;
325 /// let mut vec = Point2F::new(3.0, 9.0);
326 /// vec.iadd_scalar(4.0);
327 /// assert_eq!(7.0, vec.x);
328 /// assert_eq!(vec.y, 13.0);
329 /// ```
330 pub fn iadd_scalar(&mut self, v: T) {
331 self.x = T::add(self.x, v);
332 self.y = T::add(self.y, v);
333 }
334
335 /// Computes self += (v.x, v.y).
336 /// ```
337 /// use vox_geometry_rust::point2::Point2F;
338 /// let mut vec = Point2F::new(3.0, 9.0);
339 /// vec.iadd_scalar(4.0);
340 /// vec.iadd_vec(Point2F::new(-2.0, 1.0));
341 /// assert_eq!(5.0, vec.x);
342 /// assert_eq!(vec.y, 14.0);
343 /// ```
344 pub fn iadd_vec(&mut self, v: Point2<T>) {
345 self.x = T::add(self.x, v.x);
346 self.y = T::add(self.y, v.y);
347 }
348
349 /// Computes self -= (v, v).
350 /// ```
351 /// use vox_geometry_rust::point2::Point2F;
352 /// let mut vec = Point2F::new(3.0, 9.0);
353 /// vec.iadd_scalar(4.0);
354 /// vec.iadd_vec(Point2F::new(-2.0, 1.0));
355 /// vec.isub_scalar(8.0);
356 /// assert_eq!(-3.0, vec.x);
357 /// assert_eq!(6.0, vec.y);
358 /// ```
359 pub fn isub_scalar(&mut self, v: T) {
360 self.x = T::sub(self.x, v);
361 self.y = T::sub(self.y, v);
362 }
363
364 /// Computes self -= (v.x, v.y).
365 /// ```
366 /// use vox_geometry_rust::point2::Point2F;
367 /// let mut vec = Point2F::new(3.0, 9.0);
368 /// vec.iadd_scalar(4.0);
369 /// vec.iadd_vec(Point2F::new(-2.0, 1.0));
370 /// vec.isub_scalar(8.0);
371 /// vec.isub_vec(Point2F::new(-5.0, 3.0));
372 /// assert_eq!(2.0, vec.x);
373 /// assert_eq!(3.0, vec.y);
374 /// ```
375 pub fn isub_vec(&mut self, v: Point2<T>) {
376 self.x = T::sub(self.x, v.x);
377 self.y = T::sub(self.y, v.y);
378 }
379
380 /// Computes self *= (v, v).
381 /// ```
382 /// use vox_geometry_rust::point2::Point2F;
383 /// let mut vec = Point2F::new(3.0, 9.0);
384 /// vec.iadd_scalar(4.0);
385 /// vec.iadd_vec(Point2F::new(-2.0, 1.0));
386 /// vec.isub_scalar(8.0);
387 /// vec.isub_vec(Point2F::new(-5.0, 3.0));
388 /// vec.imul_scalar(2.0);
389 /// assert_eq!(4.0, vec.x);
390 /// assert_eq!(6.0, vec.y);
391 /// ```
392 pub fn imul_scalar(&mut self, v: T) {
393 self.x = T::mul(self.x, v);
394 self.y = T::mul(self.y, v);
395 }
396
397 /// Computes self *= (v.x, v.y).
398 /// ```
399 /// use vox_geometry_rust::point2::Point2F;
400 /// let mut vec = Point2F::new(3.0, 9.0);
401 /// vec.iadd_scalar(4.0);
402 /// vec.iadd_vec(Point2F::new(-2.0, 1.0));
403 /// vec.isub_scalar(8.0);
404 /// vec.isub_vec(Point2F::new(-5.0, 3.0));
405 /// vec.imul_scalar(2.0);
406 /// vec.imul_vec(Point2F::new(3.0, -2.0));
407 /// assert_eq!(12.0, vec.x);
408 /// assert_eq!(-12.0, vec.y);
409 /// ```
410 pub fn imul_vec(&mut self, v: Point2<T>) {
411 self.x = T::mul(self.x, v.x);
412 self.y = T::mul(self.y, v.y);
413 }
414
415 /// Computes self /= (v, v).
416 /// ```
417 /// use vox_geometry_rust::point2::Point2F;
418 /// let mut vec = Point2F::new(3.0, 9.0);
419 /// vec.iadd_scalar(4.0);
420 /// vec.iadd_vec(Point2F::new(-2.0, 1.0));
421 /// vec.isub_scalar(8.0);
422 /// vec.isub_vec(Point2F::new(-5.0, 3.0));
423 /// vec.imul_scalar(2.0);
424 /// vec.imul_vec(Point2F::new(3.0, -2.0));
425 /// vec.idiv_scalar(4.0);
426 /// assert_eq!(3.0, vec.x);
427 /// assert_eq!(-3.0, vec.y);
428 /// ```
429 pub fn idiv_scalar(&mut self, v: T) {
430 self.x = T::div(self.x, v);
431 self.y = T::div(self.y, v);
432 }
433
434 /// Computes self /= (v.x, v.y).
435 /// ```
436 /// use vox_geometry_rust::point2::Point2F;
437 /// let mut vec = Point2F::new(3.0, 9.0);
438 /// vec.iadd_scalar(4.0);
439 /// vec.iadd_vec(Point2F::new(-2.0, 1.0));
440 /// vec.isub_scalar(8.0);
441 /// vec.isub_vec(Point2F::new(-5.0, 3.0));
442 /// vec.imul_scalar(2.0);
443 /// vec.imul_vec(Point2F::new(3.0, -2.0));
444 /// vec.idiv_scalar(4.0);
445 /// vec.idiv_vec(Point2F::new(3.0, -1.0));
446 /// assert_eq!(1.0, vec.x);
447 /// assert_eq!(3.0, vec.y);
448 /// ```
449 pub fn idiv_vec(&mut self, v: Point2<T>) {
450 self.x = T::div(self.x, v.x);
451 self.y = T::div(self.y, v.y);
452 }
453}
454
455/// # Basic getters
456impl<T: Float> Point2<T> {
457 /// Returns const reference to the **i** -th element of the point.
458 /// ```
459 /// use vox_geometry_rust::point2::Point2F;
460 /// let vec = Point2F::new(8.0, 9.0);
461 /// assert_eq!(*vec.at(0), 8.0);
462 /// assert_eq!(*vec.at(1), 9.0);
463 /// ```
464 pub fn at(&self, i: usize) -> &T {
465 match i {
466 0 => return &self.x,
467 1 => return &self.y,
468 _ => { panic!() }
469 }
470 }
471
472 /// Returns reference to the **i** -th element of the point.
473 /// ```
474 /// use vox_geometry_rust::point2::Point2F;
475 /// let mut a = Point2F::new_default();
476 /// *a.at_mut(0) = 10.0_f32;
477 /// *a.at_mut(1) = 20.0_f32;
478 /// assert_eq!(*a.at(0), 10.0);
479 /// assert_eq!(*a.at(1), 20.0);
480 /// ```
481 pub fn at_mut(&mut self, i: usize) -> &mut T {
482 match i {
483 0 => return &mut self.x,
484 1 => return &mut self.y,
485 _ => { panic!() }
486 }
487 }
488
489 /// Returns the sum of all the components (i.e. x + y).
490 /// ```
491 /// use vox_geometry_rust::point2::Point2F;
492 /// let vec = Point2F::new(3.0, 7.0);
493 /// let sum = vec.sum();
494 /// assert_eq!(sum, 10.0);
495 /// ```
496 pub fn sum(&self) -> T {
497 return self.x + self.y;
498 }
499
500 /// Returns the minimum value among x and y.
501 /// ```
502 /// use vox_geometry_rust::point2::Point2F;
503 /// let vec = Point2F::new(3.0, 7.0);
504 /// let min = vec.min();
505 /// assert_eq!(min, 3.0);
506 /// ```
507 pub fn min(&self) -> T {
508 return self.x.min(self.y);
509 }
510
511 /// Returns the maximum value among x and y.
512 /// ```
513 /// use vox_geometry_rust::point2::Point2F;
514 /// let vec = Point2F::new(3.0, 7.0);
515 /// let max = vec.max();
516 /// assert_eq!(max, 7.0);
517 /// ```
518 pub fn max(&self) -> T {
519 return self.x.max(self.y);
520 }
521
522 /// Returns the absolute minimum value among x and y.
523 /// ```
524 /// use vox_geometry_rust::point2::Point2F;
525 /// let vec = Point2F::new(-3.0, -7.0);
526 /// let absmin = vec.absmin();
527 /// assert_eq!(absmin, -3.0);
528 /// ```
529 pub fn absmin(&self) -> T {
530 return crate::math_utils::absmin(self.x, self.y);
531 }
532
533 /// Returns the absolute maximum value among x and y.
534 /// ```
535 /// use vox_geometry_rust::point2::Point2F;
536 /// let vec = Point2F::new(-3.0, -7.0);
537 /// let absmax = vec.absmax();
538 /// assert_eq!(absmax, -7.0);
539 /// ```
540 pub fn absmax(&self) -> T {
541 return crate::math_utils::absmax(self.x, self.y);
542 }
543
544 /// Returns the index of the dominant axis.
545 /// ```
546 /// use vox_geometry_rust::point2::Point2F;
547 /// let vec = Point2F::new(3.0, 7.0);
548 /// let dominant_axis = vec.dominant_axis();
549 /// assert_eq!(dominant_axis, 1);
550 /// ```
551 pub fn dominant_axis(&self) -> usize {
552 match self.x.abs() > self.y.abs() {
553 true => 0,
554 false => 1
555 }
556 }
557
558 /// Returns the index of the subminant axis.
559 /// ```
560 /// use vox_geometry_rust::point2::Point2F;
561 /// let vec = Point2F::new(3.0, 7.0);
562 /// let subminant_axis = vec.subminant_axis();
563 /// assert_eq!(subminant_axis, 0);
564 /// ```
565 pub fn subminant_axis(&self) -> usize {
566 match self.x.abs() < self.y.abs() {
567 true => 0,
568 false => 1
569 }
570 }
571
572 /// Returns true if **other** is the same as self point.
573 pub fn is_equal(&self, other: &Point2<T>) -> bool {
574 return self.x == other.x && self.y == other.y;
575 }
576}
577
578/// Copy constructor.
579/// ```
580/// use vox_geometry_rust::point2::Point2F;
581/// let mut vec5 = Point2F::new_lst([7.0, 6.0]);
582/// let mut vec6 = vec5.clone();
583/// vec6.x = 10.0;
584/// assert_eq!(10.0, vec6.x);
585/// assert_eq!(7.0, vec5.x);
586/// ```
587impl<T: Float> Clone for Point2<T> {
588 fn clone(&self) -> Self {
589 return Point2 {
590 x: self.x,
591 y: self.y,
592 };
593 }
594}
595
596///
597/// ```
598/// use vox_geometry_rust::point2::Point2F;
599/// let vec = Point2F::new(5.0, 1.0);
600/// let mut vec2 = Point2F::new(3.0, 3.0);
601/// vec2 = vec;
602/// assert_eq!(5.0, vec2.x);
603/// assert_eq!(vec2.y, 1.0);
604/// ```
605impl<T: Float> Copy for Point2<T> {}
606
607/// # Operators
608/// Returns const reference to the **i** -th element of the point.
609/// ```
610/// use vox_geometry_rust::point2::Point2F;
611/// let vec = Point2F::new(8.0, 9.0);
612/// assert_eq!(vec[0], 8.0);
613/// assert_eq!(vec[1], 9.0);
614/// ```
615impl<T: Float> Index<usize> for Point2<T> {
616 type Output = T;
617 fn index(&self, index: usize) -> &Self::Output {
618 return self.at(index);
619 }
620}
621
622/// Returns reference to the **i** -th element of the point.
623/// ```
624/// use vox_geometry_rust::point2::Point2F;
625/// let mut vec = Point2F::new(8.0, 9.0);
626/// vec[0] = 7.0;
627/// vec[1] = 6.0;
628/// assert_eq!(7.0, vec.x);
629/// assert_eq!(6.0, vec.y);
630/// ```
631impl<T: Float> IndexMut<usize> for Point2<T> {
632 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
633 return self.at_mut(index);
634 }
635}
636
637/// Computes self += (v, v)
638/// ```
639/// use vox_geometry_rust::point2::Point2F;
640/// let mut vec = Point2F::new(3.0, 9.0);
641/// vec += 4.0;
642/// assert_eq!(7.0, vec.x);
643/// assert_eq!(vec.y, 13.0);
644/// ```
645impl<T: Float> AddAssign<T> for Point2<T> {
646 fn add_assign(&mut self, rhs: T) {
647 self.iadd_scalar(rhs);
648 }
649}
650
651/// Computes self += (v.x, v.y)
652/// ```
653/// use vox_geometry_rust::point2::Point2F;
654/// let mut vec = Point2F::new(3.0, 9.0);
655/// vec += 4.0;
656/// vec += Point2F::new(-2.0, 1.0);
657/// assert_eq!(5.0, vec.x);
658/// assert_eq!(vec.y, 14.0);
659/// ```
660impl<T: Float> AddAssign for Point2<T> {
661 fn add_assign(&mut self, rhs: Self) {
662 self.iadd_vec(rhs);
663 }
664}
665
666/// Computes self -= (v, v)
667/// ```
668/// use vox_geometry_rust::point2::Point2F;
669/// let mut vec = Point2F::new(3.0, 9.0);
670/// vec += 4.0;
671/// vec += Point2F::new(-2.0, 1.0);
672/// vec -= 8.0;
673/// assert_eq!(-3.0, vec.x);
674/// assert_eq!(6.0, vec.y);
675/// ```
676impl<T: Float> SubAssign<T> for Point2<T> {
677 fn sub_assign(&mut self, rhs: T) {
678 self.isub_scalar(rhs);
679 }
680}
681
682/// Computes self -= (v.x, v.y)
683/// ```
684/// use vox_geometry_rust::point2::Point2F;
685/// let mut vec = Point2F::new(3.0, 9.0);
686/// vec += 4.0;
687/// vec += Point2F::new(-2.0, 1.0);
688/// vec -= 8.0;
689/// vec -= Point2F::new(-5.0, 3.0);
690/// assert_eq!(2.0, vec.x);
691/// assert_eq!(3.0, vec.y);
692/// ```
693impl<T: Float> SubAssign for Point2<T> {
694 fn sub_assign(&mut self, rhs: Self) {
695 self.isub_vec(rhs);
696 }
697}
698
699/// Computes self *= (v, v)
700/// ```
701/// use vox_geometry_rust::point2::Point2F;
702/// let mut vec = Point2F::new(3.0, 9.0);
703/// vec += 4.0;
704/// vec += Point2F::new(-2.0, 1.0);
705/// vec -= 8.0;
706/// vec -= Point2F::new(-5.0, 3.0);
707/// vec *= 2.0;
708/// assert_eq!(4.0, vec.x);
709/// assert_eq!(6.0, vec.y);
710/// ```
711impl<T: Float> MulAssign<T> for Point2<T> {
712 fn mul_assign(&mut self, rhs: T) {
713 self.imul_scalar(rhs);
714 }
715}
716
717/// Computes self *= (v.x, v.y)
718/// ```
719/// use vox_geometry_rust::point2::Point2F;
720/// let mut vec = Point2F::new(3.0, 9.0);
721/// vec += 4.0;
722/// vec += Point2F::new(-2.0, 1.0);
723/// vec -= 8.0;
724/// vec -= Point2F::new(-5.0, 3.0);
725/// vec *= 2.0;
726/// vec *= Point2F::new(3.0, -2.0);
727/// assert_eq!(12.0, vec.x);
728/// assert_eq!(-12.0, vec.y);
729/// ```
730impl<T: Float> MulAssign for Point2<T> {
731 fn mul_assign(&mut self, rhs: Self) {
732 self.imul_vec(rhs);
733 }
734}
735
736/// Computes self /= (v, v)
737/// ```
738/// use vox_geometry_rust::point2::Point2F;
739/// let mut vec = Point2F::new(3.0, 9.0);
740/// vec += 4.0;
741/// vec += Point2F::new(-2.0, 1.0);
742/// vec -= 8.0;
743/// vec -= Point2F::new(-5.0, 3.0);
744/// vec *= 2.0;
745/// vec *= Point2F::new(3.0, -2.0);
746/// vec /= 4.0;
747/// assert_eq!(3.0, vec.x);
748/// assert_eq!(-3.0, vec.y);
749/// ```
750impl<T: Float> DivAssign<T> for Point2<T> {
751 fn div_assign(&mut self, rhs: T) {
752 self.idiv_scalar(rhs);
753 }
754}
755
756/// Computes self /= (v.x, v.y)
757/// ```
758/// use vox_geometry_rust::point2::Point2F;
759/// let mut vec = Point2F::new(3.0, 9.0);
760/// vec += 4.0;
761/// vec += Point2F::new(-2.0, 1.0);
762/// vec -= 8.0;
763/// vec -= Point2F::new(-5.0, 3.0);
764/// vec *= 2.0;
765/// vec *= Point2F::new(3.0, -2.0);
766/// vec /= 4.0;
767/// vec /= Point2F::new(3.0, -1.0);
768/// assert_eq!(1.0, vec.x);
769/// assert_eq!(3.0, vec.y);
770/// ```
771impl<T: Float> DivAssign for Point2<T> {
772 fn div_assign(&mut self, rhs: Self) {
773 self.idiv_vec(rhs);
774 }
775}
776
777/// Returns true if **other** is the same as self point.
778/// ```
779/// use vox_geometry_rust::point2::Point2F;
780/// let mut vec = Point2F::new_default();
781/// let vec2 = Point2F::new(3.0, 7.0);
782/// let vec3 = Point2F::new(3.0, 5.0);
783/// let vec4 = Point2F::new(5.0, 1.0);
784/// vec = vec2;
785/// assert_eq!(vec == vec2, true);
786/// assert_eq!(vec == vec3, false);
787/// assert_eq!(vec != vec2, false);
788/// assert_eq!(vec != vec3, true);
789/// assert_eq!(vec != vec4, true);
790/// ```
791impl<T: Float> PartialEq for Point2<T> {
792 fn eq(&self, other: &Self) -> bool {
793 return self.is_equal(other);
794 }
795}
796
797impl<T: Float> Eq for Point2<T> {}
798
799impl<T: Float> Neg for Point2<T> {
800 type Output = Point2<T>;
801 /// Negative sign operator.
802 fn neg(self) -> Self::Output {
803 return Point2::new(-self.x, -self.y);
804 }
805}
806
807/// Computes (a, a) + (b.x, b.y).
808/// ```
809/// use vox_geometry_rust::point2::Point2F;
810/// let mut vec = Point2F::new(3.0, 9.0);
811/// vec = vec + 4.0;
812/// assert_eq!(7.0, vec.x);
813/// assert_eq!(vec.y, 13.0);
814/// ```
815impl<T: Float> Add<T> for Point2<T> {
816 type Output = Point2<T>;
817 fn add(self, rhs: T) -> Self::Output {
818 return self.add_scalar(rhs);
819 }
820}
821
822/// Computes (a.x, a.y) + (b.x, b.y).
823/// ```
824/// use vox_geometry_rust::point2::Point2F;
825/// let mut vec = Point2F::new(3.0, 9.0);
826/// vec = vec + 4.0;
827/// vec = vec + Point2F::new(-2.0, 1.0);
828/// assert_eq!(5.0, vec.x);
829/// assert_eq!(vec.y, 14.0);
830/// ```
831impl<T: Float> Add for Point2<T> {
832 type Output = Point2<T>;
833 fn add(self, rhs: Self) -> Self::Output {
834 return self.add_vec(rhs);
835 }
836}
837
838/// Computes (a.x, a.y) - (b, b).
839/// ```
840/// use vox_geometry_rust::point2::Point2F;
841/// let mut vec = Point2F::new(3.0, 9.0);
842/// vec = vec + 4.0;
843/// vec = vec + Point2F::new(-2.0, 1.0);
844/// vec = vec - 8.0;
845/// assert_eq!(-3.0, vec.x);
846/// assert_eq!(6.0, vec.y);
847/// ```
848impl<T: Float> Sub<T> for Point2<T> {
849 type Output = Point2<T>;
850 fn sub(self, rhs: T) -> Self::Output {
851 return self.sub_scalar(rhs);
852 }
853}
854
855/// Computes (a.x, a.y) - (b.x, b.y).
856/// ```
857/// use vox_geometry_rust::point2::Point2F;
858/// let mut vec = Point2F::new(3.0, 9.0);
859/// vec = vec + 4.0;
860/// vec = vec + Point2F::new(-2.0, 1.0);
861/// vec = vec - 8.0;
862/// vec = vec - Point2F::new(-5.0, 3.0);
863/// assert_eq!(2.0, vec.x);
864/// assert_eq!(3.0, vec.y);
865/// ```
866impl<T: Float> Sub for Point2<T> {
867 type Output = Point2<T>;
868 fn sub(self, rhs: Self) -> Self::Output {
869 return self.sub_vec(rhs);
870 }
871}
872
873/// Computes (a.x, a.y) * (b, b).
874/// ```
875/// use vox_geometry_rust::point2::Point2F;
876/// let mut vec = Point2F::new(3.0, 9.0);
877/// vec = vec + 4.0;
878/// vec = vec + Point2F::new(-2.0, 1.0);
879/// vec = vec - 8.0;
880/// vec = vec - Point2F::new(-5.0, 3.0);
881/// vec = vec * 2.0;
882/// assert_eq!(4.0, vec.x);
883/// assert_eq!(6.0, vec.y);
884/// ```
885impl<T: Float> Mul<T> for Point2<T> {
886 type Output = Point2<T>;
887 fn mul(self, rhs: T) -> Self::Output {
888 return self.mul_scalar(rhs);
889 }
890}
891
892/// Computes (a.x, a.y) * (b.x, b.y).
893/// ```
894/// use vox_geometry_rust::point2::Point2F;
895/// let mut vec = Point2F::new(3.0, 9.0);
896/// vec = vec + 4.0;
897/// vec = vec + Point2F::new(-2.0, 1.0);
898/// vec = vec - 8.0;
899/// vec = vec - Point2F::new(-5.0, 3.0);
900/// vec = vec * 2.0;
901/// vec = vec * Point2F::new(3.0, -2.0);
902/// assert_eq!(12.0, vec.x);
903/// assert_eq!(-12.0, vec.y);
904/// ```
905impl<T: Float> Mul for Point2<T> {
906 type Output = Point2<T>;
907 fn mul(self, rhs: Self) -> Self::Output {
908 return self.mul_vec(rhs);
909 }
910}
911
912/// Computes (a.x, a.y) / (b, b).
913/// ```
914/// use vox_geometry_rust::point2::Point2F;
915/// let mut vec = Point2F::new(3.0, 9.0);
916/// vec = vec + 4.0;
917/// vec = vec + Point2F::new(-2.0, 1.0);
918/// vec = vec - 8.0;
919/// vec = vec - Point2F::new(-5.0, 3.0);
920/// vec = vec * 2.0;
921/// vec = vec * Point2F::new(3.0, -2.0);
922/// vec = vec / 4.0;
923/// assert_eq!(3.0, vec.x);
924/// assert_eq!(-3.0, vec.y);
925/// ```
926impl<T: Float> Div<T> for Point2<T> {
927 type Output = Point2<T>;
928 fn div(self, rhs: T) -> Self::Output {
929 return self.div_scalar(rhs);
930 }
931}
932
933/// Computes (a.x, a.y) / (b.x, b.y).
934/// ```
935/// use vox_geometry_rust::point2::Point2F;
936/// let mut vec = Point2F::new(3.0, 9.0);
937/// vec = vec + 4.0;
938/// vec = vec + Point2F::new(-2.0, 1.0);
939/// vec = vec - 8.0;
940/// vec = vec - Point2F::new(-5.0, 3.0);
941/// vec = vec * 2.0;
942/// vec = vec * Point2F::new(3.0, -2.0);
943/// vec = vec / 4.0;
944/// vec = vec / Point2F::new(3.0, -1.0);
945/// assert_eq!(1.0, vec.x);
946/// assert_eq!(3.0, vec.y);
947/// ```
948impl<T: Float> Div for Point2<T> {
949 type Output = Point2<T>;
950 fn div(self, rhs: Self) -> Self::Output {
951 return self.div_vec(rhs);
952 }
953}
954
955impl<T: Float + Debug> Debug for Point2<T> {
956 /// # Example
957 /// ```
958 ///
959 /// use vox_geometry_rust::point2::Point2F;
960 /// let vec = Point2F::new(10.0, 20.0);
961 /// assert_eq!(format!("{:?}", vec), "(10.0, 20.0)");
962 ///
963 /// assert_eq!(format!("{:#?}", vec), "(
964 /// 10.0,
965 /// 20.0,
966 /// )");
967 /// ```
968 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
969 f.debug_tuple("")
970 .field(&self.x)
971 .field(&self.y)
972 .finish()
973 }
974}
975
976/// # utility
977/// Returns element-wise min point: (min(a.x, b.x), min(a.y, b.y)).
978/// ```
979/// use vox_geometry_rust::point2::Point2F;
980/// use vox_geometry_rust::point2::min;
981/// let vec = Point2F::new(5.0, 1.0);
982/// let vec2 = Point2F::new(3.0, 3.0);
983/// let min_point = min(&vec, &vec2);
984/// assert_eq!(Point2F::new(3.0, 1.0), min_point);
985/// ```
986pub fn min<T: Float>(a: &Point2<T>, b: &Point2<T>) -> Point2<T> {
987 return Point2::new(T::min(a.x, b.x), T::min(a.y, b.y));
988}
989
990/// Returns element-wise max point: (max(a.x, b.x), max(a.y, b.y)).
991/// ```
992/// use vox_geometry_rust::point2::Point2F;
993/// use vox_geometry_rust::point2::max;
994/// let vec = Point2F::new(5.0, 1.0);
995/// let vec2 = Point2F::new(3.0, 3.0);
996/// let min_point = max(&vec, &vec2);
997/// assert_eq!(Point2F::new(5.0, 3.0), min_point);
998/// ```
999pub fn max<T: Float>(a: &Point2<T>, b: &Point2<T>) -> Point2<T> {
1000 return Point2::new(T::max(a.x, b.x), T::max(a.y, b.y));
1001}
1002
1003/// Returns element-wise clamped point.
1004/// ```
1005/// use vox_geometry_rust::point2::Point2F;
1006/// use vox_geometry_rust::point2::clamp;
1007/// let vec = Point2F::new(2.0, 4.0);
1008/// let low = Point2F::new(3.0, -1.0);
1009/// let high = Point2F::new(5.0, 2.0);
1010/// let clamped_vec = clamp(&vec, &low, &high);
1011/// assert_eq!(Point2F::new(3.0, 2.0), clamped_vec);
1012/// ```
1013pub fn clamp<T: Float>(v: &Point2<T>, low: &Point2<T>, high: &Point2<T>) -> Point2<T> {
1014 return Point2::new(crate::math_utils::clamp(v.x, low.x, high.x),
1015 crate::math_utils::clamp(v.y, low.y, high.y));
1016}
1017
1018/// Returns element-wise ceiled point.
1019/// ```
1020/// use vox_geometry_rust::point2::Point2F;
1021/// use vox_geometry_rust::point2::ceil;
1022/// let vec = Point2F::new(2.2, 4.7);
1023/// let ceil_vec = ceil(&vec);
1024/// assert_eq!(Point2F::new(3.0, 5.0), ceil_vec);
1025/// ```
1026pub fn ceil<T: Float>(a: &Point2<T>) -> Point2<T> {
1027 return Point2::new((a.x).ceil(), (a.y).ceil());
1028}
1029
1030/// Returns element-wise floored point.
1031/// ```
1032/// use vox_geometry_rust::point2::Point2F;
1033/// use vox_geometry_rust::point2::floor;
1034/// let vec = Point2F::new(2.2, 4.7);
1035/// let floor_vec = floor(&vec);
1036/// assert_eq!(Point2F::new(2.0, 4.0), floor_vec);
1037/// ```
1038pub fn floor<T: Float>(a: &Point2<T>) -> Point2<T> {
1039 return Point2::new((a.x).floor(), (a.y).floor());
1040}