haar_lib/geom/
intersect_circles.rs1use crate::geom::*;
4
5#[derive(Clone, Copy, Debug, PartialEq)]
7#[allow(non_camel_case_types)]
8pub enum IntersectCircles {
9 SAME,
11 INSIDE,
13 INSCRIBED,
15 INTERSECTED,
17 CIRCUMSCRIBED,
19 OUTSIDE,
21}
22
23impl IntersectCircles {
24 pub fn same(self) -> bool {
26 self == Self::SAME
27 }
28 pub fn inside(self) -> bool {
30 self == Self::INSIDE
31 }
32 pub fn inscribed(self) -> bool {
34 self == Self::INSCRIBED
35 }
36 pub fn intersected(self) -> bool {
38 self == Self::INTERSECTED
39 }
40 pub fn circumscribed(self) -> bool {
42 self == Self::CIRCUMSCRIBED
43 }
44 pub fn outside(self) -> bool {
46 self == Self::OUTSIDE
47 }
48
49 pub fn num_common_tangent(self) -> Option<u32> {
51 use self::IntersectCircles::*;
52 match self {
53 SAME => None,
54 INSIDE => Some(0),
55 INSCRIBED => Some(1),
56 INTERSECTED => Some(2),
57 CIRCUMSCRIBED => Some(3),
58 OUTSIDE => Some(4),
59 }
60 }
61}
62
63pub fn intersect_circles(a: Circle, b: Circle, eps: Eps) -> (IntersectCircles, Vec<Vector>) {
65 use self::IntersectCircles::*;
66
67 let d = (a.center - b.center).abs();
68 let x = ((a.radius * a.radius + d * d - b.radius * b.radius) / (2.0 * d * a.radius)).acos();
69 let t = (b.center.1 - a.center.1).atan2(b.center.0 - a.center.0);
70
71 if eps.eq(a.radius + b.radius, d) {
72 (CIRCUMSCRIBED, vec![a.center + Vector::polar(a.radius, t)])
73 } else if eps.eq((a.radius - b.radius).abs(), d) {
74 (INSCRIBED, vec![a.center + Vector::polar(a.radius, t)])
75 } else if eps.gt(a.radius + b.radius, d) && eps.gt(d, (a.radius - b.radius).abs()) {
76 (
77 INTERSECTED,
78 vec![
79 a.center + Vector::polar(a.radius, t + x),
80 a.center + Vector::polar(a.radius, t - x),
81 ],
82 )
83 } else if eps.lt(a.radius + b.radius, d) {
84 (OUTSIDE, vec![])
85 } else if eps.gt((a.radius - b.radius).abs(), d) {
86 (INSIDE, vec![])
87 } else {
88 (SAME, vec![])
89 }
90}