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}