Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cmath>
- #include <vector>
- using namespace std;
- const double M__PI = 3.1415926535897932384626433832795;
- struct pt
- {
- double x, y;
- pt(double x = 0, double y = 0):x(x), y(y){}
- friend pt operator - (pt a, pt b)
- {
- a.x = a.x - b.x;
- a.y = a.y - b.y;
- return a;
- }
- friend pt operator + (pt a, pt b)
- {
- a.x = a.x + b.x;
- a.y = a.y + b.y;
- return a;
- }
- friend pt operator * (pt a, double k)
- {
- a.x = a.x * k;
- a.y = a.y * k;
- return a;
- }
- };
- double RR(pt a)
- {
- return a.x * a.x + a.y * a.y;
- }
- pt rot(pt a, double u)
- {
- pt res;
- res.x = a.x * cos(u) - a.y * sin(u);
- res.y = a.x * sin(u) + a.y * cos(u);
- return res;
- }
- struct circle
- {
- pt a;
- double r;
- bool big;
- double Y;
- circle(pt a = 0, double r = 0, bool big = true, double Y = 1000.0):a(a), r(r), big(big), Y(Y){}
- };
- const double eps = 1e-7;
- vector<pt> circle_circle(pt a, double r, pt b, double r1)
- {
- if (RR(a - b) < eps)
- return vector<pt>();
- if (RR(a - b) >= (r + r1) * (r + r1) - eps || RR(a - b) <= (r - r1) * (r - r1) + eps)
- return vector<pt>();
- pt v = b - a;
- double cosu = (r * r + RR(v) - r1 * r1) / (2.0 * sqrt(RR(v)) * r);
- v = v * (r/ sqrt(RR(v)));
- vector<pt> res;
- res.push_back(a + rot(v, acos(cosu)));
- res.push_back(a + rot(v, -acos(cosu)));
- return res;
- }
- pt fromangle(circle a, double u)
- {
- return a.a + pt(cos(u), sin(u)) * a.r;
- }
- double toangle(circle a, pt p)
- {
- double u = atan2(p.y - a.a.y, p.x - a.a.x);
- if (u < 0)
- u = u + M__PI * 2.0;
- return u;
- }
- double vc(pt a, pt b)
- {
- return a.x * b.y - a.y * b.x;
- }
- int sign(double p)
- {
- if (fabs(p) < eps)
- return 0;
- if (p < eps)
- return -1;
- return 1;
- }
- void addPt(circle a, double y, vector<pt> &p)
- {
- if (fabs(a.a.y - y) >= a.r - eps)
- return;
- double d = sqrt(a.r * a.r - (a.a.y - y) * (a.a.y - y));
- pt res(a.a.x, y);
- p.push_back(res + pt(d));
- p.push_back(res - pt(d));
- }
- bool check_pt_in_circle(circle a, pt b)
- {
- return RR(a.a - b) <= a.r * a.r + eps;
- }
- bool check(circle a, circle b, double y, pt p)
- {
- if (check_pt_in_circle(b, p) && check_pt_in_circle(a, p) && p.y <= y + eps)
- return true;
- return false;
- }
- double bestU(double uf, double us)// ���� ������� ����
- {
- if (uf < us)
- return (uf + us) / 2.0;
- return (uf + us + 2.0 * M__PI) / 2.0;
- }
- bool highU(double uf, double us, circle a, double y) // ��������� ��� ����� ������� ����� ������ � �������
- {
- if (uf < us)
- {
- if (uf < M__PI / 2.0 && us > M__PI / 2.0)
- return a.a.y + a.r <= y + eps;
- }
- else
- {
- swap(uf, us);
- if (!(uf < M__PI / 2.0 && us > M__PI / 2.0))
- return a.a.y + a.r <= y + eps;
- }
- return true;
- }
- double distU(double u1, double u2)
- {
- if (u1 < u2)
- return u2 - u1;
- return u2 + 2.0 * M__PI - u1;
- }
- double S_sector(pt f, pt s, circle a)// ���� ������� �������
- {
- double S = fabs(vc(f - a.a, s - a.a)) / 2;
- double u1 = toangle(a, f);
- double u2 = toangle(a, s);
- double u = distU(u1, u2);
- //cout << u1 << " " << u2 << " u = "<< u << endl;
- double res = min(u, (2.0 * M__PI - u)) * a.r * a.r / 2.0 - S;
- //cout << res << endl;
- if (u > 2.0 * M__PI - u)
- res = M__PI * a.r * a.r - res;
- return res;
- }
- double sector(pt f, pt s, circle a, circle b, double y, vector<pt> &P) // ��������� ������������ ���� c f �� s �� ���������� a � ���������� �������, ���� ���������
- {
- // cout << "sector " << endl;
- if (fabs(RR(a.a - f) - a.r * a.r) >= eps || fabs(RR(a.a - s) - a.r * a.r) >= eps)// ���� ����� �� ���� �� ���������, �� ����� �� �� ������
- return 0.0;
- // cout << ":)" << endl;
- //cout << " " << f.x << " " << f.y << " " << s.x << " " << s.y << " " << a.r << endl;
- double u1 = toangle(a, f);
- double u2 = toangle(a, s);
- //cout << u1 << " " << u2 << endl;
- for (int i = 0; i < P.size(); ++i)
- {
- double u = toangle(a, P[i]);
- if (fabs(RR(a.a - P[i]) - a.r * a.r) > eps )
- continue;
- if (u1 < u2 && fabs(u - u1) > eps && fabs(u - u2) > eps && u > u1 + eps && u < u2 - eps)
- return 0.0;
- if (u1 > u2 && fabs(u - u1) > eps && fabs(u - u2) > eps && !(u > u2 + eps && u < u1 - eps))
- return 0.0;
- }
- // cout << ":))" << endl;
- double u = bestU(u1, u2);
- pt p = fromangle(a, u);
- // cout << p.x << " " << p.y << endl;
- // cout << highU(u1, u2, a, y) << " " << u1 << " " << u2 << endl;
- //cout << f.x << " " << f.y << " " << s.x << " " << s.y << " " << a.a.x << " " << a.a.y << " " << u << " " << u1 << endl;
- if (check(a, b, y, p) && highU(u1, u2, a, y))// ���� �� ���� ����� ����� �� ���� 3 � ����� ������� ���� y
- {
- // cout << f.x << " " << f.y << " " << s.x << " " << s.y << " " << a.a.x << " " << a.a.y << " " << u << " " << u1 << endl;
- // cout << S_sector(f, s, a) << endl;
- return S_sector(f, s, a);
- }
- return 0.0;
- }
- double answ(circle a, circle b, double y, pt f, pt s, vector<pt> &P)
- {
- //if (fabs(f.y - y) < eps && fabs(s.y - y) < eps) // ��� �������� ��� ������� �� ���� �� ������� ������
- // return 0.0;
- // cout << "answ: " << f.x << " " << f.y << " " << s.x << " " << s.y << endl;
- if (RR(a.a - b.a) < eps && fabs(a.r - b.r) < eps)
- return sector(f, s, a, b, y, P) + sector(s, f, a, b, y, P);
- return sector(f, s, a, b, y, P) + sector(s, f, a, b, y, P) + sector(f, s, b, a, y, P) + sector(s, f, b, a, y, P);
- }
- double S(circle a, circle b, double y = 1000.0)// ���������� ������� ����������� 2 �����������, � ������������� y <= const
- {
- // cout << "input: "<< a.a.x << " " << a.a.y << " " << a.r << " " << b.a.x << " " << b.a.y << " "<< b.r << " " << y << endl;
- // ������� ��� ����� ����������
- vector<pt> p = circle_circle(a.a, a.r, b.a, b.r);
- addPt(a, y, p);
- addPt(b, y, p);
- // for (int i = 0; i < p.size(); ++i)
- // cout << p[i].x << " " << p[i].y << endl;
- // cout << endl;
- //cout << p.size() << endl;
- // ������� ������� � �� ������� �� �� ���� 3 ��������
- vector<pt> A;
- for (int i = 0; i < p.size(); ++i)
- {
- if (check(a, b, y, p[i]))
- {
- // cout << "+" << endl;
- bool t = true;
- for (int i1 = 0; i1 < A.size(); ++i1)
- {
- if (RR(A[i1] - p[i]) < eps)
- t = false;
- }
- if (t)
- A.push_back(p[i]);
- }
- }
- //cout << A.size() << endl;
- // ���� ������ ������ �� �����, �� ���� ���� ������ ������ ���� 0
- if (A.size() == 0)
- {
- //cout << "O_O" << endl;
- if (RR(a.a - b.a) < (a.r + b.r) * (a.r + b.r) && a.a.y <= y + eps && b.a.y <= y + eps)
- return M__PI * min(a.r, b.r) * min(a.r, b.r);
- return 0.0;
- }
- // ���� 4 �� ����������� � ������� �������� ��������
- if (A.size() == 4)// ��������� � ������� ������
- {
- vector<pt> ans;
- for (int i = 0; i < A.size(); ++i)
- {
- for (int i1 = i + 1; i1 < A.size(); ++i1)
- {
- vector<pt> p;
- for (int j = 0; j < A.size(); ++j)
- if (j != i && j !=i1)
- p.push_back(A[j]);
- int s = sign(vc(A[i1] - A[i], p[0] - A[i])) * sign(vc(A[i1] - A[i], p[1] - A[i]));
- if (s < 0)// ������ ���������
- {
- ans.clear();
- ans.push_back(A[i]);
- ans.push_back(p[0]);
- ans.push_back(A[i1]);
- ans.push_back(p[1]);
- }
- }
- }
- A = ans;
- //if (A.size()!= 4)
- // cout << "O_O" << endl;
- }
- // ������ 4 ���� �� �����
- if (A.size() > 4)
- {
- while(true)
- {
- cout <<"O_O" << endl;
- }
- }
- if (A.size() == 1)
- {
- // cout << "O_i" << endl;
- return 0;
- }
- //cout << "A:" << A.size() << endl;
- //for (int i = 0; i < A.size(); ++i)
- // cout << A[i].x << " " << A[i].y << endl;
- //cout << endl;
- if (A.size() == 2)
- {
- return answ(a, b, y, A[0], A[1], A);
- }
- double ans = 0;
- for (int i = 0; i < A.size(); ++i)
- {
- double q = answ(a, b, y, A[i], A[(i + 1) % A.size()], A);
- ans += q; // ���������� ������� �� ������ �� ���������
- ans += fabs(vc(A[i] - A[0], A[(i + 1) % A.size()] - A[0])) / 2.0; // ���������� ��������� �������
- // cout << fabs(vc(A[i] - A[0], A[(i + 1) % A.size()] - A[0])) / 2.0 << endl;
- //cout << q << endl;
- }
- return ans;
- }
- double Sstupid(circle a, circle b, double y1 = 1000.0)// ���������� ������� ����������� 2 �����������, � ������������� y <= const
- {
- double ans = 0.0;
- for (double x = -300.0; x < 300.0; x += 0.1)
- {
- for (double y = -300.0; y < 300.0; y += 0.1)
- {
- if (check(a, b, y1, pt(x, y)))
- ans += 1e-2;
- }
- }
- return ans;
- }
- vector<circle> smile;
- void input(pt a)
- {
- smile.push_back(circle(pt(a.x , a.y ), 100.0, 1));
- smile.push_back(circle(pt(a.x - 40.0, a.y + 30.0), 30.0 , 0));
- smile.push_back(circle(pt(a.x + 40.0, a.y + 30.0), 30.0 , 0));
- smile.push_back(circle(pt(a.x , a.y - 20.0), 60.0 , 0, a.y - 20.0));
- }
- double Ss(circle a)
- {
- //cout << a.Y << " " << a.r << " " << a.a.y << endl;
- if (a.Y > 998.0)
- return a.r * a.r * M__PI;
- else
- return a.r * a.r * M__PI / 2.0;
- }
- bool checkS(vector<circle> &A, pt p)
- {
- for (int i = 0; i < A.size(); ++i)
- {
- bool in = false;
- if (RR(A[i].a - p) <= A[i].r * A[i].r && A[i].Y >= p.y)
- in = true;
- if (in && !A[i].big)
- return false;
- if (!in && A[i].big)
- return false;
- }
- return true;
- }
- double superStupid(vector<circle> A, vector<circle> B)
- {
- double ans = 0.0;
- for (double x = -300.0; x <= 300.0; x += 0.1)
- {
- for (double y = -300.0; y <= 300.0; y += 0.1)
- {
- if (checkS(A, pt(x, y)) || checkS(B, pt(x, y)))
- ans += 1e-2;
- }
- }
- return ans;
- }
- int main()
- {
- /*circle A1, B1;
- cin >> A1.a.x >> A1.a.y >> A1.r;
- cin >> B1.a.x >> B1.a.y >> B1.r;
- double y;
- cin >> y;
- cout << S(A1, B1, y) << " " << Sstupid(A1, B1, y) << endl;
- return 0;*/
- pt a, b;
- cin >> a.x >> a.y;
- cin >> b.x >> b.y;
- input(a);
- input(b);
- double ans = 0;
- double stupid_ans = 0;
- for (int i = 0; i < smile.size(); ++i)
- {
- if (smile[i].big == 1)
- ans += Ss(smile[i]);
- else
- ans -= Ss(smile[i]);
- // cout << ans << endl;
- }
- /*if (RR(a - b) < eps)
- {
- cout.precision(10);
- cout << fixed<< ans / 2.0 << endl;
- return 0;}
- */
- vector<circle> A, B;
- for (int i = 0; i < smile.size() / 2; ++i)
- {
- A.push_back(smile[i]);
- B.push_back(smile[smile.size() / 2 + i]);
- for (int i1 = smile.size() / 2; i1 < smile.size(); ++i1)
- {
- double p = -1.0;
- if (smile[i].big != smile[i1].big)
- p = 1.0;
- ans += p * S(smile[i], smile[i1], min(smile[i].Y, smile[i1].Y));
- // stupid_ans += Sstupid(smile[i], smile[i1], min(smile[i].Y, smile[i1].Y));
- double tt = min(smile[i].r * smile[i].r, smile[i1].r * smile[i1].r) * M__PI;
- //cout << S(smile[i], smile[i1], min(smile[i].Y, smile[i1].Y)) << " " << Sstupid(smile[i], smile[i1], min(smile[i].Y, smile[i1].Y)) << endl;
- // system ("pause");
- //<< " " << min(smile[i].r * smile[i].r, smile[i1].r * smile[i1].r) * M__PI<< endl;; //<< " " << Sstupid(smile[i], smile[i1], min(smile[i].Y, smile[i1].Y)) << endl;
- //int p1;
- //cout << "go" << endl;
- //cin >> p1;
- }
- }
- //cout << superStupid(A, B) <<endl;
- //for (int i = 0; i < B.size(); ++i)
- // cout << B[i].a.x << " " << B[i].a.y << B[i].r << endl;
- cout.precision(10);
- cout << fixed;
- cout << ans << endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement