1#[derive(Debug, Clone, Copy, PartialEq)]
5pub struct Point(pub f64, pub f64);
6
7impl Point {
8 pub fn from_angle(angle: f64) -> Point {
9 Point(angle.cos(), angle.sin())
10 }
11
12 pub fn dot(&self, rhs: &Self) -> f64 {
13 self.0 * rhs.0 + self.1 * rhs.1
14 }
15
16 pub fn lerp(self, rhs: Self, v: f64) -> Self {
17 self * (1.0 - v) + rhs * v
18 }
19
20 pub fn norm(self) -> f64 {
21 self.0.hypot(self.1)
22 }
23
24 pub fn atan2(self) -> f64 {
25 self.1.atan2(self.0)
26 }
27
28 pub fn rotate(self, angle: f64) -> Self {
29 let (sin, cos) = angle.sin_cos();
30 Point(self.0 * cos - self.1 * sin, self.0 * sin + self.1 * cos)
31 }
32
33 pub fn unit(self) -> Point {
34 self / self.0.hypot(self.1)
35 }
36}
37
38impl std::ops::Add for Point {
39 type Output = Self;
40 fn add(self, rhs: Self) -> Self {
41 Point(self.0 + rhs.0, self.1 + rhs.1)
42 }
43}
44
45impl std::ops::Sub for Point {
46 type Output = Self;
47 fn sub(self, rhs: Self) -> Self {
48 Point(self.0 - rhs.0, self.1 - rhs.1)
49 }
50}
51
52impl std::ops::Mul<f64> for Point {
53 type Output = Self;
54 fn mul(self, rhs: f64) -> Self {
55 Point(self.0 * rhs, self.1 * rhs)
56 }
57}
58
59impl std::ops::Div<f64> for Point {
60 type Output = Self;
61 fn div(self, rhs: f64) -> Self {
62 Point(self.0 / rhs, self.1 / rhs)
63 }
64}
65
66impl<T: Into<f64>> From<(T, T)> for Point {
67 fn from(tuple: (T, T)) -> Point {
68 Point(tuple.0.into(), tuple.1.into())
69 }
70}
71
72impl From<Point> for (f64, f64) {
73 fn from(point: Point) -> (f64, f64) {
74 (point.0, point.1)
75 }
76}