# 2D (Circle)

Dec 4th, 2021
487
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. struct Circle: Point {
2.     double r;
3.     Circle(double x = 0, double y = 0, double r = 0): Point(x, y), r(r) {}
4.     Circle(Point p, double r): Point(p), r(r) {}
5.     bool contains(Point p) {
6.         return ( * this - p).len() <= r + EPS;
7.     }
8. };
9. double sqr(double a) {
10.     return a * a;
11. }
12. void tangents(Point c, double r1, double r2, vector < Line > & ans) {
13.     double r = r2 - r1;
14.     double z = sqr(c.x) + sqr(c.y);
15.     double d = z - sqr(r);
16.     if (d < -EPS) return;
17.     d = sqrt(fabs(d));
18.     Line l((c.x * r + c.y * d) / z, (c.y * r - c.x * d) / z, r1);
19.     ans.push_back(l);
20. }
21. vector < Line > tangents(Circle a, Circle b) {
22.     vector < Line > ans;
23.     ans.clear();
24.     for (int i = -1; i <= 1; i += 2)
25.         for (int j = -1; j <= 1; j += 2)
26.             tangents(b - a, a.r * i, b.r * j, ans);
27.     for (int i = 0; i < ans.size(); ++i)
28.         ans[i].c -= ans[i].a * a.x + ans[i].b * a.y;
29.     vector < Line > ret;
30.     for (int i = 0; i < ans.size(); ++i) {
31.         bool ok = true;
32.         for (int j = 0; j < ret.size(); ++j)
33.             if (areSame(ret[j], ans[i])) {
34.                 ok = false;
35.                 break;
36.             }
37.         if (ok) ret.push_back(ans[i]);
38.     }
39.     return ret;
40. }
41. vector < Point > intersection(Line l, Circle cir) {
42.     double r = cir.r, a = l.a, b = l.b, c = l.c + l.a * cir.x + l.b * cir.y;
43.     vector < Point > res;
44.     double x0 = -a * c / (a * a + b * b), y0 = -b * c / (a * a + b * b);
45.     if (c * c > r * r * (a * a + b * b) + EPS) return res;
46.     else if (fabs(c * c - r * r * (a * a + b * b)) < EPS) {
47.         res.push_back(Point(x0, y0) + Point(cir.x, cir.y));
48.         return res;
49.     } else {
50.         double d = r * r - c * c / (a * a + b * b);
51.         double mult = sqrt(d / (a * a + b * b));
52.         double ax, ay, bx, by;
53.         ax = x0 + b * mult;
54.         bx = x0 - b * mult;
55.         ay = y0 - a * mult;
56.         by = y0 + a * mult;
57.         res.push_back(Point(ax, ay) + Point(cir.x, cir.y));
58.         res.push_back(Point(bx, by) + Point(cir.x, cir.y));
59.         return res;
60.     }
61. }
62. double cir_area_solve(double a, double b, double c) {
63.     return acos((a * a + b * b - c * c) / 2 / a / b);
64. }
65. double cir_area_cut(double a, double r) {
66.     double s1 = a * r * r / 2;
67.     double s2 = sin(a) * r * r / 2;
68.     return s1 - s2;
69. }
70. double commonCircleArea(Circle c1, Circle c2) {
71.     if (c1.r < c2.r) swap(c1, c2);
72.     double d = (c1 - c2).len();
73.     if (d + c2.r <= c1.r + EPS) return c2.r * c2.r * PI;
74.     if (d >= c1.r + c2.r - EPS) return 0.0;
75.     double a1 = cir_area_solve(d, c1.r, c2.r);
76.     double a2 = cir_area_solve(d, c2.r, c1.r);
77.     return cir_area_cut(a1 * 2, c1.r) + cir_area_cut(a2 * 2, c2.r);
78. }
79. bool areIntersect(Circle u, Circle v) {
80.     if (cmp((u - v).len(), u.r + v.r) > 0) return false;
81.     if (cmp((u - v).len() + v.r, u.r) < 0) return false;
82.     if (cmp((u - v).len() + u.r, v.r) < 0) return false;
83.     return true;
84. }
85. vector < Point > circleIntersect(Circle u, Circle v) {
86.     vector < Point > res;
87.     if (!areIntersect(u, v)) return res;
88.     double d = (u - v).len();
89.     double alpha = acos((u.r * u.r + d * d - v.r * v.r) / 2.0 / u.r / d);
90.     Point p1 = (v - u).rotate(alpha);
91.     Point p2 = (v - u).rotate(-alpha);
92.     res.push_back(p1 / p1.len() * u.r + u);
93.     res.push_back(p2 / p2.len() * u.r + u);
94.     return res;
95. }