nanachi/
point.rs

1//! [`Point`] represents x, y coordinates.
2
3/// Auxiliary struct representing 2D coordinates.
4#[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}