1pub mod ccw;
4
5pub mod intersect_circle_line;
6pub mod intersect_circle_segment;
7pub mod intersect_circles;
8pub mod intersect_line_segment;
9pub mod intersect_segments;
10
11pub mod dist_line_point;
12pub mod dist_segment_point;
13pub mod dist_segments;
14
15pub mod area_intersection_circle_polygon;
16pub mod area_intersection_circles;
17pub mod area_polygon;
18
19pub mod convex;
20pub mod convex_cut;
21pub mod convex_diameter;
22pub mod convex_hull;
23
24pub mod point_in_polygon;
25
26pub mod circumcircle;
27pub mod incircle;
28
29pub mod common_tangent_circles;
30pub mod tangent_circle;
31
32pub mod closest_pair;
33
34use crate::impl_ops;
35use std::{cmp::Ordering, f64::consts::PI};
36
37#[derive(Copy, Clone)]
39pub struct Eps {
40 eps: f64,
41}
42
43impl Eps {
44 pub fn new(eps: f64) -> Self {
46 Self { eps }
47 }
48 pub fn eq(&self, a: f64, b: f64) -> bool {
50 (a - b).abs() < self.eps
51 }
52 pub fn ne(&self, a: f64, b: f64) -> bool {
54 !self.eq(a, b)
55 }
56 pub fn lt(&self, a: f64, b: f64) -> bool {
58 a - b < -self.eps
59 }
60 pub fn gt(&self, a: f64, b: f64) -> bool {
62 a - b > self.eps
63 }
64 pub fn le(&self, a: f64, b: f64) -> bool {
66 self.lt(a, b) || self.eq(a, b)
67 }
68 pub fn ge(&self, a: f64, b: f64) -> bool {
70 self.gt(a, b) || self.eq(a, b)
71 }
72 pub fn partial_cmp(&self, a: f64, b: f64) -> Option<Ordering> {
74 if self.eq(a, b) {
75 Some(Ordering::Equal)
76 } else if self.lt(a, b) {
77 Some(Ordering::Less)
78 } else if self.gt(a, b) {
79 Some(Ordering::Greater)
80 } else {
81 None
82 }
83 }
84}
85
86#[derive(Clone, Copy, Debug, Default)]
88pub struct Vector(pub f64, pub f64);
89
90impl_ops!(Add for Vector, |a: Self, b: Self| Self(a.0 + b.0, a.1 + b.1));
91impl_ops!(Sub for Vector, |a: Self, b: Self| Self(a.0 - b.0, a.1 - b.1));
92impl_ops!(Mul<f64> for Vector, |a: Self, k: f64| Self(a.0 * k, a.1 * k));
93impl_ops!(Div<f64> for Vector, |a: Self, k: f64| Self(a.0 / k, a.1 / k));
94
95impl Vector {
96 pub fn abs(self) -> f64 {
98 (self.0 * self.0 + self.1 * self.1).sqrt()
99 }
100 pub fn abs_sq(self) -> f64 {
102 self.0 * self.0 + self.1 * self.1
103 }
104 pub fn dot(self, other: Self) -> f64 {
106 self.0 * other.0 + self.1 * other.1
107 }
108 pub fn cross(self, other: Self) -> f64 {
110 self.0 * other.1 - self.1 * other.0
111 }
112 pub fn unit(self) -> Self {
114 self / self.abs()
115 }
116 pub fn normal(self) -> Self {
118 Self(-self.1, self.0)
119 }
120 pub fn angle(self, other: Self) -> f64 {
122 (other.1 - self.1).atan2(other.0 - self.0)
123 }
124 pub fn polar(r: f64, ang: f64) -> Self {
126 Vector(r * ang.cos(), r * ang.sin())
127 }
128 pub fn angle_diff(self, other: Self) -> f64 {
130 let r = other.1.atan2(other.0) - self.1.atan2(self.0);
131
132 if r < -PI {
133 r + PI * 2.0
134 } else if r > PI {
135 r - PI * 2.0
136 } else {
137 r
138 }
139 }
140 pub fn eq(self, other: Self, eps: Eps) -> bool {
142 eps.eq(self.0, other.0) && eps.eq(self.1, other.1)
143 }
144}
145
146#[derive(Copy, Clone, Debug, Default)]
148pub struct Line {
149 pub from: Vector,
151 pub to: Vector,
153}
154
155impl Line {
156 pub fn new(from: Vector, to: Vector) -> Self {
158 Self { from, to }
159 }
160 pub fn unit(self) -> Vector {
162 (self.to - self.from).unit()
163 }
164 pub fn normal(self) -> Vector {
166 (self.to - self.from).normal()
167 }
168 pub fn diff(self) -> Vector {
170 self.to - self.from
171 }
172 pub fn abs(self) -> f64 {
174 self.diff().abs()
175 }
176 pub fn dot(self, other: Self) -> f64 {
178 self.diff().dot(other.diff())
179 }
180 pub fn cross(self, other: Self) -> f64 {
182 self.diff().cross(other.diff())
183 }
184 pub fn eq(self, other: Self, eps: Eps) -> bool {
186 self.from.eq(other.from, eps) && self.to.eq(other.to, eps)
187 }
188
189 pub fn projection(self, p: Vector) -> Vector {
191 self.from + self.unit() * self.unit().dot(p - self.from)
192 }
193
194 pub fn reflection(self, p: Vector) -> Vector {
196 p + (self.projection(p) - p) * 2.0
197 }
198
199 pub fn is_orthogonal(self, other: Self, eps: Eps) -> bool {
201 eps.eq(self.dot(other).abs(), 0.0)
202 }
203
204 pub fn is_parallel(self, other: Self, eps: Eps) -> bool {
206 eps.eq(self.cross(other).abs(), 0.0)
207 }
208}
209
210#[derive(Clone, Copy, Debug, Default)]
212pub struct Circle {
213 pub center: Vector,
215 pub radius: f64,
217}
218
219impl Circle {
220 pub fn new(center: Vector, radius: f64) -> Self {
222 Circle { center, radius }
223 }
224
225 pub fn eq(self, other: Self, eps: Eps) -> bool {
227 self.center.eq(other.center, eps) && eps.eq(self.radius, other.radius)
228 }
229}