#include using namespace std; typedef long double ld; const ld eps = 0.0000002; const ld pi = 3.14159265359; bool cmp(const ld &a, const ld &b) { return abs(a-b) < eps; } struct pnt { ld x, y; pnt (ld _x = 0, ld _y = 0) : x(_x), y(_y) {} pnt operator - (const pnt &p) const { return pnt(x - p.x, y - p.y); } pnt operator + (const pnt &p) const { return pnt(x + p.x, y + p.y); } ld operator * (const pnt &p) const { return x * p.y - y * p.x; } ld operator ^ (const pnt &p) const { return x * p.x + y * p.y; } ld mod2() { return x*x + y*y; } ld mod() { return sqrt(mod2()); } pnt operator * (const ld &a) const { return pnt (a * x, a * y); } }; bool cmp (const pnt &p1, const pnt &p2) { bool t1 = (p1.x > 0 || (p1.x == 0 && p1.y >= 0)); bool t2 = (p2.x > 0 || (p2.x == 0 && p2.y >= 0)); if (t1 != t2) return t1; return (p1*p2) < 0; } bool isInCircle(pnt s, ld R, pnt a) { ld w = (a.x - s.x) * (a.x - s.x) + (a.y - s.y) * (a.y - s.y); return w <= R * R; } pnt rzut (pnt a, pnt b, pnt c) { ld dot = (b-a) ^ (c-a); ld mod = (b-a).mod2(); return (b-a) * (dot/mod) + a; } bool isInSeg(pnt a, pnt b, pnt x) { if (a.x == b.x) { if (x.x == a.x) { if (x.y >= a.y && x.y <= b.y) return true; if (x.y >= b.y && x.y <= a.y) return true; } }else { if (x.y == a.y) { if (x.x >= a.x && x.x <= b.x) return true; if (x.x >= b.x && x.x <= a.x) return true; } } return false; } ld kat(pnt a, pnt b) { ld cross = a * b; ld dot = a ^ b; ld res = asin(cross / (a.mod() * b.mod())); res = abs(res); //cout << cross << " " << dot << " " << res << "\n"; if (cross >= 0 && dot >= 0) {} if (cross >= 0 && dot < 0) { //cout << "xd\n"; res += pi/(ld)2; } if (cross < 0 && dot <= 0) { res += pi; //cout << "xxd\n"; } if (cross <= 0 && dot > 0) { // cout << cross << "xxddd " << dot << "\n"; res += (ld)3*pi/(ld)2; } //cout << "res: " << res << "\n"; return res; } int main() { pnt s, a, b; ld r; cin >> s.x >> s.y >> r >> a.x >> a.y >> b.x >> b.y; a = a - s; b = b - s; s = s - s; if (a.x > b.x) swap(a.x, b.x); if (a.y > b.y) swap(a.y, b.y); pnt c = pnt(a.x, b.y); pnt d = pnt(b.x, a.y); swap(b, d); swap(d, c); if (!isInCircle(s,r,a)) { if (a.x < -r) { a.x = -r; } if (a.y < -r) a.y = -r; } if (!isInCircle(s,r,b)) { if (b.x > r) b.x = r; if (b.y < -r) b.y = -r; } if (!isInCircle(s,r,c) ){ if (c.x > r) c.x = r; if (c.y > r) c.y = r; } if (!isInCircle(s,r,d)) { if (d.x < -r) d.x = -r; if (d.y > r) d.y = r; } if (isInCircle(s,r,a) && isInCircle(s,r,b) && isInCircle(s,r,c) && isInCircle(s,r,d)) { cout << fixed << setprecision(8) << (c.x-a.x) * (c.y-a.y) << "\n"; return 0; } pnt rect[] = {a, b, c, d, a}; //cout << a.x << " " << a.y << " " << b.x << " " << b.y << " " << c.x << " " << c.y << " " << d.x << " " << d.y << "\n"; vector okr; for (int i = 0 ; i < 4; ++i) { pnt rz = rzut(rect[i], rect[i + 1], s); //cout << "---------\nrz: " << rz.x << "," << rz.y << " " << "\n"; if ((rz-s).mod2() > r*r) { //cout << "xd\n"; continue; } ld D = (rz-s).mod2(); ld y = r*r - D; y = sqrt(y); //cout << rect[i].x << ", " << rect[i].y << " " << rect[i+1].x << ", " << rect[i+1].y << "\n"; if (i % 2 == 0) { if (isInSeg(rect[i], rect[i+1], pnt(rz.x - y, rz.y))) { okr.push_back(pnt(rz.x - y, rz.y)); } if (isInSeg(rect[i], rect[i+1], pnt(rz.x + y, rz.y))) { okr.push_back(pnt(rz.x + y, rz.y)); } }else { if (isInSeg(rect[i], rect[i+1], pnt(rz.x, rz.y - y))) { okr.push_back(pnt(rz.x, rz.y - y)); } if (isInSeg(rect[i], rect[i+1], pnt(rz.x, rz.y + y))) { okr.push_back(pnt(rz.x, rz.y + y)); } } if (isInCircle(s, r, rect[i])) okr.push_back(rect[i]); } pnt mid = pnt((a.x + c.x)/(ld)2, (a.y + c.y) / (ld)2); sort(okr.begin(), okr.end(), [&](const pnt &p1, const pnt &p2){ return !cmp((p1-mid), (p2-mid)); }); vector okr2 = okr; okr.clear(); if (okr2.size() > 0) { okr.push_back(okr2[0]); for (int i = 1; i < okr2.size(); ++i) { if (cmp(okr.back().x, okr2[i].x) && cmp(okr.back().y, okr2[i].y)) continue; okr.push_back(okr2[i]); } } //cout << "okr:\n"; //for (auto p : okr) cout << p.x << " " << p.y << "\n"; if (okr.size() == 0 || okr.size() == 1) { if (a.x < 0 && a.y < 0 && c.x > 0 && c.y > 0) { cout << fixed << setprecision(8) << r * r * pi << "\n"; }else { cout << 0 << "\n"; } return 0; } int sz = okr.size(); okr.push_back(okr[0]); ld res = 0; for (int i = 0; i < sz; ++i) { ld pol = 0; bool seg = false; for (int j = 0; j < 4; ++j) { if (isInSeg(rect[j], rect[j+1], okr[i]) && isInSeg(rect[j], rect[j+1], okr[i+1])) { seg = true; pol += (okr[i] * okr[i+1]); break; } } if (!seg) { pol += ((kat(okr[i], okr[i+1])) * r * r); } //cout << "pol: " << pol << "\n"; res += pol; } cout << fixed << setprecision(7) << (res /(ld)2)<< "\n"; }