1use std::ops::{Add, Div, Mul, Neg, Sub};
2
3use crate::math::{clamp, EPSILON};
4
5#[derive(Debug, Clone, Copy, PartialEq, Default)]
7pub struct Point {
8 pub x: f64,
10 pub y: f64,
12}
13
14impl Point {
15 #[must_use]
17 pub const fn new(x: f64, y: f64) -> Self {
18 Self { x, y }
19 }
20
21 #[must_use]
23 pub fn is_finite(self) -> bool {
24 self.x.is_finite() && self.y.is_finite()
25 }
26}
27
28impl Add<Vector> for Point {
29 type Output = Point;
30
31 fn add(self, rhs: Vector) -> Self::Output {
32 Point::new(self.x + rhs.x, self.y + rhs.y)
33 }
34}
35
36impl Sub<Point> for Point {
37 type Output = Vector;
38
39 fn sub(self, rhs: Point) -> Self::Output {
40 Vector::new(self.x - rhs.x, self.y - rhs.y)
41 }
42}
43
44impl Sub<Vector> for Point {
45 type Output = Point;
46
47 fn sub(self, rhs: Vector) -> Self::Output {
48 Point::new(self.x - rhs.x, self.y - rhs.y)
49 }
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Default)]
54pub struct Vector {
55 pub x: f64,
57 pub y: f64,
59}
60
61impl Vector {
62 #[must_use]
64 pub const fn new(x: f64, y: f64) -> Self {
65 Self { x, y }
66 }
67
68 #[must_use]
70 pub fn is_finite(self) -> bool {
71 self.x.is_finite() && self.y.is_finite()
72 }
73
74 #[must_use]
76 pub fn length(self) -> f64 {
77 self.length_squared().sqrt()
78 }
79
80 #[must_use]
82 pub const fn length_squared(self) -> f64 {
83 self.x * self.x + self.y * self.y
84 }
85
86 #[must_use]
88 pub const fn dot(self, other: Vector) -> f64 {
89 self.x * other.x + self.y * other.y
90 }
91
92 #[must_use]
94 pub const fn cross(self, other: Vector) -> f64 {
95 self.x * other.y - self.y * other.x
96 }
97
98 #[must_use]
100 pub fn normalized(self) -> Option<Vector> {
101 let length = self.length();
102 if !length.is_finite() || length <= EPSILON {
103 return None;
104 }
105 Some(self / length)
106 }
107
108 #[must_use]
110 pub fn angle_between(self, other: Vector) -> Option<f64> {
111 let a = self.normalized()?;
112 let b = other.normalized()?;
113 Some(clamp(a.dot(b), -1.0, 1.0).acos())
114 }
115}
116
117impl Add for Vector {
118 type Output = Vector;
119
120 fn add(self, rhs: Vector) -> Self::Output {
121 Vector::new(self.x + rhs.x, self.y + rhs.y)
122 }
123}
124
125impl Sub for Vector {
126 type Output = Vector;
127
128 fn sub(self, rhs: Vector) -> Self::Output {
129 Vector::new(self.x - rhs.x, self.y - rhs.y)
130 }
131}
132
133impl Mul<f64> for Vector {
134 type Output = Vector;
135
136 fn mul(self, rhs: f64) -> Self::Output {
137 Vector::new(self.x * rhs, self.y * rhs)
138 }
139}
140
141impl Mul<Vector> for f64 {
142 type Output = Vector;
143
144 fn mul(self, rhs: Vector) -> Self::Output {
145 rhs * self
146 }
147}
148
149impl Div<f64> for Vector {
150 type Output = Vector;
151
152 fn div(self, rhs: f64) -> Self::Output {
153 Vector::new(self.x / rhs, self.y / rhs)
154 }
155}
156
157impl Neg for Vector {
158 type Output = Vector;
159
160 fn neg(self) -> Self::Output {
161 Vector::new(-self.x, -self.y)
162 }
163}