POJ 1279 Art Gallery 多边形内核面积

来源:互联网 发布:电气工程绘图软件 编辑:程序博客网 时间:2024/05/21 03:25

题目大意:按顺序给出一个多边形的顶点,求这个多边形内核的面积。答案保留两位输出。


思路:半平面交。加边的时候要讨论一下第一个点和最后一个点,否则会wa的很惨。


CODE:

#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 1510#define EPS 1e-8#define DCMP(a) (fabs(a) < EPS)using namespace std;struct Point{double x,y;Point(double _ = .0,double __ = .0):x(_),y(__) {}Point operator +(const Point &a)const {return Point(x + a.x,y + a.y);}Point operator -(const Point &a)const {return Point(x - a.x,y - a.y);}Point operator *(double a)const {return Point(x * a,y * a);}void Read() {scanf("%lf%lf",&x,&y);}}point[MAX],p[MAX],ploygen[MAX];struct Line{Point p,v;double alpha;Line(Point _,Point __):p(_),v(__) {alpha = atan2(v.y,v.x);}Line() {}bool operator <(const Line &a)const {return alpha < a.alpha;}}line[MAX],q[MAX];int cases;int points,lines;inline void Initialize();inline void MakeLine(const Point &a,const Point &b);inline double Cross(const Point &a,const Point &b);inline bool OnLeft(const Line &l,const Point &p);inline Point GetIntersection(const Line &a,const Line &b);inline double HalfPlaneIntersection();inline double GetArea(int cnt);int main(){for(cin >> cases;cases; --cases) {scanf("%d",&points);Initialize();for(int i = 1;i <= points; ++i)point[i].Read();for(int i = points;i > 1; --i)MakeLine(point[i],point[i - 1]);MakeLine(point[1],point[points]);sort(line + 1,line + lines + 1);printf("%.2lf\n",HalfPlaneIntersection());}return 0;}inline void Initialize(){lines = 0;}inline void MakeLine(const Point &a,const Point &b){line[++lines] = Line(a,b - a);}inline double Cross(const Point &a,const Point &b){return a.x * b.y - a.y * b.x;}inline Point GetIntersection(const Line &a,const Line &b){Point u = a.p - b.p;double temp = Cross(b.v,u) / Cross(a.v,b.v);return a.p + a.v * temp;}inline bool OnLeft(const Line &l,const Point &p){return Cross(l.v,p - l.p) > 0;}inline double HalfPlaneIntersection(){int front = 1,tail = 1;q[tail] = line[1];for(int i = 2;i <= lines; ++i) {while(front < tail && !OnLeft(line[i],p[tail - 1]))--tail;while(front < tail && !OnLeft(line[i],p[front]))++front;if(DCMP(Cross(line[i].v,q[tail].v)))q[tail] = OnLeft(q[tail],line[i].p) ? line[i]:q[tail];elseq[++tail] = line[i];if(front < tail)p[tail - 1] = GetIntersection(q[tail],q[tail - 1]);}while(front < tail && !OnLeft(q[front],p[tail - 1]))--tail;if(front == tail)return .0;p[tail] = GetIntersection(q[front],q[tail]);int cnt = 0;for(int i = front;i <= tail; ++i)ploygen[++cnt] = p[i];return GetArea(cnt);}inline double GetArea(int cnt){double re = Cross(ploygen[cnt],ploygen[1]);for(int i = 1;i < cnt; ++i)re += Cross(ploygen[i],ploygen[i + 1]);return fabs(re / 2);}


0 0
原创粉丝点击