void_graph/graph/
geometry.rs1use std::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
7
8#[derive(Debug, Clone, Copy, PartialEq)]
9pub struct Point {
10 pub x: f64,
11 pub y: f64,
12}
13
14impl Point {
15 pub fn new(x: f64, y: f64) -> Self {
16 Self { x, y }
17 }
18
19 pub fn is_inside_polygon(&self, vertices: &[Point]) -> bool {
20 if vertices.len() < 3 {
21 return false;
22 }
23
24 let signs = vertices
25 .iter()
26 .zip(vertices.iter().cycle().skip(1))
27 .map(|(&a, &b)| {
28 let edge_vector = b - a;
29 let point_vector = *self - a;
30 edge_vector.cross(point_vector).signum()
31 })
32 .collect::<Vec<_>>();
33
34 let first_sign = signs[0];
35 if first_sign == 0.0 {
36 return true;
37 }
38
39 signs.iter().all(|&s| s == 0.0 || s == first_sign)
40 }
41}
42
43impl Add<Vector> for Point {
44 type Output = Point;
45
46 fn add(self, rhs: Vector) -> Self::Output {
47 Point {
48 x: self.x + rhs.x,
49 y: self.y + rhs.y,
50 }
51 }
52}
53
54impl Sub for Point {
55 type Output = Vector;
56
57 fn sub(self, rhs: Point) -> Self::Output {
58 Vector {
59 x: self.x - rhs.x,
60 y: self.y - rhs.y,
61 }
62 }
63}
64
65impl Sub<Vector> for Point {
66 type Output = Point;
67
68 fn sub(self, rhs: Vector) -> Self::Output {
69 Point {
70 x: self.x - rhs.x,
71 y: self.y - rhs.y,
72 }
73 }
74}
75
76#[derive(Debug, Clone, Copy, PartialEq)]
77pub struct Vector {
78 pub x: f64,
79 pub y: f64,
80}
81
82impl Vector {
83 pub fn new(x: f64, y: f64) -> Self {
84 Self { x, y }
85 }
86
87 pub fn length(&self) -> f64 {
88 (self.x.powi(2) + self.y.powi(2)).sqrt()
89 }
90
91 pub fn zero() -> Self {
92 Self { x: 0.0, y: 0.0 }
93 }
94
95 pub fn normalize(&self) -> Vector {
96 let len = self.length();
97 if len == 0.0 {
98 Vector::zero()
99 } else {
100 *self / len
101 }
102 }
103
104 pub fn perpendicular(&self) -> Vector {
105 Vector::new(-self.y, self.x)
106 }
107
108 pub fn dot(&self, other: Vector) -> f64 {
109 self.x * other.x + self.y * other.y
110 }
111
112 pub fn cross(&self, other: Vector) -> f64 {
113 self.x * other.y - self.y * other.x
114 }
115}
116
117impl Add for Vector {
118 type Output = Vector;
119
120 fn add(self, rhs: Vector) -> Self::Output {
121 Vector {
122 x: self.x + rhs.x,
123 y: self.y + rhs.y,
124 }
125 }
126}
127
128impl AddAssign for Vector {
129 fn add_assign(&mut self, rhs: Self) {
130 self.x += rhs.x;
131 self.y += rhs.y;
132 }
133}
134
135impl Sub for Vector {
136 type Output = Vector;
137
138 fn sub(self, rhs: Vector) -> Self::Output {
139 Vector {
140 x: self.x - rhs.x,
141 y: self.y - rhs.y,
142 }
143 }
144}
145
146impl SubAssign for Vector {
147 fn sub_assign(&mut self, rhs: Self) {
148 self.x -= rhs.x;
149 self.y -= rhs.y;
150 }
151}
152
153impl Mul<f64> for Vector {
154 type Output = Vector;
155
156 fn mul(self, rhs: f64) -> Self::Output {
157 Vector {
158 x: self.x * rhs,
159 y: self.y * rhs,
160 }
161 }
162}
163
164impl Mul<Vector> for f64 {
165 type Output = Vector;
166
167 fn mul(self, rhs: Vector) -> Self::Output {
168 rhs * self
169 }
170}
171
172impl Div<f64> for Vector {
173 type Output = Vector;
174
175 fn div(self, rhs: f64) -> Self::Output {
176 Vector {
177 x: self.x / rhs,
178 y: self.y / rhs,
179 }
180 }
181}
182
183pub fn bounding_box_u32(points: &[Point]) -> (u32, u32, u32, u32) {
184 let (mut min_x, mut min_y) = (f64::INFINITY, f64::INFINITY);
185 let (mut max_x, mut max_y) = (f64::NEG_INFINITY, f64::NEG_INFINITY);
186
187 for point in points {
188 if point.x < min_x {
189 min_x = point.x;
190 }
191 if point.y < min_y {
192 min_y = point.y;
193 }
194 if point.x > max_x {
195 max_x = point.x;
196 }
197 if point.y > max_y {
198 max_y = point.y;
199 }
200 }
201
202 (min_x as u32, min_y as u32, max_x as u32, max_y as u32)
203}