半平面求交——放置守卫

来源:互联网 发布:软件框架图 编辑:程序博客网 时间:2024/06/04 19:47
#include <bits/stdc++.h>//using namespcace std;const int maxn = 1510;const double EPS = 1E-12;struct Point{double x, y;};Point convex[maxn];struct Line{Point a, b;double ang;};Line l[maxn], st[maxn];int n, ccnt;double operator *(const Point &x, const Point &y){return x.x * y.y - x.y * y.x;}Point operator - (Point x, const Point &y){x.x -= y.x, x.y -= y.y;return x;}Point operator * (const Line &x, const Line &y){double a1 = (y.b - x.a) * (y.a - x.a) , a2 = (y.a - x.b) * (y.b - x.b);Point r;r.x =  (x.a.x * a2 + x.b.x * a1) / (a2 + a1);r.y = (x.a.y * a2 + x.b.y * a1) / (a2 + a1);return r;}bool operator == (const Point &a, const Point &b){return fabs(a.x - b.x) < EPS && fabs(a.y - b.y) < EPS;}bool operator <(const Line &x, const Line &y){if (fabs(x.ang - y.ang) < EPS)return (y.b - x.a) * (x.b - y.a) > EPS;return x.ang < y.ang;}bool JudgeOut(const Line &x, const Point &p){return (p - x.a) * (x.b - x.a) > EPS;}bool Parellel(const Line &x, const Line &y){return fabs((x.b - x.a) * (y.b - y.a)) < -EPS;}void InputData(){scanf("%d", &n);scanf("%lf%lf", &l[0].b.x, &l[0].b.y);l[n - 1].a.x = l[0].b.x, l[n - 1].a.y = l[0].b.y;for (int i = 1; i < n; i++){scanf("%lf%lf", &l[i].b.x, &l[i].b.y);l[i - 1].a.x = l[i].b.x; l[i - 1].a.y = l[i].b.y;}for (int i = 0; i < n; i++)l[i].ang = atan2(l[i].b.y - l[i].a.y, l[i].b.x - l[i].a.x);}double HplaneIntersection(){int top = 1, bot  = 0;std::sort(l, l + n);int tmp = 1;for (int i = 1; i < n; i++)if (l[i].ang - l[i - 1].ang > EPS) l[tmp++] = l[i];n = tmp;st[0] = l[0], st[1] = l[1];for (int i = 2; i < n; i++){if (Parellel(st[top], st[top - 1]) || Parellel(st[bot], st[bot - 1])) return 0;while (bot < top && JudgeOut(l[i], st[top]*st[top - 1])) top--;while (bot < top && JudgeOut(l[i], st[bot]*st[bot + 1])) bot++;st[++top] = l[i];}while (bot < top && JudgeOut(st[bot], st[top]*st[top - 1])) top--;while (bot < top && JudgeOut(st[top], st[bot]*st[bot + 1])) bot++;if (top <= bot + 1) return 0.00;st[++top] = st[bot];ccnt = 0;for (int i = bot; i < top; i++)convex[ccnt++] = st[i] * st[i + 1];double ans = 0;convex[ccnt] = convex[0];for (int i = 0; i < ccnt; i++)ans += convex[i] * convex[i + 1];return ans / 2;}double CheckDirection(){double ans = 0;for (int i = 0; i < n; i++)ans += l[i].a * l[i].b;return ans;}void ChangeDirection(){for (int i = 0; i < n; i++)std::swap(l[i].a, l[i].b);}int main(){int t;scanf("%d", &t);while (t--){InputData();if (CheckDirection() < 0) ChangeDirection();printf("%.2f\n", HplaneIntersection());}return 0;}

0 0
原创粉丝点击