#include using namespace std; typedef long double ld; const ld eps = 0.00000001; 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 wiek(const ld a, const ld b) { return (!cmp(a,b) && a > b); } bool wiekRow(const ld a, const ld b) { return (cmp(a,b) || a > b); } bool isInCircle(ld R, pnt a) { ld w = (a.x) * (a.x) + (a.y) * (a.y); return wiekRow(R*R, w); } pnt rzut (pnt a, pnt b) { ld dot = (b-a) ^ (pnt(0,0)-a); ld mod = (b-a).mod2(); return (b-a) * (dot/mod) + a; } bool isInSeg(pnt a, pnt b, pnt x) { if (cmp(a.x, b.x)) { if (cmp(x.x, a.x)) { if (wiekRow(x.y, a.y) && wiekRow(b.y, x.y)) return true; if (wiekRow(a.y, x.y) && wiekRow(x.y, b.y)) return true; } }else { if (cmp(x.y, a.y)) { if (wiekRow(x.x, a.x) && wiekRow(b.x, x.x)) return true; if (wiekRow(a.x, x.x) && wiekRow(x.x, b.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 (wiekRow(cross,0) && wiekRow(dot,0)) {} else if (wiekRow(cross,0) && wiek(0,dot)) { //cout << "xd\n"; res += pi/(ld)2; } else if (wiek(0,cross) && wiekRow(0,dot)) { res += pi; //cout << "xxd\n"; } if (wiekRow(0,cross) && wiek(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 = pnt(0,0); if (wiek(a.x, b.x)) swap(a.x, b.x); if (wiek(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(r,a)) { if (wiek(-r, a.x)) a.x = -r; if (wiek(-r, a.y)) a.y = -r; } if (!isInCircle(r,b)) { if (wiek(b.x, r)) b.x = r; if (wiek(-r, b.y)) b.y = -r; } if (!isInCircle(r,c) ){ if (wiek(c.x,r)) c.x = r; if (wiek(c.y, r)) c.y = r; } if (!isInCircle(r,d)) { if (wiek(-r, d.x)) d.x = -r; if (wiek(d.y,r)) d.y = r; } if (isInCircle(r,a) && isInCircle(r,b) && isInCircle(r,c) && isInCircle(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]); //cout << "---------\nrz: " << rz.x << "," << rz.y << " " << "\n"; if (wiek((rz).mod2(), r*r)) { //cout << "xd\n"; continue; } ld D = (rz).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(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]); } } 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"; }