Advertisement
Merevoli

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. }
Advertisement
RAW Paste Data Copied
Advertisement