Description
Input
Output
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 #define sqr(x) ((x) * (x)) 8 9 typedef long long LL; 10 typedef long double LD; 11 12 const int MAXN = 55; 13 const double EPS = 1e-10; 14 const double PI = acos(-1.0);//3.14159265358979323846 15 const double INF = 1; 16 17 inline int sgn(double x) { 18 return (x > EPS) - (x < -EPS); 19 } 20 21 struct Point { 22 double x, y, ag; 23 Point() {} 24 Point(double x, double y): x(x), y(y) {} 25 void read() { 26 scanf("%lf%lf", &x, &y); 27 } 28 bool operator == (const Point &rhs) const { 29 return sgn(x - rhs.x) == 0 && sgn(y - rhs.y) == 0; 30 } 31 bool operator < (const Point &rhs) const { 32 if(y != rhs.y) return y < rhs.y; 33 return x < rhs.x; 34 } 35 Point operator + (const Point &rhs) const { 36 return Point(x + rhs.x, y + rhs.y); 37 } 38 Point operator - (const Point &rhs) const { 39 return Point(x - rhs.x, y - rhs.y); 40 } 41 Point operator * (const double &b) const { 42 return Point(x * b, y * b); 43 } 44 Point operator / (const double &b) const { 45 return Point(x / b, y / b); 46 } 47 double operator * (const Point &rhs) const { 48 return x * rhs.x + y * rhs.y; 49 } 50 double length() { 51 return sqrt(x * x + y * y); 52 } 53 double angle() { 54 return atan2(y, x); 55 } 56 Point unit() { 57 return *this / length(); 58 } 59 void makeAg() { 60 ag = atan2(y, x); 61 } 62 void print() { 63 printf("%.10f %.10f\n", x, y); 64 } 65 }; 66 typedef Point Vector; 67 68 double dist(const Point &a, const Point &b) { 69 return (a - b).length(); 70 } 71 72 double cross(const Point &a, const Point &b) { 73 return a.x * b.y - a.y * b.x; 74 } 75 //ret >= 0 means turn right 76 double cross(const Point &sp, const Point &ed, const Point &op) { 77 return cross(sp - op, ed - op); 78 } 79 80 double area(const Point& a, const Point &b, const Point &c) { 81 return fabs(cross(a - c, b - c)) / 2; 82 } 83 //counter-clockwise 84 Point rotate(const Point &p, double angle, const Point &o = Point(0, 0)) { 85 Point t = p - o; 86 double x = t.x * cos(angle) - t.y * sin(angle); 87 double y = t.y * cos(angle) + t.x * sin(angle); 88 return Point(x, y) + o; 89 } 90 91 double cosIncludeAngle(const Point &a, const Point &b, const Point &o) { 92 Point p1 = a - o, p2 = b - o; 93 return (p1 * p2) / (p1.length() * p2.length()); 94 } 95 96 double includedAngle(const Point &a, const Point &b, const Point &o) { 97 return acos(cosIncludeAngle(a, b, o)); 98 /* 99 double ret = abs((a - o).angle() - (b - o).angle()); 100 if(sgn(ret - PI) > 0) ret = 2 * PI - ret; 101 return ret; 102 */ 103 } 104 105 struct Seg { 106 Point st, ed; 107 double ag; 108 Seg() {} 109 Seg(Point st, Point ed): st(st), ed(ed) {} 110 void read() { 111 st.read(); ed.read(); 112 } 113 void makeAg() { 114 ag = atan2(ed.y - st.y, ed.x - st.x); 115 } 116 }; 117 typedef Seg Line; 118 119 //ax + by + c > 0 120 Line buildLine(double a, double b, double c) { 121 if(sgn(a) == 0 && sgn(b) == 0) return Line(Point(sgn(c) > 0 ? -1 : 1, INF), Point(0, INF)); 122 if(sgn(a) == 0) return Line(Point(sgn(b), -c/b), Point(0, -c/b)); 123 if(sgn(b) == 0) return Line(Point(-c/a, 0), Point(-c/a, sgn(a))); 124 if(b < 0) return Line(Point(0, -c/b), Point(1, -(a + c) / b)); 125 else return Line(Point(1, -(a + c) / b), Point(0, -c/b)); 126 } 127 128 void moveRight(Line &v, double r) { 129 double dx = v.ed.x - v.st.x, dy = v.ed.y - v.st.y; 130 dx = dx / dist(v.st, v.ed) * r; 131 dy = dy / dist(v.st, v.ed) * r; 132 v.st.x += dy; v.ed.x += dy; 133 v.st.y -= dx; v.ed.y -= dx; 134 } 135 136 bool isOnSeg(const Seg &s, const Point &p) { 137 return (p == s.st || p == s.ed) || 138 (((p.x - s.st.x) * (p.x - s.ed.x) < 0 || 139 (p.y - s.st.y) * (p.y - s.ed.y) < 0) && 140 sgn(cross(s.ed, p, s.st)) == 0); 141 } 142 143 bool isInSegRec(const Seg &s, const Point &p) { 144 return sgn(min(s.st.x, s.ed.x) - p.x) <= 0 && sgn(p.x - max(s.st.x, s.ed.x)) <= 0 145 && sgn(min(s.st.y, s.ed.y) - p.y) <= 0 && sgn(p.y - max(s.st.y, s.ed.y)) <= 0; 146 } 147 148 bool isIntersected(const Point &s1, const Point &e1, const Point &s2, const Point &e2) { 149 return (max(s1.x, e1.x) >= min(s2.x, e2.x)) && 150 (max(s2.x, e2.x) >= min(s1.x, e1.x)) && 151 (max(s1.y, e1.y) >= min(s2.y, e2.y)) && 152 (max(s2.y, e2.y) >= min(s1.y, e1.y)) && 153 (cross(s2, e1, s1) * cross(e1, e2, s1) >= 0) && 154 (cross(s1, e2, s2) * cross(e2, e1, s2) >= 0); 155 } 156 157 bool isIntersected(const Seg &a, const Seg &b) { 158 return isIntersected(a.st, a.ed, b.st, b.ed); 159 } 160 161 bool isParallel(const Seg &a, const Seg &b) { 162 return sgn(cross(a.ed - a.st, b.ed - b.st)) == 0; 163 } 164 165 //return Ax + By + C =0 's A, B, C 166 void Coefficient(const Line &L, double &A, double &B, double &C) { 167 A = L.ed.y - L.st.y; 168 B = L.st.x - L.ed.x; 169 C = L.ed.x * L.st.y - L.st.x * L.ed.y; 170 } 171 //point of intersection 172 Point operator * (const Line &a, const Line &b) { 173 double A1, B1, C1; 174 double A2, B2, C2; 175 Coefficient(a, A1, B1, C1); 176 Coefficient(b, A2, B2, C2); 177 Point I; 178 I.x = - (B2 * C1 - B1 * C2) / (A1 * B2 - A2 * B1); 179 I.y = (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1); 180 return I; 181 } 182 183 bool isEqual(const Line &a, const Line &b) { 184 double A1, B1, C1; 185 double A2, B2, C2; 186 Coefficient(a, A1, B1, C1); 187 Coefficient(b, A2, B2, C2); 188 return sgn(A1 * B2 - A2 * B1) == 0 && sgn(A1 * C2 - A2 * C1) == 0 && sgn(B1 * C2 - B2 * C1) == 0; 189 } 190 191 double Point_to_Line(const Point &p, const Line &L) { 192 return fabs(cross(p, L.st, L.ed)/dist(L.st, L.ed)); 193 } 194 195 double Point_to_Seg(const Point &p, const Seg &L) { 196 if(sgn((L.ed - L.st) * (p - L.st)) < 0) return dist(p, L.st); 197 if(sgn((L.st - L.ed) * (p - L.ed)) < 0) return dist(p, L.ed); 198 return Point_to_Line(p, L); 199 } 200 201 double Seg_to_Seg(const Seg &a, const Seg &b) { 202 double ans1 = min(Point_to_Seg(a.st, b), Point_to_Seg(a.ed, b)); 203 double ans2 = min(Point_to_Seg(b.st, a), Point_to_Seg(b.ed, a)); 204 return min(ans1, ans2); 205 } 206 207 struct Circle { 208 Point c; 209 double r; 210 Circle() {} 211 Circle(Point c, double r): c(c), r(r) {} 212 void read() { 213 c.read(); 214 scanf("%lf", &r); 215 } 216 double area() const { 217 return PI * r * r; 218 } 219 bool contain(const Circle &rhs) const { 220 return sgn(dist(c, rhs.c) + rhs.r - r) <= 0; 221 } 222 bool contain(const Point &p) const { 223 return sgn(dist(c, p) - r) <= 0; 224 } 225 bool intersect(const Circle &rhs) const { 226 return sgn(dist(c, rhs.c) - r - rhs.r) < 0; 227 } 228 bool tangency(const Circle &rhs) const { 229 return sgn(dist(c, rhs.c) - r - rhs.r) == 0; 230 } 231 Point pos(double angle) const { 232 Point p = Point(c.x + r, c.y); 233 return rotate(p, angle, c); 234 } 235 }; 236 237 double CommonArea(const Circle &A, const Circle &B) { 238 double area = 0.0; 239 const Circle & M = (A.r > B.r) ? A : B; 240 const Circle & N = (A.r > B.r) ? B : A; 241 double D = dist(M.c, N.c); 242 if((D < M.r + N.r) && (D > M.r - N.r)) { 243 double cosM = (M.r * M.r + D * D - N.r * N.r) / (2.0 * M.r * D); 244 double cosN = (N.r * N.r + D * D - M.r * M.r) / (2.0 * N.r * D); 245 double alpha = 2 * acos(cosM); 246 double beta = 2 * acos(cosN); 247 double TM = 0.5 * M.r * M.r * (alpha - sin(alpha)); 248 double TN = 0.5 * N.r * N.r * (beta - sin(beta)); 249 area = TM + TN; 250 } 251 else if(D <= M.r - N.r) { 252 area = N.area(); 253 } 254 return area; 255 } 256 257 int intersection(const Seg &s, const Circle &cir, Point &p1, Point &p2) { 258 double angle = cosIncludeAngle(s.ed, cir.c, s.st); 259 //double angle1 = cos(includedAngle(s.ed, cir.c, s.st)); 260 double B = dist(cir.c, s.st); 261 double a = 1, b = -2 * B * angle, c = sqr(B) - sqr(cir.r); 262 double delta = sqr(b) - 4 * a * c; 263 if(sgn(delta) < 0) return 0; 264 if(sgn(delta) == 0) delta = 0; 265 double x1 = (-b - sqrt(delta)) / (2 * a), x2 = (-b + sqrt(delta)) / (2 * a); 266 Vector v = (s.ed - s.st).unit(); 267 p1 = s.st + v * x1; 268 p2 = s.st + v * x2; 269 return 1 + sgn(delta); 270 } 271 272 double CommonArea(const Circle &cir, Point p1, Point p2) { 273 if(p1 == cir.c || p2 == cir.c) return 0; 274 if(cir.contain(p1) && cir.contain(p2)) { 275 return area(cir.c, p1, p2); 276 } else if(!cir.contain(p1) && !cir.contain(p2)) { 277 Point q1, q2; 278 int t = intersection(Line(p1, p2), cir, q1, q2); 279 if(t == 0) { 280 double angle = includedAngle(p1, p2, cir.c); 281 return 0.5 * sqr(cir.r) * angle; 282 } else { 283 double angle1 = includedAngle(p1, p2, cir.c); 284 double angle2 = includedAngle(q1, q2, cir.c); 285 if(isInSegRec(Seg(p1, p2), q1))return 0.5 * sqr(cir.r) * (angle1 - angle2 + sin(angle2)); 286 else return 0.5 * sqr(cir.r) * angle1; 287 } 288 } else { 289 if(cir.contain(p2)) swap(p1, p2); 290 Point q1, q2; 291 intersection(Line(p1, p2), cir, q1, q2); 292 double angle = includedAngle(q2, p2, cir.c); 293 double a = area(cir.c, p1, q2); 294 double b = 0.5 * sqr(cir.r) * angle; 295 return a + b; 296 } 297 } 298 299 struct Triangle { 300 Point p[3]; 301 Triangle() {} 302 Triangle(Point *t) { 303 for(int i = 0; i < 3; ++i) p[i] = t[i]; 304 } 305 void read() { 306 for(int i = 0; i < 3; ++i) p[i].read(); 307 } 308 double area() const { 309 return ::area(p[0], p[1], p[2]); 310 } 311 Point& operator[] (int i) { 312 return p[i]; 313 } 314 }; 315 316 double CommonArea(Triangle tir, const Circle &cir) { 317 double ret = 0; 318 ret += sgn(cross(tir[0], cir.c, tir[1])) * CommonArea(cir, tir[0], tir[1]); 319 ret += sgn(cross(tir[1], cir.c, tir[2])) * CommonArea(cir, tir[1], tir[2]); 320 ret += sgn(cross(tir[2], cir.c, tir[0])) * CommonArea(cir, tir[2], tir[0]); 321 return abs(ret); 322 } 323 324 struct Poly { 325 int n; 326 Point p[MAXN];//p[n] = p[0] 327 void init(Point *pp, int nn) { 328 n = nn; 329 for(int i = 0; i < n; ++i) p[i] = pp[i]; 330 p[n] = p[0]; 331 } 332 double area() { 333 if(n < 3) return 0; 334 double s = p[0].y * (p[n - 1].x - p[1].x); 335 for(int i = 1; i < n; ++i) 336 s += p[i].y * (p[i - 1].x - p[i + 1].x); 337 return s / 2; 338 } 339 }; 340 //the convex hull is clockwise 341 void Graham_scan(Point *p, int n, int *stk, int &top) {//stk[0] = stk[top] 342 sort(p, p + n); 343 top = 1; 344 stk[0] = 0; stk[1] = 1; 345 for(int i = 2; i < n; ++i) { 346 while(top && cross(p[i], p[stk[top]], p[stk[top - 1]]) <= 0) --top; 347 stk[++top] = i; 348 } 349 int len = top; 350 stk[++top] = n - 2; 351 for(int i = n - 3; i >= 0; --i) { 352 while(top != len && cross(p[i], p[stk[top]], p[stk[top - 1]]) <= 0) --top; 353 stk[++top] = i; 354 } 355 } 356 //use for half_planes_cross 357 bool cmpAg(const Line &a, const Line &b) { 358 if(sgn(a.ag - b.ag) == 0) 359 return sgn(cross(b.ed, a.st, b.st)) < 0; 360 return a.ag < b.ag; 361 } 362 //clockwise, plane is on the right 363 bool half_planes_cross(Line *v, int vn, Poly &res, Line *deq) { 364 int i, n; 365 sort(v, v + vn, cmpAg); 366 for(i = n = 1; i < vn; ++i) { 367 if(sgn(v[i].ag - v[i-1].ag) == 0) continue; 368 v[n++] = v[i]; 369 } 370 int head = 0, tail = 1; 371 deq[0] = v[0], deq[1] = v[1]; 372 for(i = 2; i < n; ++i) { 373 if(isParallel(deq[tail - 1], deq[tail]) || isParallel(deq[head], deq[head + 1])) 374 return false; 375 while(head < tail && sgn(cross(v[i].ed, deq[tail - 1] * deq[tail], v[i].st)) > 0) 376 --tail; 377 while(head < tail && sgn(cross(v[i].ed, deq[head] * deq[head + 1], v[i].st)) > 0) 378 ++head; 379 deq[++tail] = v[i]; 380 } 381 while(head < tail && sgn(cross(deq[head].ed, deq[tail - 1] * deq[tail], deq[head].st)) > 0) 382 --tail; 383 while(head < tail && sgn(cross(deq[tail].ed, deq[head] * deq[head + 1], deq[tail].st)) > 0) 384 ++head; 385 if(tail <= head + 1) return false; 386 res.n = 0; 387 for(i = head; i < tail; ++i) 388 res.p[res.n++] = deq[i] * deq[i + 1]; 389 res.p[res.n++] = deq[head] * deq[tail]; 390 res.n = unique(res.p, res.p + res.n) - res.p; 391 res.p[res.n] = res.p[0]; 392 return true; 393 } 394 395 //ix and jx is the points whose distance is return, res.p[n - 1] = res.p[0], res must be clockwise 396 double dia_rotating_calipers(Poly &res, int &ix, int &jx) { 397 double dia = 0; 398 int q = 1; 399 for(int i = 0; i < res.n - 1; ++i) { 400 while(sgn(cross(res.p[i], res.p[q + 1], res.p[i + 1]) - cross(res.p[i], res.p[q], res.p[i + 1])) > 0) 401 q = (q + 1) % (res.n - 1); 402 if(sgn(dist(res.p[i], res.p[q]) - dia) > 0) { 403 dia = dist(res.p[i], res.p[q]); 404 ix = i; jx = q; 405 } 406 if(sgn(dist(res.p[i + 1], res.p[q]) - dia) > 0) { 407 dia = dist(res.p[i + 1], res.p[q]); 408 ix = i + 1; jx = q; 409 } 410 } 411 return dia; 412 } 413 //a and b must be clockwise, find the minimum distance between two convex hull 414 double half_rotating_calipers(Poly &a, Poly &b) { 415 int sa = 0, sb = 0; 416 for(int i = 0; i < a.n; ++i) if(sgn(a.p[i].y - a.p[sa].y) < 0) sa = i; 417 for(int i = 0; i < b.n; ++i) if(sgn(b.p[i].y - b.p[sb].y) < 0) sb = i; 418 double tmp, ans = dist(a.p[0], b.p[0]); 419 for(int i = 0; i < a.n; ++i) { 420 while(sgn(tmp = cross(a.p[sa], a.p[sa + 1], b.p[sb + 1]) - cross(a.p[sa], a.p[sa + 1], b.p[sb])) > 0) 421 sb = (sb + 1) % (b.n - 1); 422 if(sgn(tmp) < 0) ans = min(ans, Point_to_Seg(b.p[sb], Seg(a.p[sa], a.p[sa + 1]))); 423 else ans = min(ans, Seg_to_Seg(Seg(a.p[sa], a.p[sa + 1]), Seg(b.p[sb], b.p[sb + 1]))); 424 sa = (sa + 1) % (a.n - 1); 425 } 426 return ans; 427 } 428 429 double rotating_calipers(Poly &a, Poly &b) { 430 return min(half_rotating_calipers(a, b), half_rotating_calipers(b, a)); 431 } 432 //欧拉四面体公式AB, AC, AD, BC, BD, CD 433 double area(double p, double q, double r, double n, double m, double l) { 434 p *= p, q *= q, r *= r, n *= n, m *= m, l *= l; 435 long double ret = 0; 436 ret += LD(p) * q * r; 437 ret += LD(p + q - n) * (q + r - l) * (p + r - m) / 4; 438 ret -= LD(p + r - m) * q * (p + r - m) / 4; 439 ret -= LD(p + q - n) * (p + q - n) * r / 4; 440 ret -= LD(q + r - l) * (q + r - l) * p / 4; 441 return sqrt(ret / 36); 442 } 443 444 /*******************************************************************************************/ 445 446 Point p[MAXN]; 447 Circle cir; 448 double r; 449 int n; 450 451 int main() { 452 double p, q, r, n, m, l; 453 while(cin>>p>>q>>r>>n>>m>>l) { 454 printf("%.4f\n", area(p, q, r, n, m, l)); 455 } 456 }