chemrust_nasl/geometry/intersections/
circle_sphere.rs1use nalgebra::Point3;
2
3use crate::geometry::{
4 approx_cmp_f64, intersections::circle_circle::coplanar_circle_circle_intersect, Circle3d,
5 CircleCircleIntersection, Sphere,
6};
7
8use super::{FloatOrdering, Intersect};
9
10#[derive(Debug, Clone, Copy)]
11pub enum CircleSphereIntersection {
12 Invalid,
13 Zero,
14 InsideSphere,
15 SphereInCircle,
16 Single(Point3<f64>),
17 Double(Point3<f64>, Point3<f64>),
18 Circle(Circle3d),
19}
20
21impl Intersect<Sphere> for Circle3d {
22 type Output = CircleSphereIntersection;
23
24 fn intersect(&self, rhs: &Sphere) -> Self::Output {
25 let cs_cc = self.center() - rhs.center();
26 let cut_at = self.n().dot(&cs_cc);
29 match approx_cmp_f64(cut_at.abs(), rhs.radius()) {
33 FloatOrdering::Greater => CircleSphereIntersection::Zero,
34 FloatOrdering::Equal => {
35 let projected_dist = (cs_cc.norm_squared() - rhs.radius().powi(2)).sqrt();
36 match approx_cmp_f64(projected_dist, self.radius()) {
37 FloatOrdering::Less => CircleSphereIntersection::SphereInCircle,
38 FloatOrdering::Equal => {
39 let p = rhs.center() + self.n().scale(cut_at);
40 CircleSphereIntersection::Single(p)
41 }
42 FloatOrdering::Greater => CircleSphereIntersection::Zero,
43 }
44 }
45 FloatOrdering::Less => {
46 let new_circle_center = rhs.center() + self.n().scale(cut_at);
47 let new_circle_radius = (rhs.radius().powi(2) - cut_at.powi(2)).sqrt();
49 let new_circle = Circle3d::new(new_circle_center, new_circle_radius, self.n());
50 let result = coplanar_circle_circle_intersect(self, &new_circle);
51 match result {
52 CircleCircleIntersection::Empty => CircleSphereIntersection::Zero,
53 CircleCircleIntersection::Single(p) => CircleSphereIntersection::Single(p),
54 CircleCircleIntersection::Double(p1, p2) => {
55 CircleSphereIntersection::Double(p1, p2)
56 }
57 CircleCircleIntersection::Overlap(c) => CircleSphereIntersection::Circle(c),
58 CircleCircleIntersection::Contains(inner, _outer) => {
59 if inner.radius() == self.radius() {
62 CircleSphereIntersection::InsideSphere
63 } else {
64 CircleSphereIntersection::SphereInCircle
65 }
66 }
67 CircleCircleIntersection::Invalid => CircleSphereIntersection::Invalid,
68 }
69 }
70 }
71 }
72}