smooth_frame/types/
geometry.rs1use std::ops::{Add, Div, Mul, Neg, Sub};
2
3use crate::utils::{EPSILON, clamp};
4
5#[derive(Debug, Clone, Copy, PartialEq, Default)]
7pub struct Point {
8 pub x: f64,
10 pub y: f64,
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Default)]
16pub struct Vector {
17 pub x: f64,
19 pub y: f64,
21}
22
23impl Point {
24 #[must_use]
26 pub const fn new(x: f64, y: f64) -> Self {
27 Self { x, y }
28 }
29
30 #[must_use]
32 pub fn is_finite(self) -> bool {
33 self.x.is_finite() && self.y.is_finite()
34 }
35}
36
37impl Vector {
38 #[must_use]
40 pub const fn new(x: f64, y: f64) -> Self {
41 Self { x, y }
42 }
43
44 #[must_use]
46 pub fn is_finite(self) -> bool {
47 self.x.is_finite() && self.y.is_finite()
48 }
49
50 #[must_use]
52 pub fn length(self) -> f64 {
53 self.length_squared().sqrt()
54 }
55
56 #[must_use]
58 pub const fn length_squared(self) -> f64 {
59 self.x * self.x + self.y * self.y
60 }
61
62 #[must_use]
64 pub const fn dot(self, other: Vector) -> f64 {
65 self.x * other.x + self.y * other.y
66 }
67
68 #[must_use]
70 pub const fn cross(self, other: Vector) -> f64 {
71 self.x * other.y - self.y * other.x
72 }
73
74 #[must_use]
76 pub fn normalized(self) -> Option<Vector> {
77 let length = self.length();
78 if !length.is_finite() || length <= EPSILON {
79 return None;
80 }
81 Some(self / length)
82 }
83
84 #[must_use]
86 pub fn angle_between(self, other: Vector) -> Option<f64> {
87 let a = self.normalized()?;
88 let b = other.normalized()?;
89 Some(clamp(a.dot(b), -1.0, 1.0).acos())
90 }
91}
92
93impl Add<Vector> for Point {
95 type Output = Point;
96
97 fn add(self, rhs: Vector) -> Self::Output {
99 Point::new(self.x + rhs.x, self.y + rhs.y)
100 }
101}
102
103impl Sub<Point> for Point {
105 type Output = Vector;
106
107 fn sub(self, rhs: Point) -> Self::Output {
109 Vector::new(self.x - rhs.x, self.y - rhs.y)
110 }
111}
112
113impl Sub<Vector> for Point {
115 type Output = Point;
116
117 fn sub(self, rhs: Vector) -> Self::Output {
119 Point::new(self.x - rhs.x, self.y - rhs.y)
120 }
121}
122
123impl Add for Vector {
125 type Output = Vector;
126
127 fn add(self, rhs: Vector) -> Self::Output {
129 Vector::new(self.x + rhs.x, self.y + rhs.y)
130 }
131}
132
133impl Sub for Vector {
135 type Output = Vector;
136
137 fn sub(self, rhs: Vector) -> Self::Output {
139 Vector::new(self.x - rhs.x, self.y - rhs.y)
140 }
141}
142
143impl Mul<f64> for Vector {
145 type Output = Vector;
146
147 fn mul(self, rhs: f64) -> Self::Output {
149 Vector::new(self.x * rhs, self.y * rhs)
150 }
151}
152
153impl Mul<Vector> for f64 {
155 type Output = Vector;
156
157 fn mul(self, rhs: Vector) -> Self::Output {
159 rhs * self
160 }
161}
162
163impl Div<f64> for Vector {
165 type Output = Vector;
166
167 fn div(self, rhs: f64) -> Self::Output {
169 Vector::new(self.x / rhs, self.y / rhs)
170 }
171}
172
173impl Neg for Vector {
175 type Output = Vector;
176
177 fn neg(self) -> Self::Output {
179 Vector::new(-self.x, -self.y)
180 }
181}