rustsim_geometry/
sphere.rs1use crate::aabb::Aabb3;
4use crate::triangle::Triangle3;
5use crate::vec3::{self, Vec3};
6
7#[derive(Debug, Clone, Copy, PartialEq)]
9pub struct Sphere3 {
10 pub center: Vec3,
12 pub radius: f64,
14}
15
16impl Sphere3 {
17 pub fn intersects_aabb(&self, aabb: &Aabb3) -> bool {
19 let cx = self.center[0].clamp(aabb.min[0], aabb.max[0]);
20 let cy = self.center[1].clamp(aabb.min[1], aabb.max[1]);
21 let cz = self.center[2].clamp(aabb.min[2], aabb.max[2]);
22 let d = vec3::sub(self.center, [cx, cy, cz]);
23 vec3::norm_squared(d) <= self.radius * self.radius
24 }
25
26 pub fn intersects_triangle(&self, tri: &Triangle3) -> bool {
28 let q = tri.closest_point(self.center);
29 vec3::norm_squared(vec3::sub(self.center, q)) <= self.radius * self.radius
30 }
31
32 pub fn intersects(&self, other: &Sphere3) -> bool {
34 let d2 = vec3::norm_squared(vec3::sub(self.center, other.center));
35 let r = self.radius + other.radius;
36 d2 <= r * r
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn sphere_vs_aabb_overlap() {
46 let s = Sphere3 {
47 center: [0.0, 0.0, 0.0],
48 radius: 1.5,
49 };
50 let a = Aabb3::from_points([1.0, -1.0, -1.0], [3.0, 1.0, 1.0]);
51 assert!(s.intersects_aabb(&a));
52 let b = Aabb3::from_points([5.0, 5.0, 5.0], [10.0, 10.0, 10.0]);
53 assert!(!s.intersects_aabb(&b));
54 }
55
56 #[test]
57 fn sphere_vs_sphere() {
58 let a = Sphere3 {
59 center: [0.0, 0.0, 0.0],
60 radius: 1.0,
61 };
62 let b = Sphere3 {
63 center: [1.5, 0.0, 0.0],
64 radius: 1.0,
65 };
66 let c = Sphere3 {
67 center: [3.0, 0.0, 0.0],
68 radius: 0.5,
69 };
70 assert!(a.intersects(&b));
71 assert!(!a.intersects(&c));
72 }
73
74 #[test]
75 fn sphere_vs_triangle() {
76 let t = Triangle3 {
77 a: [0.0, 0.0, 0.0],
78 b: [1.0, 0.0, 0.0],
79 c: [0.0, 1.0, 0.0],
80 };
81 let s = Sphere3 {
82 center: [0.25, 0.25, 0.1],
83 radius: 0.5,
84 };
85 assert!(s.intersects_triangle(&t));
86 let s2 = Sphere3 {
87 center: [0.25, 0.25, 10.0],
88 radius: 0.5,
89 };
90 assert!(!s2.intersects_triangle(&t));
91 }
92}