algorithms_edu/algo/
geometry.rs1pub mod angle_between_vectors;
2pub mod geographical_coordinate;
3pub mod tangent;
4
5use std::ops::Sub;
6
7pub const EPS: f64 = 1e-6;
8
9pub struct Vec2D {
10 x: f64,
11 y: f64,
12}
13
14pub struct Vec3D {
15 x: f64,
16 y: f64,
17 z: f64,
18}
19
20impl Vec2D {
21 pub fn new(x: f64, y: f64) -> Self {
22 Self { x, y }
23 }
24 pub fn magnitude(&self) -> f64 {
25 (self.x * self.x + self.y * self.y).sqrt()
26 }
27 pub fn dot(&self, other: &Self) -> f64 {
29 (self.x * other.x) + (self.y * other.y)
30 }
31}
32
33impl Vec3D {
34 pub fn new(x: f64, y: f64, z: f64) -> Self {
35 Self { x, y, z }
36 }
37 pub fn magnitude(&self) -> f64 {
38 (self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
39 }
40 pub fn dot(&self, other: &Self) -> f64 {
42 self.x * other.x + self.y * other.y + self.z * other.z
43 }
44}
45
46#[derive(Copy, Clone)]
47pub struct Point2D {
48 pub x: f64,
49 pub y: f64,
50}
51
52impl Sub<&Self> for Point2D {
53 type Output = Vec2D;
54 fn sub(self, rhs: &Self) -> Self::Output {
55 Vec2D {
56 x: self.x - rhs.x,
57 y: self.y - rhs.y,
58 }
59 }
60}
61
62pub struct Point3D {
63 x: f64,
64 y: f64,
65 z: f64,
66}
67
68impl Point2D {
69 pub fn new(x: f64, y: f64) -> Self {
70 Self { x, y }
71 }
72 pub fn distance_to_point(&self, other: &Self) -> f64 {
73 Vec2D::new(self.x - other.x, self.y - other.y).magnitude()
74 }
75}
76
77impl Point3D {
78 pub fn new(x: f64, y: f64, z: f64) -> Self {
79 Self { x, y, z }
80 }
81 pub fn distance_to_point(&self, other: &Self) -> f64 {
82 Vec3D::new(self.x - other.x, self.y - other.y, self.z - other.z).magnitude()
83 }
84}
85
86pub struct Circle {
87 center: Point2D,
88 radius: f64,
89}
90
91impl Circle {
92 pub fn new(x: f64, y: f64, radius: f64) -> Self {
93 Self {
94 center: Point2D { x, y },
95 radius,
96 }
97 }
98}
99
100use num_traits::Float;
101pub trait SafeArcSinCos: Float {
102 fn asin_safe(self) -> Self;
106 fn acos_safe(self) -> Self;
110}
111
112impl SafeArcSinCos for f64 {
113 fn asin_safe(self) -> Self {
114 if self <= -1.0 {
115 -std::f64::consts::FRAC_PI_2
116 } else if self >= 1.0 {
117 std::f64::consts::FRAC_PI_2
118 } else {
119 self.asin()
120 }
121 }
122 fn acos_safe(self) -> Self {
123 if self <= -1.0 {
124 std::f64::consts::PI
125 } else if self >= 1.0 {
126 0.
127 } else {
128 self.acos()
129 }
130 }
131}