fork download
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. // https://v...content-available-to-author-only...e.com/cp-geo.pdf
  5. const int N = 3e5 + 9;
  6.  
  7. const double inf = 1e100;
  8. const double eps = 1e-9;
  9. const double PI = acos((double)-1.0);
  10. int sign(double x) { return (x > eps) - (x < -eps); }
  11. struct PT {
  12. double x, y;
  13. PT() { x = 0, y = 0; }
  14. PT(double x, double y) : x(x), y(y) {}
  15. PT(const PT &p) : x(p.x), y(p.y) {}
  16. PT operator + (const PT &a) const { return PT(x + a.x, y + a.y); }
  17. PT operator - (const PT &a) const { return PT(x - a.x, y - a.y); }
  18. PT operator * (const double a) const { return PT(x * a, y * a); }
  19. friend PT operator * (const double &a, const PT &b) { return PT(a * b.x, a * b.y); }
  20. PT operator / (const double a) const { return PT(x / a, y / a); }
  21. bool operator == (PT a) const { return sign(a.x - x) == 0 && sign(a.y - y) == 0; }
  22. bool operator != (PT a) const { return !(*this == a); }
  23. bool operator < (PT a) const { return sign(a.x - x) == 0 ? y < a.y : x < a.x; }
  24. bool operator > (PT a) const { return sign(a.x - x) == 0 ? y > a.y : x > a.x; }
  25. double norm() { return sqrt(x * x + y * y); }
  26. double norm2() { return x * x + y * y; }
  27. PT perp() { return PT(-y, x); }
  28. double arg() { return atan2(y, x); }
  29. PT truncate(double r) { // returns a vector with norm r and having same direction
  30. double k = norm();
  31. if (!sign(k)) return *this;
  32. r /= k;
  33. return PT(x * r, y * r);
  34. }
  35. };
  36. istream &operator >> (istream &in, PT &p) { return in >> p.x >> p.y; }
  37. ostream &operator << (ostream &out, PT &p) { return out << "(" << p.x << "," << p.y << ")"; }
  38. inline double dot(PT a, PT b) { return a.x * b.x + a.y * b.y; }
  39. inline double dist2(PT a, PT b) { return dot(a - b, a - b); }
  40. inline double dist(PT a, PT b) { return sqrt(dot(a - b, a - b)); }
  41. inline double cross(PT a, PT b) { return a.x * b.y - a.y * b.x; }
  42. inline double cross2(PT a, PT b, PT c) { return cross(b - a, c - a); }
  43. inline int orientation(PT a, PT b, PT c) { return sign(cross(b - a, c - a)); }
  44. PT perp(PT a) { return PT(-a.y, a.x); }
  45. PT rotateccw90(PT a) { return PT(-a.y, a.x); }
  46. PT rotatecw90(PT a) { return PT(a.y, -a.x); }
  47. PT rotateccw(PT a, double t) { return PT(a.x * cos(t) - a.y * sin(t), a.x * sin(t) + a.y * cos(t)); }
  48. PT rotatecw(PT a, double t) { return PT(a.x * cos(t) + a.y * sin(t), -a.x * sin(t) + a.y * cos(t)); }
  49. double SQ(double x) { return x * x; }
  50. double rad_to_deg(double r) { return (r * 180.0 / PI); }
  51. double deg_to_rad(double d) { return (d * PI / 180.0); }
  52. double get_angle(PT a, PT b) {
  53. double costheta = dot(a, b) / a.norm() / b.norm();
  54. return acos(max((double)-1.0, min((double)1.0, costheta)));
  55. }
  56. bool is_point_in_angle(PT b, PT a, PT c, PT p) { // does point p lie in angle <bac
  57. assert(orientation(a, b, c) != 0);
  58. if (orientation(a, c, b) < 0) swap(b, c);
  59. return orientation(a, c, p) >= 0 && orientation(a, b, p) <= 0;
  60. }
  61. bool half(PT p) {
  62. return p.y > 0.0 || (p.y == 0.0 && p.x < 0.0);
  63. }
  64. void polar_sort(vector<PT> &v) { // sort points in counterclockwise
  65. sort(v.begin(), v.end(), [](PT a,PT b) {
  66. return make_tuple(half(a), 0.0, a.norm2()) < make_tuple(half(b), cross(a, b), b.norm2());
  67. });
  68. }
  69. void polar_sort(vector<PT> &v, PT o) { // sort points in counterclockwise with respect to point o
  70. sort(v.begin(), v.end(), [&](PT a,PT b) {
  71. return make_tuple(half(a - o), 0.0, (a - o).norm2()) < make_tuple(half(b - o), cross(a - o, b - o), (b - o).norm2());
  72. });
  73. }
  74. struct line {
  75. PT a, b; // goes through points a and b
  76. PT v; double c; //line form: direction vec [cross] (x, y) = c
  77. line() {}
  78. //direction vector v and offset c
  79. line(PT v, double c) : v(v), c(c) {
  80. auto p = get_points();
  81. a = p.first; b = p.second;
  82. }
  83. // equation ax + by + c = 0
  84. line(double _a, double _b, double _c) : v({_b, -_a}), c(-_c) {
  85. auto p = get_points();
  86. a = p.first; b = p.second;
  87. }
  88. // goes through points p and q
  89. line(PT p, PT q) : v(q - p), c(cross(v, p)), a(p), b(q) {}
  90. pair<PT, PT> get_points() { //extract any two points from this line
  91. PT p, q; double a = -v.y, b = v.x; // ax + by = c
  92. if (sign(a) == 0) {
  93. p = PT(0, c / b);
  94. q = PT(1, c / b);
  95. }
  96. else if (sign(b) == 0) {
  97. p = PT(c / a, 0);
  98. q = PT(c / a, 1);
  99. }
  100. else {
  101. p = PT(0, c / b);
  102. q = PT(1, (c - a) / b);
  103. }
  104. return {p, q};
  105. }
  106. // ax + by + c = 0
  107. array<double, 3> get_abc() {
  108. double a = -v.y, b = v.x;
  109. return {a, b, -c};
  110. }
  111. // 1 if on the left, -1 if on the right, 0 if on the line
  112. int side(PT p) { return sign(cross(v, p) - c); }
  113. // line that is perpendicular to this and goes through point p
  114. line perpendicular_through(PT p) { return {p, p + perp(v)}; }
  115. // translate the line by vector t i.e. shifting it by vector t
  116. line translate(PT t) { return {v, c + cross(v, t)}; }
  117. // compare two points by their orthogonal projection on this line
  118. // a projection point comes before another if it comes first according to vector v
  119. bool cmp_by_projection(PT p, PT q) { return dot(v, p) < dot(v, q); }
  120. line shift_left(double d) {
  121. PT z = v.perp().truncate(d);
  122. return line(a + z, b + z);
  123. }
  124. };
  125. // find a point from a through b with distance d
  126. PT point_along_line(PT a, PT b, double d) {
  127. assert(a != b);
  128. return a + (((b - a) / (b - a).norm()) * d);
  129. }
  130. // projection point c onto line through a and b assuming a != b
  131. PT project_from_point_to_line(PT a, PT b, PT c) {
  132. return a + (b - a) * dot(c - a, b - a) / (b - a).norm2();
  133. }
  134. // reflection point c onto line through a and b assuming a != b
  135. PT reflection_from_point_to_line(PT a, PT b, PT c) {
  136. PT p = project_from_point_to_line(a,b,c);
  137. return p + p - c;
  138. }
  139. // minimum distance from point c to line through a and b
  140. double dist_from_point_to_line(PT a, PT b, PT c) {
  141. return fabs(cross(b - a, c - a) / (b - a).norm());
  142. }
  143. // returns true if point p is on line segment ab
  144. bool is_point_on_seg(PT a, PT b, PT p) {
  145. if (fabs(cross(p - b, a - b)) < eps) {
  146. if (p.x < min(a.x, b.x) - eps || p.x > max(a.x, b.x) + eps) return false;
  147. if (p.y < min(a.y, b.y) - eps || p.y > max(a.y, b.y) + eps) return false;
  148. return true;
  149. }
  150. return false;
  151. }
  152. // minimum distance point from point c to segment ab that lies on segment ab
  153. PT project_from_point_to_seg(PT a, PT b, PT c) {
  154. double r = dist2(a, b);
  155. if (sign(r) == 0) return a;
  156. r = dot(c - a, b - a) / r;
  157. if (r < 0) return a;
  158. if (r > 1) return b;
  159. return a + (b - a) * r;
  160. }
  161. // minimum distance from point c to segment ab
  162. double dist_from_point_to_seg(PT a, PT b, PT c) {
  163. return dist(c, project_from_point_to_seg(a, b, c));
  164. }
  165. // 0 if not parallel, 1 if parallel, 2 if collinear
  166. int is_parallel(PT a, PT b, PT c, PT d) {
  167. double k = fabs(cross(b - a, d - c));
  168. if (k < eps){
  169. if (fabs(cross(a - b, a - c)) < eps && fabs(cross(c - d, c - a)) < eps) return 2;
  170. else return 1;
  171. }
  172. else return 0;
  173. }
  174. // check if two lines are same
  175. bool are_lines_same(PT a, PT b, PT c, PT d) {
  176. if (fabs(cross(a - c, c - d)) < eps && fabs(cross(b - c, c - d)) < eps) return true;
  177. return false;
  178. }
  179. // bisector vector of <abc
  180. PT angle_bisector(PT &a, PT &b, PT &c){
  181. PT p = a - b, q = c - b;
  182. return p + q * sqrt(dot(p, p) / dot(q, q));
  183. }
  184. // 1 if point is ccw to the line, 2 if point is cw to the line, 3 if point is on the line
  185. int point_line_relation(PT a, PT b, PT p) {
  186. int c = sign(cross(p - a, b - a));
  187. if (c < 0) return 1;
  188. if (c > 0) return 2;
  189. return 3;
  190. }
  191. // intersection point between ab and cd assuming unique intersection exists
  192. bool line_line_intersection(PT a, PT b, PT c, PT d, PT &ans) {
  193. double a1 = a.y - b.y, b1 = b.x - a.x, c1 = cross(a, b);
  194. double a2 = c.y - d.y, b2 = d.x - c.x, c2 = cross(c, d);
  195. double det = a1 * b2 - a2 * b1;
  196. if (det == 0) return 0;
  197. ans = PT((b1 * c2 - b2 * c1) / det, (c1 * a2 - a1 * c2) / det);
  198. return 1;
  199. }
  200. // intersection point between segment ab and segment cd assuming unique intersection exists
  201. bool seg_seg_intersection(PT a, PT b, PT c, PT d, PT &ans) {
  202. double oa = cross2(c, d, a), ob = cross2(c, d, b);
  203. double oc = cross2(a, b, c), od = cross2(a, b, d);
  204. if (oa * ob < 0 && oc * od < 0){
  205. ans = (a * ob - b * oa) / (ob - oa);
  206. return 1;
  207. }
  208. else return 0;
  209. }
  210. // intersection point between segment ab and segment cd assuming unique intersection may not exists
  211. // se.size()==0 means no intersection
  212. // se.size()==1 means one intersection
  213. // se.size()==2 means range intersection
  214. set<PT> seg_seg_intersection_inside(PT a, PT b, PT c, PT d) {
  215. PT ans;
  216. if (seg_seg_intersection(a, b, c, d, ans)) return {ans};
  217. set<PT> se;
  218. if (is_point_on_seg(c, d, a)) se.insert(a);
  219. if (is_point_on_seg(c, d, b)) se.insert(b);
  220. if (is_point_on_seg(a, b, c)) se.insert(c);
  221. if (is_point_on_seg(a, b, d)) se.insert(d);
  222. return se;
  223. }
  224. // intersection between segment ab and line cd
  225. // 0 if do not intersect, 1 if proper intersect, 2 if segment intersect
  226. int seg_line_relation(PT a, PT b, PT c, PT d) {
  227. double p = cross2(c, d, a);
  228. double q = cross2(c, d, b);
  229. if (sign(p) == 0 && sign(q) == 0) return 2;
  230. else if (p * q < 0) return 1;
  231. else return 0;
  232. }
  233. // intersection between segament ab and line cd assuming unique intersection exists
  234. bool seg_line_intersection(PT a, PT b, PT c, PT d, PT &ans) {
  235. bool k = seg_line_relation(a, b, c, d);
  236. assert(k != 2);
  237. if (k) line_line_intersection(a, b, c, d, ans);
  238. return k;
  239. }
  240. // minimum distance from segment ab to segment cd
  241. double dist_from_seg_to_seg(PT a, PT b, PT c, PT d) {
  242. PT dummy;
  243. if (seg_seg_intersection(a, b, c, d, dummy)) return 0.0;
  244. else return min({dist_from_point_to_seg(a, b, c), dist_from_point_to_seg(a, b, d),
  245. dist_from_point_to_seg(c, d, a), dist_from_point_to_seg(c, d, b)});
  246. }
  247. // minimum distance from point c to ray (starting point a and direction vector b)
  248. double dist_from_point_to_ray(PT a, PT b, PT c) {
  249. b = a + b;
  250. double r = dot(c - a, b - a);
  251. if (r < 0.0) return dist(c, a);
  252. return dist_from_point_to_line(a, b, c);
  253. }
  254. // starting point as and direction vector ad
  255. bool ray_ray_intersection(PT as, PT ad, PT bs, PT bd) {
  256. double dx = bs.x - as.x, dy = bs.y - as.y;
  257. double det = bd.x * ad.y - bd.y * ad.x;
  258. if (fabs(det) < eps) return 0;
  259. double u = (dy * bd.x - dx * bd.y) / det;
  260. double v = (dy * ad.x - dx * ad.y) / det;
  261. if (sign(u) >= 0 && sign(v) >= 0) return 1;
  262. else return 0;
  263. }
  264. double ray_ray_distance(PT as, PT ad, PT bs, PT bd) {
  265. if (ray_ray_intersection(as, ad, bs, bd)) return 0.0;
  266. double ans = dist_from_point_to_ray(as, ad, bs);
  267. ans = min(ans, dist_from_point_to_ray(bs, bd, as));
  268. return ans;
  269. }
  270. struct circle {
  271. PT p; double r;
  272. circle() {}
  273. circle(PT _p, double _r): p(_p), r(_r) {};
  274. // center (x, y) and radius r
  275. circle(double x, double y, double _r): p(PT(x, y)), r(_r) {};
  276. // circumcircle of a triangle
  277. // the three points must be unique
  278. circle(PT a, PT b, PT c) {
  279. b = (a + b) * 0.5;
  280. c = (a + c) * 0.5;
  281. line_line_intersection(b, b + rotatecw90(a - b), c, c + rotatecw90(a - c), p);
  282. r = dist(a, p);
  283. }
  284. // inscribed circle of a triangle
  285. // pass a bool just to differentiate from circumcircle
  286. circle(PT a, PT b, PT c, bool t) {
  287. line u, v;
  288. double m = atan2(b.y - a.y, b.x - a.x), n = atan2(c.y - a.y, c.x - a.x);
  289. u.a = a;
  290. u.b = u.a + (PT(cos((n + m)/2.0), sin((n + m)/2.0)));
  291. v.a = b;
  292. m = atan2(a.y - b.y, a.x - b.x), n = atan2(c.y - b.y, c.x - b.x);
  293. v.b = v.a + (PT(cos((n + m)/2.0), sin((n + m)/2.0)));
  294. line_line_intersection(u.a, u.b, v.a, v.b, p);
  295. r = dist_from_point_to_seg(a, b, p);
  296. }
  297. bool operator == (circle v) { return p == v.p && sign(r - v.r) == 0; }
  298. double area() { return PI * r * r; }
  299. double circumference() { return 2.0 * PI * r; }
  300. };
  301. //0 if outside, 1 if on circumference, 2 if inside circle
  302. int circle_point_relation(PT p, double r, PT b) {
  303. double d = dist(p, b);
  304. if (sign(d - r) < 0) return 2;
  305. if (sign(d - r) == 0) return 1;
  306. return 0;
  307. }
  308. // 0 if outside, 1 if on circumference, 2 if inside circle
  309. int circle_line_relation(PT p, double r, PT a, PT b) {
  310. double d = dist_from_point_to_line(a, b, p);
  311. if (sign(d - r) < 0) return 2;
  312. if (sign(d - r) == 0) return 1;
  313. return 0;
  314. }
  315. //compute intersection of line through points a and b with
  316. //circle centered at c with radius r > 0
  317. vector<PT> circle_line_intersection(PT c, double r, PT a, PT b) {
  318. vector<PT> ret;
  319. b = b - a; a = a - c;
  320. double A = dot(b, b), B = dot(a, b);
  321. double C = dot(a, a) - r * r, D = B * B - A * C;
  322. if (D < -eps) return ret;
  323. ret.push_back(c + a + b * (-B + sqrt(D + eps)) / A);
  324. if (D > eps) ret.push_back(c + a + b * (-B - sqrt(D)) / A);
  325. return ret;
  326. }
  327. //5 - outside and do not intersect
  328. //4 - intersect outside in one point
  329. //3 - intersect in 2 points
  330. //2 - intersect inside in one point
  331. //1 - inside and do not intersect
  332. int circle_circle_relation(PT a, double r, PT b, double R) {
  333. double d = dist(a, b);
  334. if (sign(d - r - R) > 0) return 5;
  335. if (sign(d - r - R) == 0) return 4;
  336. double l = fabs(r - R);
  337. if (sign(d - r - R) < 0 && sign(d - l) > 0) return 3;
  338. if (sign(d - l) == 0) return 2;
  339. if (sign(d - l) < 0) return 1;
  340. assert(0); return -1;
  341. }
  342. vector<PT> circle_circle_intersection(PT a, double r, PT b, double R) {
  343. if (a == b && sign(r - R) == 0) return {PT(1e18, 1e18)};
  344. vector<PT> ret;
  345. double d = sqrt(dist2(a, b));
  346. if (d > r + R || d + min(r, R) < max(r, R)) return ret;
  347. double x = (d * d - R * R + r * r) / (2 * d);
  348. double y = sqrt(r * r - x * x);
  349. PT v = (b - a) / d;
  350. ret.push_back(a + v * x + rotateccw90(v) * y);
  351. if (y > 0) ret.push_back(a + v * x - rotateccw90(v) * y);
  352. return ret;
  353. }
  354. // returns two circle c1, c2 through points a, b and of radius r
  355. // 0 if there is no such circle, 1 if one circle, 2 if two circle
  356. int get_circle(PT a, PT b, double r, circle &c1, circle &c2) {
  357. vector<PT> v = circle_circle_intersection(a, r, b, r);
  358. int t = v.size();
  359. if (!t) return 0;
  360. c1.p = v[0], c1.r = r;
  361. if (t == 2) c2.p = v[1], c2.r = r;
  362. return t;
  363. }
  364. // returns two circle c1, c2 which is tangent to line u, goes through
  365. // point q and has radius r1; 0 for no circle, 1 if c1 = c2 , 2 if c1 != c2
  366. int get_circle(line u, PT q, double r1, circle &c1, circle &c2) {
  367. double d = dist_from_point_to_line(u.a, u.b, q);
  368. if (sign(d - r1 * 2.0) > 0) return 0;
  369. if (sign(d) == 0) {
  370. cout << u.v.x << ' ' << u.v.y << '\n';
  371. c1.p = q + rotateccw90(u.v).truncate(r1);
  372. c2.p = q + rotatecw90(u.v).truncate(r1);
  373. c1.r = c2.r = r1;
  374. return 2;
  375. }
  376. line u1 = line(u.a + rotateccw90(u.v).truncate(r1), u.b + rotateccw90(u.v).truncate(r1));
  377. line u2 = line(u.a + rotatecw90(u.v).truncate(r1), u.b + rotatecw90(u.v).truncate(r1));
  378. circle cc = circle(q, r1);
  379. PT p1, p2; vector<PT> v;
  380. v = circle_line_intersection(q, r1, u1.a, u1.b);
  381. if (!v.size()) v = circle_line_intersection(q, r1, u2.a, u2.b);
  382. v.push_back(v[0]);
  383. p1 = v[0], p2 = v[1];
  384. c1 = circle(p1, r1);
  385. if (p1 == p2) {
  386. c2 = c1;
  387. return 1;
  388. }
  389. c2 = circle(p2, r1);
  390. return 2;
  391. }
  392. // returns the circle such that for all points w on the circumference of the circle
  393. // dist(w, a) : dist(w, b) = rp : rq
  394. // rp != rq
  395. // https://e...content-available-to-author-only...a.org/wiki/Circles_of_Apollonius
  396. circle get_apollonius_circle(PT p, PT q, double rp, double rq ){
  397. rq *= rq ;
  398. rp *= rp ;
  399. double a = rq - rp ;
  400. assert(sign(a));
  401. double g = rq * p.x - rp * q.x ; g /= a ;
  402. double h = rq * p.y - rp * q.y ; h /= a ;
  403. double c = rq * p.x * p.x - rp * q.x * q.x + rq * p.y * p.y - rp * q.y * q.y ;
  404. c /= a ;
  405. PT o(g, h);
  406. double r = g * g + h * h - c ;
  407. r = sqrt(r);
  408. return circle(o,r);
  409. }
  410. // returns area of intersection between two circles
  411. double circle_circle_area(PT a, double r1, PT b, double r2) {
  412. double d = (a - b).norm();
  413. if(r1 + r2 < d + eps) return 0;
  414. if(r1 + d < r2 + eps) return PI * r1 * r1;
  415. if(r2 + d < r1 + eps) return PI * r2 * r2;
  416. double theta_1 = acos((r1 * r1 + d * d - r2 * r2) / (2 * r1 * d)),
  417. theta_2 = acos((r2 * r2 + d * d - r1 * r1)/(2 * r2 * d));
  418. return r1 * r1 * (theta_1 - sin(2 * theta_1)/2.) + r2 * r2 * (theta_2 - sin(2 * theta_2)/2.);
  419. }
  420. // tangent lines from point q to the circle
  421. int tangent_lines_from_point(PT p, double r, PT q, line &u, line &v) {
  422. int x = sign(dist2(p, q) - r * r);
  423. if (x < 0) return 0; // point in cricle
  424. if (x == 0) { // point on circle
  425. u = line(q, q + rotateccw90(q - p));
  426. v = u;
  427. return 1;
  428. }
  429. double d = dist(p, q);
  430. double l = r * r / d;
  431. double h = sqrt(r * r - l * l);
  432. u = line(q, p + ((q - p).truncate(l) + (rotateccw90(q - p).truncate(h))));
  433. v = line(q, p + ((q - p).truncate(l) + (rotatecw90(q - p).truncate(h))));
  434. return 2;
  435. }
  436. // returns outer tangents line of two circles
  437. // if inner == 1 it returns inner tangent lines
  438. int tangents_lines_from_circle(PT c1, double r1, PT c2, double r2, bool inner, line &u, line &v) {
  439. if (inner) r2 = -r2;
  440. PT d = c2 - c1;
  441. double dr = r1 - r2, d2 = d.norm2(), h2 = d2 - dr * dr;
  442. if (d2 == 0 || h2 < 0) {
  443. assert(h2 != 0);
  444. return 0;
  445. }
  446. vector<pair<PT, PT>>out;
  447. for (int tmp: {- 1, 1}) {
  448. PT v = (d * dr + rotateccw90(d) * sqrt(h2) * tmp) / d2;
  449. out.push_back({c1 + v * r1, c2 + v * r2});
  450. }
  451. u = line(out[0].first, out[0].second);
  452. if (out.size() == 2) v = line(out[1].first, out[1].second);
  453. return 1 + (h2 > 0);
  454. }
  455. // O(n^2 log n)
  456. // https://v...content-available-to-author-only...e.net/problem/UVA-12056
  457. struct CircleUnion {
  458. int n;
  459. double x[2020], y[2020], r[2020];
  460. int covered[2020];
  461. vector<pair<double, double> > seg, cover;
  462. double arc, pol;
  463. inline int sign(double x) {return x < -eps ? -1 : x > eps;}
  464. inline int sign(double x, double y) {return sign(x - y);}
  465. inline double SQ(const double x) {return x * x;}
  466. inline double dist(double x1, double y1, double x2, double y2) {return sqrt(SQ(x1 - x2) + SQ(y1 - y2));}
  467. inline double angle(double A, double B, double C) {
  468. double val = (SQ(A) + SQ(B) - SQ(C)) / (2 * A * B);
  469. if (val < -1) val = -1;
  470. if (val > +1) val = +1;
  471. return acos(val);
  472. }
  473. CircleUnion() {
  474. n = 0;
  475. seg.clear(), cover.clear();
  476. arc = pol = 0;
  477. }
  478. void init() {
  479. n = 0;
  480. seg.clear(), cover.clear();
  481. arc = pol = 0;
  482. }
  483. void add(double xx, double yy, double rr) {
  484. x[n] = xx, y[n] = yy, r[n] = rr, covered[n] = 0, n++;
  485. }
  486. void getarea(int i, double lef, double rig) {
  487. arc += 0.5 * r[i] * r[i] * (rig - lef - sin(rig - lef));
  488. double x1 = x[i] + r[i] * cos(lef), y1 = y[i] + r[i] * sin(lef);
  489. double x2 = x[i] + r[i] * cos(rig), y2 = y[i] + r[i] * sin(rig);
  490. pol += x1 * y2 - x2 * y1;
  491. }
  492. double solve() {
  493. for (int i = 0; i < n; i++) {
  494. for (int j = 0; j < i; j++) {
  495. if (!sign(x[i] - x[j]) && !sign(y[i] - y[j]) && !sign(r[i] - r[j])) {
  496. r[i] = 0.0;
  497. break;
  498. }
  499. }
  500. }
  501. for (int i = 0; i < n; i++) {
  502. for (int j = 0; j < n; j++) {
  503. if (i != j && sign(r[j] - r[i]) >= 0 && sign(dist(x[i], y[i], x[j], y[j]) - (r[j] - r[i])) <= 0) {
  504. covered[i] = 1;
  505. break;
  506. }
  507. }
  508. }
  509. for (int i = 0; i < n; i++) {
  510. if (sign(r[i]) && !covered[i]) {
  511. seg.clear();
  512. for (int j = 0; j < n; j++) {
  513. if (i != j) {
  514. double d = dist(x[i], y[i], x[j], y[j]);
  515. if (sign(d - (r[j] + r[i])) >= 0 || sign(d - abs(r[j] - r[i])) <= 0) {
  516. continue;
  517. }
  518. double alpha = atan2(y[j] - y[i], x[j] - x[i]);
  519. double beta = angle(r[i], d, r[j]);
  520. pair<double, double> tmp(alpha - beta, alpha + beta);
  521. if (sign(tmp.first) <= 0 && sign(tmp.second) <= 0) {
  522. seg.push_back(pair<double, double>(2 * PI + tmp.first, 2 * PI + tmp.second));
  523. }
  524. else if (sign(tmp.first) < 0) {
  525. seg.push_back(pair<double, double>(2 * PI + tmp.first, 2 * PI));
  526. seg.push_back(pair<double, double>(0, tmp.second));
  527. }
  528. else {
  529. seg.push_back(tmp);
  530. }
  531. }
  532. }
  533. sort(seg.begin(), seg.end());
  534. double rig = 0;
  535. for (vector<pair<double, double> >::iterator iter = seg.begin(); iter != seg.end(); iter++) {
  536. if (sign(rig - iter->first) >= 0) {
  537. rig = max(rig, iter->second);
  538. }
  539. else {
  540. getarea(i, rig, iter->first);
  541. rig = iter->second;
  542. }
  543. }
  544. if (!sign(rig)) {
  545. arc += r[i] * r[i] * PI;
  546. }
  547. else {
  548. getarea(i, rig, 2 * PI);
  549. }
  550. }
  551. }
  552. return pol / 2.0 + arc;
  553. }
  554. } CU;
  555. double area_of_triangle(PT a, PT b, PT c) {
  556. return fabs(cross(b - a, c - a) * 0.5);
  557. }
  558. // -1 if strictly inside, 0 if on the polygon, 1 if strictly outside
  559. int is_point_in_triangle(PT a, PT b, PT c, PT p) {
  560. if (sign(cross(b - a,c - a)) < 0) swap(b, c);
  561. int c1 = sign(cross(b - a,p - a));
  562. int c2 = sign(cross(c - b,p - b));
  563. int c3 = sign(cross(a - c,p - c));
  564. if (c1<0 || c2<0 || c3 < 0) return 1;
  565. if (c1 + c2 + c3 != 3) return 0;
  566. return -1;
  567. }
  568. double perimeter(vector<PT> &p) {
  569. double ans=0; int n = p.size();
  570. for (int i = 0; i < n; i++) ans += dist(p[i], p[(i + 1) % n]);
  571. return ans;
  572. }
  573. double area(vector<PT> &p) {
  574. double ans = 0; int n = p.size();
  575. for (int i = 0; i < n; i++) ans += cross(p[i], p[(i + 1) % n]);
  576. return fabs(ans) * 0.5;
  577. }
  578. // centroid of a (possibly non-convex) polygon,
  579. // assuming that the coordinates are listed in a clockwise or
  580. // counterclockwise fashion. Note that the centroid is often known as
  581. // the "center of gravity" or "center of mass".
  582. PT centroid(vector<PT> &p) {
  583. int n = p.size(); PT c(0, 0);
  584. double sum = 0;
  585. for (int i = 0; i < n; i++) sum += cross(p[i], p[(i + 1) % n]);
  586. double scale = 3.0 * sum;
  587. for (int i = 0; i < n; i++) {
  588. int j = (i + 1) % n;
  589. c = c + (p[i] + p[j]) * cross(p[i], p[j]);
  590. }
  591. return c / scale;
  592. }
  593. // 0 if cw, 1 if ccw
  594. bool get_direction(vector<PT> &p) {
  595. double ans = 0; int n = p.size();
  596. for (int i = 0; i < n; i++) ans += cross(p[i], p[(i + 1) % n]);
  597. if (sign(ans) > 0) return 1;
  598. return 0;
  599. }
  600. // it returns a point such that the sum of distances
  601. // from that point to all points in p is minimum
  602. // O(n log^2 MX)
  603. PT geometric_median(vector<PT> p) {
  604. auto tot_dist = [&](PT z) {
  605. double res = 0;
  606. for (int i = 0; i < p.size(); i++) res += dist(p[i], z);
  607. return res;
  608. };
  609. auto findY = [&](double x) {
  610. double yl = -1e5, yr = 1e5;
  611. for (int i = 0; i < 60; i++) {
  612. double ym1 = yl + (yr - yl) / 3;
  613. double ym2 = yr - (yr - yl) / 3;
  614. double d1 = tot_dist(PT(x, ym1));
  615. double d2 = tot_dist(PT(x, ym2));
  616. if (d1 < d2) yr = ym2;
  617. else yl = ym1;
  618. }
  619. return pair<double, double> (yl, tot_dist(PT(x, yl)));
  620. };
  621. double xl = -1e5, xr = 1e5;
  622. for (int i = 0; i < 60; i++) {
  623. double xm1 = xl + (xr - xl) / 3;
  624. double xm2 = xr - (xr - xl) / 3;
  625. double y1, d1, y2, d2;
  626. auto z = findY(xm1); y1 = z.first; d1 = z.second;
  627. z = findY(xm2); y2 = z.first; d2 = z.second;
  628. if (d1 < d2) xr = xm2;
  629. else xl = xm1;
  630. }
  631. return {xl, findY(xl).first };
  632. }
  633. vector<PT> convex_hull(vector<PT> &p) {
  634. if (p.size() <= 1) return p;
  635. vector<PT> v = p;
  636. sort(v.begin(), v.end());
  637. vector<PT> up, dn;
  638. for (auto& p : v) {
  639. while (up.size() > 1 && orientation(up[up.size() - 2], up.back(), p) >= 0) {
  640. up.pop_back();
  641. }
  642. while (dn.size() > 1 && orientation(dn[dn.size() - 2], dn.back(), p) <= 0) {
  643. dn.pop_back();
  644. }
  645. up.push_back(p);
  646. dn.push_back(p);
  647. }
  648. v = dn;
  649. if (v.size() > 1) v.pop_back();
  650. reverse(up.begin(), up.end());
  651. up.pop_back();
  652. for (auto& p : up) {
  653. v.push_back(p);
  654. }
  655. if (v.size() == 2 && v[0] == v[1]) v.pop_back();
  656. return v;
  657. }
  658. //checks if convex or not
  659. bool is_convex(vector<PT> &p) {
  660. bool s[3]; s[0] = s[1] = s[2] = 0;
  661. int n = p.size();
  662. for (int i = 0; i < n; i++) {
  663. int j = (i + 1) % n;
  664. int k = (j + 1) % n;
  665. s[sign(cross(p[j] - p[i], p[k] - p[i])) + 1] = 1;
  666. if (s[0] && s[2]) return 0;
  667. }
  668. return 1;
  669. }
  670. // -1 if strictly inside, 0 if on the polygon, 1 if strictly outside
  671. // it must be strictly convex, otherwise make it strictly convex first
  672. int is_point_in_convex(vector<PT> &p, const PT& x) { // O(log n)
  673. int n = p.size(); assert(n >= 3);
  674. int a = orientation(p[0], p[1], x), b = orientation(p[0], p[n - 1], x);
  675. if (a < 0 || b > 0) return 1;
  676. int l = 1, r = n - 1;
  677. while (l + 1 < r) {
  678. int mid = l + r >> 1;
  679. if (orientation(p[0], p[mid], x) >= 0) l = mid;
  680. else r = mid;
  681. }
  682. int k = orientation(p[l], p[r], x);
  683. if (k <= 0) return -k;
  684. if (l == 1 && a == 0) return 0;
  685. if (r == n - 1 && b == 0) return 0;
  686. return -1;
  687. }
  688. bool is_point_on_polygon(vector<PT> &p, const PT& z) {
  689. int n = p.size();
  690. for (int i = 0; i < n; i++) {
  691. if (is_point_on_seg(p[i], p[(i + 1) % n], z)) return 1;
  692. }
  693. return 0;
  694. }
  695. // returns 1e9 if the point is on the polygon
  696. int winding_number(vector<PT> &p, const PT& z) { // O(n)
  697. if (is_point_on_polygon(p, z)) return 1e9;
  698. int n = p.size(), ans = 0;
  699. for (int i = 0; i < n; ++i) {
  700. int j = (i + 1) % n;
  701. bool below = p[i].y < z.y;
  702. if (below != (p[j].y < z.y)) {
  703. auto orient = orientation(z, p[j], p[i]);
  704. if (orient == 0) return 0;
  705. if (below == (orient > 0)) ans += below ? 1 : -1;
  706. }
  707. }
  708. return ans;
  709. }
  710. // -1 if strictly inside, 0 if on the polygon, 1 if strictly outside
  711. int is_point_in_polygon(vector<PT> &p, const PT& z) { // O(n)
  712. int k = winding_number(p, z);
  713. return k == 1e9 ? 0 : k == 0 ? 1 : -1;
  714. }
  715. // id of the vertex having maximum dot product with z
  716. // polygon must need to be convex
  717. // top - upper right vertex
  718. // for minimum dot product negate z and return -dot(z, p[id])
  719. int extreme_vertex(vector<PT> &p, const PT &z, const int top) { // O(log n)
  720. int n = p.size();
  721. if (n == 1) return 0;
  722. double ans = dot(p[0], z); int id = 0;
  723. if (dot(p[top], z) > ans) ans = dot(p[top], z), id = top;
  724. int l = 1, r = top - 1;
  725. while (l < r) {
  726. int mid = l + r >> 1;
  727. if (dot(p[mid + 1], z) >= dot(p[mid], z)) l = mid + 1;
  728. else r = mid;
  729. }
  730. if (dot(p[l], z) > ans) ans = dot(p[l], z), id = l;
  731. l = top + 1, r = n - 1;
  732. while (l < r) {
  733. int mid = l + r >> 1;
  734. if (dot(p[(mid + 1) % n], z) >= dot(p[mid], z)) l = mid + 1;
  735. else r = mid;
  736. }
  737. l %= n;
  738. if (dot(p[l], z) > ans) ans = dot(p[l], z), id = l;
  739. return id;
  740. }
  741. // maximum distance from any point on the perimeter to another point on the perimeter
  742. double diameter(vector<PT> &p) {
  743. int n = (int)p.size();
  744. if (n == 1) return 0;
  745. if (n == 2) return dist(p[0], p[1]);
  746. double ans = 0;
  747. int i = 0, j = 1;
  748. while (i < n) {
  749. while (cross(p[(i + 1) % n] - p[i], p[(j + 1) % n] - p[j]) >= 0) {
  750. ans = max(ans, dist2(p[i], p[j]));
  751. j = (j + 1) % n;
  752. }
  753. ans = max(ans, dist2(p[i], p[j]));
  754. i++;
  755. }
  756. return sqrt(ans);
  757. }
  758. // minimum distance between two parallel lines (non necessarily axis parallel)
  759. // such that the polygon can be put between the lines
  760. double width(vector<PT> &p) {
  761. int n = (int)p.size();
  762. if (n <= 2) return 0;
  763. double ans = inf;
  764. int i = 0, j = 1;
  765. while (i < n) {
  766. while (cross(p[(i + 1) % n] - p[i], p[(j + 1) % n] - p[j]) >= 0) j = (j + 1) % n;
  767. ans = min(ans, dist_from_point_to_line(p[i], p[(i + 1) % n], p[j]));
  768. i++;
  769. }
  770. return ans;
  771. }
  772. // minimum perimeter
  773. double minimum_enclosing_rectangle(vector<PT> &p) {
  774. int n = p.size();
  775. if (n <= 2) return perimeter(p);
  776. int mndot = 0; double tmp = dot(p[1] - p[0], p[0]);
  777. for (int i = 1; i < n; i++) {
  778. if (dot(p[1] - p[0], p[i]) <= tmp) {
  779. tmp = dot(p[1] - p[0], p[i]);
  780. mndot = i;
  781. }
  782. }
  783. double ans = inf;
  784. int i = 0, j = 1, mxdot = 1;
  785. while (i < n) {
  786. PT cur = p[(i + 1) % n] - p[i];
  787. while (cross(cur, p[(j + 1) % n] - p[j]) >= 0) j = (j + 1) % n;
  788. while (dot(p[(mxdot + 1) % n], cur) >= dot(p[mxdot], cur)) mxdot = (mxdot + 1) % n;
  789. while (dot(p[(mndot + 1) % n], cur) <= dot(p[mndot], cur)) mndot = (mndot + 1) % n;
  790. ans = min(ans, 2.0 * ((dot(p[mxdot], cur) / cur.norm() - dot(p[mndot], cur) / cur.norm()) + dist_from_point_to_line(p[i], p[(i + 1) % n], p[j])));
  791. i++;
  792. }
  793. return ans;
  794. }
  795. // given n points, find the minimum enclosing circle of the points
  796. // call convex_hull() before this for faster solution
  797. // expected O(n)
  798. circle minimum_enclosing_circle(vector<PT> &p) {
  799. random_shuffle(p.begin(), p.end());
  800. int n = p.size();
  801. circle c(p[0], 0);
  802. for (int i = 1; i < n; i++) {
  803. if (sign(dist(c.p, p[i]) - c.r) > 0) {
  804. c = circle(p[i], 0);
  805. for (int j = 0; j < i; j++) {
  806. if (sign(dist(c.p, p[j]) - c.r) > 0) {
  807. c = circle((p[i] + p[j]) / 2, dist(p[i], p[j]) / 2);
  808. for (int k = 0; k < j; k++) {
  809. if (sign(dist(c.p, p[k]) - c.r) > 0) {
  810. c = circle(p[i], p[j], p[k]);
  811. }
  812. }
  813. }
  814. }
  815. }
  816. }
  817. return c;
  818. }
  819. // returns a vector with the vertices of a polygon with everything
  820. // to the left of the line going from a to b cut away.
  821. vector<PT> cut(vector<PT> &p, PT a, PT b) {
  822. vector<PT> ans;
  823. int n = (int)p.size();
  824. for (int i = 0; i < n; i++) {
  825. double c1 = cross(b - a, p[i] - a);
  826. double c2 = cross(b - a, p[(i + 1) % n] - a);
  827. if (sign(c1) >= 0) ans.push_back(p[i]);
  828. if (sign(c1 * c2) < 0) {
  829. if (!is_parallel(p[i], p[(i + 1) % n], a, b)) {
  830. PT tmp; line_line_intersection(p[i], p[(i + 1) % n], a, b, tmp);
  831. ans.push_back(tmp);
  832. }
  833. }
  834. }
  835. return ans;
  836. }
  837. // not necessarily convex, boundary is included in the intersection
  838. // returns total intersected length
  839. // it returns the sum of the lengths of the portions of the line that are inside the polygon
  840. double polygon_line_intersection(vector<PT> p, PT a, PT b) {
  841. int n = p.size();
  842. p.push_back(p[0]);
  843. line l = line(a, b);
  844. double ans = 0.0;
  845. vector< pair<double, int> > vec;
  846. for (int i = 0; i < n; i++) {
  847. int s1 = orientation(a, b, p[i]);
  848. int s2 = orientation(a, b, p[i + 1]);
  849. if (s1 == s2) continue;
  850. line t = line(p[i], p[i + 1]);
  851. PT inter = (t.v * l.c - l.v * t.c) / cross(l.v, t.v);
  852. double tmp = dot(inter, l.v);
  853. int f;
  854. if (s1 > s2) f = s1 && s2 ? 2 : 1;
  855. else f = s1 && s2 ? -2 : -1;
  856. vec.push_back(make_pair((f > 0 ? tmp - eps : tmp + eps), f)); // keep eps very small like 1e-12
  857. }
  858. sort(vec.begin(), vec.end());
  859. for (int i = 0, j = 0; i + 1 < (int)vec.size(); i++){
  860. j += vec[i].second;
  861. if (j) ans += vec[i + 1].first - vec[i].first; // if this portion is inside the polygon
  862. // else ans = 0; // if we want the maximum intersected length which is totally inside the polygon, uncomment this and take the maximum of ans
  863. }
  864. ans = ans / sqrt(dot(l.v, l.v));
  865. p.pop_back();
  866. return ans;
  867. }
  868. // given a convex polygon p, and a line ab and the top vertex of the polygon
  869. // returns the intersection of the line with the polygon
  870. // it returns the indices of the edges of the polygon that are intersected by the line
  871. // so if it returns i, then the line intersects the edge (p[i], p[(i + 1) % n])
  872. array<int, 2> convex_line_intersection(vector<PT> &p, PT a, PT b, int top) {
  873. int end_a = extreme_vertex(p, (a - b).perp(), top);
  874. int end_b = extreme_vertex(p, (b - a).perp(), top);
  875. auto cmp_l = [&](int i) { return orientation(a, p[i], b); };
  876. if (cmp_l(end_a) < 0 || cmp_l(end_b) > 0)
  877. return {-1, -1}; // no intersection
  878. array<int, 2> res;
  879. for (int i = 0; i < 2; i++) {
  880. int lo = end_b, hi = end_a, n = p.size();
  881. while ((lo + 1) % n != hi) {
  882. int m = ((lo + hi + (lo < hi ? 0 : n)) / 2) % n;
  883. (cmp_l(m) == cmp_l(end_b) ? lo : hi) = m;
  884. }
  885. res[i] = (lo + !cmp_l(hi)) % n;
  886. swap(end_a, end_b);
  887. }
  888. if (res[0] == res[1]) return {res[0], -1}; // touches the vertex res[0]
  889. if (!cmp_l(res[0]) && !cmp_l(res[1]))
  890. switch ((res[0] - res[1] + (int)p.size() + 1) % p.size()) {
  891. case 0: return {res[0], res[0]}; // touches the edge (res[0], res[0] + 1)
  892. case 2: return {res[1], res[1]}; // touches the edge (res[1], res[1] + 1)
  893. }
  894. return res; // intersects the edges (res[0], res[0] + 1) and (res[1], res[1] + 1)
  895. }
  896.  
  897. pair<PT, int> point_poly_tangent(vector<PT> &p, PT Q, int dir, int l, int r) {
  898. while (r - l > 1) {
  899. int mid = (l + r) >> 1;
  900. bool pvs = orientation(Q, p[mid], p[mid - 1]) != -dir;
  901. bool nxt = orientation(Q, p[mid], p[mid + 1]) != -dir;
  902. if (pvs && nxt) return {p[mid], mid};
  903. if (!(pvs || nxt)) {
  904. auto p1 = point_poly_tangent(p, Q, dir, mid + 1, r);
  905. auto p2 = point_poly_tangent(p, Q, dir, l, mid - 1);
  906. return orientation(Q, p1.first, p2.first) == dir ? p1 : p2;
  907. }
  908. if (!pvs) {
  909. if (orientation(Q, p[mid], p[l]) == dir) r = mid - 1;
  910. else if (orientation(Q, p[l], p[r]) == dir) r = mid - 1;
  911. else l = mid + 1;
  912. }
  913. if (!nxt) {
  914. if (orientation(Q, p[mid], p[l]) == dir) l = mid + 1;
  915. else if (orientation(Q, p[l], p[r]) == dir) r = mid - 1;
  916. else l = mid + 1;
  917. }
  918. }
  919. pair<PT, int> ret = {p[l], l};
  920. for (int i = l + 1; i <= r; i++) ret = orientation(Q, ret.first, p[i]) != dir ? make_pair(p[i], i) : ret;
  921. return ret;
  922. }
  923. // (ccw, cw) tangents from a point that is outside this convex polygon
  924. // returns indexes of the points
  925. // ccw means the tangent from Q to that point is in the same direction as the polygon ccw direction
  926. pair<int, int> tangents_from_point_to_polygon(vector<PT> &p, PT Q){
  927. int ccw = point_poly_tangent(p, Q, 1, 0, (int)p.size() - 1).second;
  928. int cw = point_poly_tangent(p, Q, -1, 0, (int)p.size() - 1).second;
  929. return make_pair(ccw, cw);
  930. }
  931.  
  932. // minimum distance from a point to a convex polygon
  933. // it assumes point lie strictly outside the polygon
  934. double dist_from_point_to_polygon(vector<PT> &p, PT z) {
  935. double ans = inf;
  936. int n = p.size();
  937. if (n <= 3) {
  938. for(int i = 0; i < n; i++) ans = min(ans, dist_from_point_to_seg(p[i], p[(i + 1) % n], z));
  939. return ans;
  940. }
  941. auto [r, l] = tangents_from_point_to_polygon(p, z);
  942. if(l > r) r += n;
  943. while (l < r) {
  944. int mid = (l + r) >> 1;
  945. double left = dist2(p[mid % n], z), right= dist2(p[(mid + 1) % n], z);
  946. ans = min({ans, left, right});
  947. if(left < right) r = mid;
  948. else l = mid + 1;
  949. }
  950. ans = sqrt(ans);
  951. ans = min(ans, dist_from_point_to_seg(p[l % n], p[(l + 1) % n], z));
  952. ans = min(ans, dist_from_point_to_seg(p[l % n], p[(l - 1 + n) % n], z));
  953. return ans;
  954. }
  955. // minimum distance from convex polygon p to line ab
  956. // returns 0 is it intersects with the polygon
  957. // top - upper right vertex
  958. double dist_from_polygon_to_line(vector<PT> &p, PT a, PT b, int top) { //O(log n)
  959. PT orth = (b - a).perp();
  960. if (orientation(a, b, p[0]) > 0) orth = (a - b).perp();
  961. int id = extreme_vertex(p, orth, top);
  962. if (dot(p[id] - a, orth) > 0) return 0.0; //if orth and a are in the same half of the line, then poly and line intersects
  963. return dist_from_point_to_line(a, b, p[id]); //does not intersect
  964. }
  965. // minimum distance from a convex polygon to another convex polygon
  966. // the polygon doesnot overlap or touch
  967. // tested in https://t...content-available-to-author-only...h.co/p/the-wall
  968. double dist_from_polygon_to_polygon(vector<PT> &p1, vector<PT> &p2) { // O(n log n)
  969. double ans = inf;
  970. for (int i = 0; i < p1.size(); i++) {
  971. ans = min(ans, dist_from_point_to_polygon(p2, p1[i]));
  972. }
  973. for (int i = 0; i < p2.size(); i++) {
  974. ans = min(ans, dist_from_point_to_polygon(p1, p2[i]));
  975. }
  976. return ans;
  977. }
  978. // maximum distance from a convex polygon to another convex polygon
  979. double maximum_dist_from_polygon_to_polygon(vector<PT> &u, vector<PT> &v){ //O(n)
  980. int n = (int)u.size(), m = (int)v.size();
  981. double ans = 0;
  982. if (n < 3 || m < 3) {
  983. for (int i = 0; i < n; i++) {
  984. for (int j = 0; j < m; j++) ans = max(ans, dist2(u[i], v[j]));
  985. }
  986. return sqrt(ans);
  987. }
  988. if (u[0].x > v[0].x) swap(n, m), swap(u, v);
  989. int i = 0, j = 0, step = n + m + 10;
  990. while (j + 1 < m && v[j].x < v[j + 1].x) j++ ;
  991. while (step--) {
  992. if (cross(u[(i + 1)%n] - u[i], v[(j + 1)%m] - v[j]) >= 0) j = (j + 1) % m;
  993. else i = (i + 1) % n;
  994. ans = max(ans, dist2(u[i], v[j]));
  995. }
  996. return sqrt(ans);
  997. }
  998.  
  999. // calculates the area of the union of n polygons (not necessarily convex).
  1000. // the points within each polygon must be given in CCW order.
  1001. // complexity: O(N^2), where N is the total number of points
  1002. double rat(PT a, PT b, PT p) {
  1003. return !sign(a.x - b.x) ? (p.y - a.y) / (b.y - a.y) : (p.x - a.x) / (b.x - a.x);
  1004. };
  1005. double polygon_union(vector<vector<PT>> &p) {
  1006. int n = p.size();
  1007. double ans=0;
  1008. for(int i = 0; i < n; ++i) {
  1009. for (int v = 0; v < (int)p[i].size(); ++v) {
  1010. PT a = p[i][v], b = p[i][(v + 1) % p[i].size()];
  1011. vector<pair<double, int>> segs;
  1012. segs.emplace_back(0, 0), segs.emplace_back(1, 0);
  1013. for(int j = 0; j < n; ++j) {
  1014. if(i != j) {
  1015. for(size_t u = 0; u < p[j].size(); ++u) {
  1016. PT c = p[j][u], d = p[j][(u + 1) % p[j].size()];
  1017. int sc = sign(cross(b - a, c - a)), sd = sign(cross(b - a, d - a));
  1018. if(!sc && !sd) {
  1019. if(sign(dot(b - a, d - c)) > 0 && i > j) {
  1020. segs.emplace_back(rat(a, b, c), 1), segs.emplace_back(rat(a, b, d), -1);
  1021. }
  1022. }
  1023. else {
  1024. double sa = cross(d - c, a - c), sb = cross(d - c, b - c);
  1025. if(sc >= 0 && sd < 0) segs.emplace_back(sa / (sa - sb), 1);
  1026. else if(sc < 0 && sd >= 0) segs.emplace_back(sa / (sa - sb), -1);
  1027. }
  1028. }
  1029. }
  1030. }
  1031. sort(segs.begin(), segs.end());
  1032. double pre = min(max(segs[0].first, 0.0), 1.0), now, sum = 0;
  1033. int cnt = segs[0].second;
  1034. for(int j = 1; j < segs.size(); ++j) {
  1035. now = min(max(segs[j].first, 0.0), 1.0);
  1036. if (!cnt) sum += now - pre;
  1037. cnt += segs[j].second;
  1038. pre = now;
  1039. }
  1040. ans += cross(a, b) * sum;
  1041. }
  1042. }
  1043. return ans * 0.5;
  1044. }
  1045. // contains all points p such that: cross(b - a, p - a) >= 0
  1046. struct HP {
  1047. PT a, b;
  1048. HP() {}
  1049. HP(PT a, PT b) : a(a), b(b) {}
  1050. HP(const HP& rhs) : a(rhs.a), b(rhs.b) {}
  1051. int operator < (const HP& rhs) const {
  1052. PT p = b - a;
  1053. PT q = rhs.b - rhs.a;
  1054. int fp = (p.y < 0 || (p.y == 0 && p.x < 0));
  1055. int fq = (q.y < 0 || (q.y == 0 && q.x < 0));
  1056. if (fp != fq) return fp == 0;
  1057. if (cross(p, q)) return cross(p, q) > 0;
  1058. return cross(p, rhs.b - a) < 0;
  1059. }
  1060. PT line_line_intersection(PT a, PT b, PT c, PT d) {
  1061. b = b - a; d = c - d; c = c - a;
  1062. return a + b * cross(c, d) / cross(b, d);
  1063. }
  1064. PT intersection(const HP &v) {
  1065. return line_line_intersection(a, b, v.a, v.b);
  1066. }
  1067. };
  1068. int check(HP a, HP b, HP c) {
  1069. return cross(a.b - a.a, b.intersection(c) - a.a) > -eps; //-eps to include polygons of zero area (straight lines, points)
  1070. }
  1071. // consider half-plane of counter-clockwise side of each line
  1072. // if lines are not bounded add infinity rectangle
  1073. // returns a convex polygon, a point can occur multiple times though
  1074. // complexity: O(n log(n))
  1075. vector<PT> half_plane_intersection(vector<HP> h) {
  1076. sort(h.begin(), h.end());
  1077. vector<HP> tmp;
  1078. for (int i = 0; i < h.size(); i++) {
  1079. if (!i || cross(h[i].b - h[i].a, h[i - 1].b - h[i - 1].a)) {
  1080. tmp.push_back(h[i]);
  1081. }
  1082. }
  1083. h = tmp;
  1084. vector<HP> q(h.size() + 10);
  1085. int qh = 0, qe = 0;
  1086. for (int i = 0; i < h.size(); i++) {
  1087. while (qe - qh > 1 && !check(h[i], q[qe - 2], q[qe - 1])) qe--;
  1088. while (qe - qh > 1 && !check(h[i], q[qh], q[qh + 1])) qh++;
  1089. q[qe++] = h[i];
  1090. }
  1091. while (qe - qh > 2 && !check(q[qh], q[qe - 2], q[qe - 1])) qe--;
  1092. while (qe - qh > 2 && !check(q[qe - 1], q[qh], q[qh + 1])) qh++;
  1093. vector<HP> res;
  1094. for (int i = qh; i < qe; i++) res.push_back(q[i]);
  1095. vector<PT> hull;
  1096. if (res.size() > 2) {
  1097. for (int i = 0; i < res.size(); i++) {
  1098. hull.push_back(res[i].intersection(res[(i + 1) % ((int)res.size())]));
  1099. }
  1100. }
  1101. return hull;
  1102. }
  1103. // rotate the polygon such that the (bottom, left)-most point is at the first position
  1104. void reorder_polygon(vector<PT> &p) {
  1105. int pos = 0;
  1106. for (int i = 1; i < p.size(); i++) {
  1107. if (p[i].y < p[pos].y || (sign(p[i].y - p[pos].y) == 0 && p[i].x < p[pos].x)) pos = i;
  1108. }
  1109. rotate(p.begin(), p.begin() + pos, p.end());
  1110. }
  1111. // a and b are convex polygons
  1112. // returns a convex hull of their minkowski sum
  1113. // min(a.size(), b.size()) >= 2
  1114. // https://c...content-available-to-author-only...s.com/geometry/minkowski.html
  1115. vector<PT> minkowski_sum(vector<PT> a, vector<PT> b) {
  1116. reorder_polygon(a); reorder_polygon(b);
  1117. int n = a.size(), m = b.size();
  1118. int i = 0, j = 0;
  1119. a.push_back(a[0]); a.push_back(a[1]);
  1120. b.push_back(b[0]); b.push_back(b[1]);
  1121. vector<PT> c;
  1122. while (i < n || j < m) {
  1123. c.push_back(a[i] + b[j]);
  1124. double p = cross(a[i + 1] - a[i], b[j + 1] - b[j]);
  1125. if (sign(p) >= 0) ++i;
  1126. if (sign(p) <= 0) ++j;
  1127. }
  1128. return c;
  1129. }
  1130. // returns the area of the intersection of the circle with center c and radius r
  1131. // and the triangle formed by the points c, a, b
  1132. double _triangle_circle_intersection(PT c, double r, PT a, PT b) {
  1133. double sd1 = dist2(c, a), sd2 = dist2(c, b);
  1134. if(sd1 > sd2) swap(a, b), swap(sd1, sd2);
  1135. double sd = dist2(a, b);
  1136. double d1 = sqrtl(sd1), d2 = sqrtl(sd2), d = sqrt(sd);
  1137. double x = abs(sd2 - sd - sd1) / (2 * d);
  1138. double h = sqrtl(sd1 - x * x);
  1139. if(r >= d2) return h * d / 2;
  1140. double area = 0;
  1141. if(sd + sd1 < sd2) {
  1142. if(r < d1) area = r * r * (acos(h / d2) - acos(h / d1)) / 2;
  1143. else {
  1144. area = r * r * ( acos(h / d2) - acos(h / r)) / 2;
  1145. double y = sqrtl(r * r - h * h);
  1146. area += h * (y - x) / 2;
  1147. }
  1148. }
  1149. else {
  1150. if(r < h) area = r * r * (acos(h / d2) + acos(h / d1)) / 2;
  1151. else {
  1152. area += r * r * (acos(h / d2) - acos(h / r)) / 2;
  1153. double y = sqrtl(r * r - h * h);
  1154. area += h * y / 2;
  1155. if(r < d1) {
  1156. area += r * r * (acos(h / d1) - acos(h / r)) / 2;
  1157. area += h * y / 2;
  1158. }
  1159. else area += h * x / 2;
  1160. }
  1161. }
  1162. return area;
  1163. }
  1164. // intersection between a simple polygon and a circle
  1165. double polygon_circle_intersection(vector<PT> &v, PT p, double r) {
  1166. int n = v.size();
  1167. double ans = 0.00;
  1168. PT org = {0, 0};
  1169. for(int i = 0; i < n; i++) {
  1170. int x = orientation(p, v[i], v[(i + 1) % n]);
  1171. if(x == 0) continue;
  1172. double area = _triangle_circle_intersection(org, r, v[i] - p, v[(i + 1) % n] - p);
  1173. if (x < 0) ans -= area;
  1174. else ans += area;
  1175. }
  1176. return abs(ans);
  1177. }
  1178. // find a circle of radius r that contains as many points as possible
  1179. // O(n^2 log n);
  1180. double maximum_circle_cover(vector<PT> p, double r, circle &c) {
  1181. int n = p.size();
  1182. int ans = 0;
  1183. int id = 0; double th = 0;
  1184. for (int i = 0; i < n; ++i) {
  1185. // maximum circle cover when the circle goes through this point
  1186. vector<pair<double, int>> events = {{-PI, +1}, {PI, -1}};
  1187. for (int j = 0; j < n; ++j) {
  1188. if (j == i) continue;
  1189. double d = dist(p[i], p[j]);
  1190. if (d > r * 2) continue;
  1191. double dir = (p[j] - p[i]).arg();
  1192. double ang = acos(d / 2 / r);
  1193. double st = dir - ang, ed = dir + ang;
  1194. if (st > PI) st -= PI * 2;
  1195. if (st <= -PI) st += PI * 2;
  1196. if (ed > PI) ed -= PI * 2;
  1197. if (ed <= -PI) ed += PI * 2;
  1198. events.push_back({st - eps, +1}); // take care of precisions!
  1199. events.push_back({ed, -1});
  1200. if (st > ed) {
  1201. events.push_back({-PI, +1});
  1202. events.push_back({+PI, -1});
  1203. }
  1204. }
  1205. sort(events.begin(), events.end());
  1206. int cnt = 0;
  1207. for (auto &&e: events) {
  1208. cnt += e.second;
  1209. if (cnt > ans) {
  1210. ans = cnt;
  1211. id = i; th = e.first;
  1212. }
  1213. }
  1214. }
  1215. PT w = PT(p[id].x + r * cos(th), p[id].y + r * sin(th));
  1216. c = circle(w, r); //best_circle
  1217. return ans;
  1218. }
  1219. // radius of the maximum inscribed circle in a convex polygon
  1220. double maximum_inscribed_circle(vector<PT> p) {
  1221. int n = p.size();
  1222. if (n <= 2) return 0;
  1223. double l = 0, r = 20000;
  1224. while (r - l > eps) {
  1225. double mid = (l + r) * 0.5;
  1226. vector<HP> h;
  1227. const int L = 1e9;
  1228. h.push_back(HP(PT(-L, -L), PT(L, -L)));
  1229. h.push_back(HP(PT(L, -L), PT(L, L)));
  1230. h.push_back(HP(PT(L, L), PT(-L, L)));
  1231. h.push_back(HP(PT(-L, L), PT(-L, -L)));
  1232. for (int i = 0; i < n; i++) {
  1233. PT z = (p[(i + 1) % n] - p[i]).perp();
  1234. z = z.truncate(mid);
  1235. PT y = p[i] + z, q = p[(i + 1) % n] + z;
  1236. h.push_back(HP(p[i] + z, p[(i + 1) % n] + z));
  1237. }
  1238. vector<PT> nw = half_plane_intersection(h);
  1239. if (!nw.empty()) l = mid;
  1240. else r = mid;
  1241. }
  1242. return l;
  1243. }
  1244. // ear decomposition, O(n^3) but faster
  1245. vector<vector<PT>> triangulate(vector<PT> p) {
  1246. vector<vector<PT>> v;
  1247. while (p.size() >= 3) {
  1248. for (int i = 0, n = p.size(); i < n; i++) {
  1249. int pre = i == 0 ? n - 1 : i - 1;;
  1250. int nxt = i == n - 1 ? 0 : i + 1;;
  1251. int ori = orientation(p[i], p[pre], p[nxt]);
  1252. if (ori < 0) {
  1253. int ok = 1;
  1254. for (int j = 0; j < n; j++) {
  1255. if (j == i || j == pre || j == nxt)continue;
  1256. if (is_point_in_triangle(p[i], p[pre], p[nxt] , p[j]) < 1) {
  1257. ok = 0;
  1258. break;
  1259. }
  1260. }
  1261. if (ok) {
  1262. v.push_back({p[pre], p[i], p[nxt]});
  1263. p.erase(p.begin() + i);
  1264. break;
  1265. }
  1266. }
  1267. }
  1268. }
  1269. return v;
  1270. }
  1271.  
  1272. struct star {
  1273. int n; // number of sides of the star
  1274. double r; // radius of the circumcircle
  1275. star(int _n, double _r) {
  1276. n = _n;
  1277. r = _r;
  1278. }
  1279.  
  1280. double area() {
  1281. double theta = PI / n;
  1282. double s = 2 * r * sin(theta);
  1283. double R = 0.5 * s / tan(theta);
  1284. double a = 0.5 * n * s * R;
  1285. double a2 = 0.25 * s * s / tan(1.5 * theta);
  1286. return a - n * a2;
  1287. }
  1288. };
  1289.  
  1290. // given a list of lengths of the sides of a polygon in counterclockwise order
  1291. // returns the maximum area of a non-degenerate polygon that can be formed using those lengths
  1292. double get_maximum_polygon_area_for_given_lengths(vector<double> v) {
  1293. if (v.size() < 3) {
  1294. return 0;
  1295. }
  1296. int m = 0;
  1297. double sum = 0;
  1298. for (int i = 0; i < v.size(); i++) {
  1299. if (v[i] > v[m]) {
  1300. m = i;
  1301. }
  1302. sum += v[i];
  1303. }
  1304. if (sign(v[m] - (sum - v[m])) >= 0) {
  1305. return 0; // no non-degenerate polygon is possible
  1306. }
  1307. // the polygon should be a circular polygon
  1308. // that is all points are on the circumference of a circle
  1309. double l = v[m] / 2, r = 1e6; // fix it correctly
  1310. int it = 60;
  1311. auto ang = [](double x, double r) { // x = length of the chord, r = radius of the circle
  1312. return 2 * asin((x / 2) / r);
  1313. };
  1314. auto calc = [=](double r) {
  1315. double sum = 0;
  1316. for (auto x: v) {
  1317. sum += ang(x, r);
  1318. }
  1319. return sum;
  1320. };
  1321. // compute the radius of the circle
  1322. while (it--) {
  1323. double mid = (l + r) / 2;
  1324. if (calc(mid) <= 2 * PI) {
  1325. r = mid;
  1326. }
  1327. else {
  1328. l = mid;
  1329. }
  1330. }
  1331.  
  1332. if (calc(r) <= 2 * PI - eps) { // the center of the circle is outside the polygon
  1333. auto calc2 = [&](double r) {
  1334. double sum = 0;
  1335. for (int i = 0; i < v.size(); i++) {
  1336. double x = v[i];
  1337. double th = ang(x, r);
  1338. if (i != m) {
  1339. sum += th;
  1340. }
  1341. else {
  1342. sum += 2 * PI - th;
  1343. }
  1344. }
  1345. return sum;
  1346. };
  1347. l = v[m] / 2; r = 1e6;
  1348. it = 60;
  1349. while (it--) {
  1350. double mid = (l + r) / 2;
  1351. if (calc2(mid) > 2 * PI) {
  1352. r = mid;
  1353. }
  1354. else {
  1355. l = mid;
  1356. }
  1357. }
  1358. auto get_area = [=](double r) {
  1359. double ans = 0;
  1360. for (int i = 0; i < v.size(); i++) {
  1361. double x = v[i];
  1362. double area = r * r * sin(ang(x, r)) / 2;
  1363. if (i != m) {
  1364. ans += area;
  1365. }
  1366. else {
  1367. ans -= area;
  1368. }
  1369. }
  1370. return ans;
  1371. };
  1372. return get_area(r);
  1373. }
  1374. else { // the center of the circle is inside the polygon
  1375. auto get_area = [=](double r) {
  1376. double ans = 0;
  1377. for (auto x: v) {
  1378. ans += r * r * sin(ang(x, r)) / 2;
  1379. }
  1380. return ans;
  1381. };
  1382. return get_area(r);
  1383. }
  1384. }
  1385.  
  1386. int32_t main() {
  1387. ios_base::sync_with_stdio(0);
  1388. cin.tie(0);
  1389.  
  1390. return 0;
  1391. }
Success #stdin #stdout 0s 5328KB
stdin
Standard input is empty
stdout
Standard output is empty