scirs2_spatial/collision/
shapes.rs1#[derive(Debug, Clone, Copy)]
12pub struct Circle {
13 pub center: [f64; 2],
15 pub radius: f64,
17}
18
19impl Circle {
20 pub fn new(center: [f64; 2], radius: f64) -> Self {
22 Circle { center, radius }
23 }
24
25 pub fn area(&self) -> f64 {
27 std::f64::consts::PI * self.radius * self.radius
28 }
29
30 pub fn contains_point(&self, point: &[f64; 2]) -> bool {
32 super::narrowphase::point_circle_collision(point, self)
33 }
34}
35
36#[derive(Debug, Clone, Copy)]
38pub struct LineSegment2D {
39 pub start: [f64; 2],
41 pub end: [f64; 2],
43}
44
45impl LineSegment2D {
46 pub fn new(start: [f64; 2], end: [f64; 2]) -> Self {
48 LineSegment2D { start, end }
49 }
50
51 pub fn length(&self) -> f64 {
53 let dx = self.end[0] - self.start[0];
54 let dy = self.end[1] - self.start[1];
55 (dx * dx + dy * dy).sqrt()
56 }
57}
58
59#[derive(Debug, Clone, Copy)]
61pub struct Triangle2D {
62 pub v1: [f64; 2],
64 pub v2: [f64; 2],
66 pub v3: [f64; 2],
68}
69
70impl Triangle2D {
71 pub fn new(a: [f64; 2], b: [f64; 2], c: [f64; 2]) -> Self {
73 Triangle2D {
74 v1: a,
75 v2: b,
76 v3: c,
77 }
78 }
79
80 pub fn area(&self) -> f64 {
82 0.5 * ((self.v2[0] - self.v1[0]) * (self.v3[1] - self.v1[1])
83 - (self.v3[0] - self.v1[0]) * (self.v2[1] - self.v1[1]))
84 .abs()
85 }
86
87 pub fn contains_point(&self, point: &[f64; 2]) -> bool {
89 super::narrowphase::point_triangle2d_collision(point, self)
90 }
91
92 pub fn a(&self) -> &[f64; 2] {
94 &self.v1
95 }
96
97 pub fn b(&self) -> &[f64; 2] {
99 &self.v2
100 }
101
102 pub fn c(&self) -> &[f64; 2] {
104 &self.v3
105 }
106}
107
108#[derive(Debug, Clone, Copy)]
110pub struct Box2D {
111 pub min: [f64; 2],
113 pub max: [f64; 2],
115}
116
117impl Box2D {
118 pub fn new(min: [f64; 2], max: [f64; 2]) -> Self {
120 Box2D { min, max }
121 }
122
123 pub fn width(&self) -> f64 {
125 self.max[0] - self.min[0]
126 }
127
128 pub fn height(&self) -> f64 {
130 self.max[1] - self.min[1]
131 }
132
133 pub fn area(&self) -> f64 {
135 self.width() * self.height()
136 }
137
138 pub fn center(&self) -> [f64; 2] {
140 [
141 (self.min[0] + self.max[0]) * 0.5,
142 (self.min[1] + self.max[1]) * 0.5,
143 ]
144 }
145
146 pub fn contains_point(&self, point: &[f64; 2]) -> bool {
148 super::narrowphase::point_box2d_collision(point, self)
149 }
150}
151
152#[derive(Debug, Clone, Copy)]
158pub struct Sphere {
159 pub center: [f64; 3],
161 pub radius: f64,
163}
164
165impl Sphere {
166 pub fn new(center: [f64; 3], radius: f64) -> Self {
168 Sphere { center, radius }
169 }
170
171 pub fn volume(&self) -> f64 {
173 (4.0 / 3.0) * std::f64::consts::PI * self.radius * self.radius * self.radius
174 }
175
176 pub fn contains_point(&self, point: &[f64; 3]) -> bool {
178 super::narrowphase::point_sphere_collision(point, self)
179 }
180}
181
182#[derive(Debug, Clone, Copy)]
184pub struct LineSegment3D {
185 pub start: [f64; 3],
187 pub end: [f64; 3],
189}
190
191impl LineSegment3D {
192 pub fn new(start: [f64; 3], end: [f64; 3]) -> Self {
194 LineSegment3D { start, end }
195 }
196
197 pub fn length(&self) -> f64 {
199 let dx = self.end[0] - self.start[0];
200 let dy = self.end[1] - self.start[1];
201 let dz = self.end[2] - self.start[2];
202 (dx * dx + dy * dy + dz * dz).sqrt()
203 }
204}
205
206#[derive(Debug, Clone, Copy)]
208pub struct Triangle3D {
209 pub v1: [f64; 3],
211 pub v2: [f64; 3],
213 pub v3: [f64; 3],
215}
216
217impl Triangle3D {
218 pub fn new(a: [f64; 3], b: [f64; 3], c: [f64; 3]) -> Self {
220 Triangle3D {
221 v1: a,
222 v2: b,
223 v3: c,
224 }
225 }
226
227 pub fn area(&self) -> f64 {
229 let edge1 = [
230 self.v2[0] - self.v1[0],
231 self.v2[1] - self.v1[1],
232 self.v2[2] - self.v1[2],
233 ];
234
235 let edge2 = [
236 self.v3[0] - self.v1[0],
237 self.v3[1] - self.v1[1],
238 self.v3[2] - self.v1[2],
239 ];
240
241 let cross = [
243 edge1[1] * edge2[2] - edge1[2] * edge2[1],
244 edge1[2] * edge2[0] - edge1[0] * edge2[2],
245 edge1[0] * edge2[1] - edge1[1] * edge2[0],
246 ];
247
248 0.5 * (cross[0] * cross[0] + cross[1] * cross[1] + cross[2] * cross[2]).sqrt()
250 }
251
252 pub fn normal(&self) -> [f64; 3] {
254 let edge1 = [
255 self.v2[0] - self.v1[0],
256 self.v2[1] - self.v1[1],
257 self.v2[2] - self.v1[2],
258 ];
259
260 let edge2 = [
261 self.v3[0] - self.v1[0],
262 self.v3[1] - self.v1[1],
263 self.v3[2] - self.v1[2],
264 ];
265
266 let normal = [
268 edge1[1] * edge2[2] - edge1[2] * edge2[1],
269 edge1[2] * edge2[0] - edge1[0] * edge2[2],
270 edge1[0] * edge2[1] - edge1[1] * edge2[0],
271 ];
272
273 let normal_length =
275 (normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]).sqrt();
276 if normal_length == 0.0 {
277 [0.0, 0.0, 0.0] } else {
279 [
280 normal[0] / normal_length,
281 normal[1] / normal_length,
282 normal[2] / normal_length,
283 ]
284 }
285 }
286
287 pub fn a(&self) -> &[f64; 3] {
289 &self.v1
290 }
291
292 pub fn b(&self) -> &[f64; 3] {
294 &self.v2
295 }
296
297 pub fn c(&self) -> &[f64; 3] {
299 &self.v3
300 }
301}
302
303#[derive(Debug, Clone, Copy)]
305pub struct Box3D {
306 pub min: [f64; 3],
308 pub max: [f64; 3],
310}
311
312impl Box3D {
313 pub fn new(min: [f64; 3], max: [f64; 3]) -> Self {
315 Box3D { min, max }
316 }
317
318 pub fn width(&self) -> f64 {
320 self.max[0] - self.min[0]
321 }
322
323 pub fn height(&self) -> f64 {
325 self.max[1] - self.min[1]
326 }
327
328 pub fn depth(&self) -> f64 {
330 self.max[2] - self.min[2]
331 }
332
333 pub fn volume(&self) -> f64 {
335 self.width() * self.height() * self.depth()
336 }
337
338 pub fn center(&self) -> [f64; 3] {
340 [
341 (self.min[0] + self.max[0]) * 0.5,
342 (self.min[1] + self.max[1]) * 0.5,
343 (self.min[2] + self.max[2]) * 0.5,
344 ]
345 }
346
347 pub fn contains_point(&self, point: &[f64; 3]) -> bool {
349 super::narrowphase::point_box3d_collision(point, self)
350 }
351}