【模板】【圆和多边形面积交】三角剖分 poj 3675

题目链接:https://vjudge.net/problem/POJ-3675

原文链接:https://blog.csdn.net/pokemonn_getto_daze/article/details/52058312

还是借鉴别人的模板的。。。写的太好了。

模板:

  1 /*************************************************************************
  2     > File Name: poj3675.cpp
  3 # File Name: poj3675.cpp
  4 # Author : xiaobuxie
  5 # QQ : 760427180
  6 # Email:760427180@qq.com
  7 # Created Time: 2019年10月16日 星期三 19时08分03秒
  8  ************************************************************************/
  9 
 10 #include<iostream>
 11 #include<cstdio>
 12 #include<map>
 13 #include<cmath>
 14 #include<cstring>
 15 #include<set>
 16 #include<queue>
 17 #include<vector>
 18 #include<algorithm>
 19 using namespace std;
 20 typedef long long ll;
 21 #define inf 0x3f3f3f3f
 22 #define pq priority_queue<int,vector<int>,greater<int> >
 23 #define eps 1e-6
 24 ll gcd(ll a,ll b){
 25     if(a<b) return gcd(b,a);
 26     return b==0?a:gcd(b,a%b);
 27 }
 28 
 29 const int N = 50+9;
 30 int sgn(double x){
 31     if(fabs(x) < eps) return 0;
 32     if( x < 0) return -1;
 33     return 1;
 34 }
 35 struct Point{
 36     double x,y;
 37     Point(){x=y=0;}
 38     Point(double a,double b){ x=a,y=b;}
 39     Point operator - (const Point& b)const
 40     {return Point(x-b.x,y-b.y);}
 41     Point operator + (const Point& b)const
 42     {return Point(x+b.x,y+b.y);}
 43     Point operator * (const double& b)const
 44     {return Point(x*b,y*b);}
 45     double dot (const Point& b)const
 46     {return x*b.x + y*b.y;}
 47     double cross (const Point& b ,const Point& c)const
 48     {return (b.x - x)*(c.y - y) - (c.x - x)*(b.y - y);}
 49     double dis(const Point& b)const
 50     {return sqrt( (x-b.x)*(x-b.x) + (y-b.y)*(y-b.y));}
 51     bool OnLine(const Point& st,Point& ed)const
 52     {return !sgn(cross(st,ed));}
 53     bool OnSeg(const Point& st,Point& ed)const
 54     {return OnLine(st,ed) && (*this - ed).dot(*this - st) < eps;}
 55 }p[N];
 56 int n;
 57 
 58 //两 直线 交点
 59 Point LineCross(Point a,Point b,Point c,Point d){
 60     double u = a.cross(b,c), v = b.cross(a,d);
 61     return Point((c.x*v + d.x*u) / (u+v), (c.y*v + d.y*u)/(u+v));
 62 }
 63 
 64 //a,b线段(直线)和圆的交点 p1,p2分别为靠近a,b的交点
 65 //a,b在圆的同一侧也可以,只是将向量长度改变而已
 66 double LineCrossCircle(Point a,Point b,Point o,double r,Point& p1,Point& p2){
 67     Point fp = LineCross(o,Point(o.x + a.y - b.y , o.y + b.x -a.x),a,b);// o 垂直到ab直线交点
 68     double otol = o.dis(fp);
 69     double otos = fp.OnSeg(a,b) ? otol : min(o.dis(a) , o.dis(b));
 70     double atob = a.dis(b);
 71     double fptoe = sqrt( r*r - otol*otol ) / atob;
 72     if( otos > r - eps) return otos;
 73     //向量长度改变
 74     p1 = fp + ( a - b ) * fptoe;
 75     p2 = fp + ( b - a ) * fptoe;
 76     return otos;
 77 }
 78 
 79 //oa,到 ob 扇形面积
 80 double SectorA(Point o,Point a,Point b,double r){ //a to b 逆时针
 81     double ao2 = (a.x - o.x)*(a.x - o.x) + (a.y - o.y)*(a.y - o.y);
 82     double bo2 = (b.x - o.x)*(b.x - o.x) + (b.y - o.y)*(b.y - o.y);
 83     double ab2 = (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
 84     double ang = acos(0.5*(ao2 + bo2 - ab2)/sqrt(ao2)/sqrt(bo2));
 85     return 0.5 * r * r * ang;
 86 }
 87 
 88 // 三角形oab 和圆相交的面积
 89 double TICA(Point o,Point a,Point b,double r){//a to b逆时针
 90     if(o.OnLine(a,b)) return 0.0;
 91     double adis = o.dis(a),bdis = o.dis(b);
 92     if( adis < r + eps && bdis < r + eps) return o.cross(a,b) * 0.5;
 93     Point ta,tb;
 94     double otos = LineCrossCircle(a,b,o,r,ta,tb);
 95     if( otos > r - eps) return SectorA(o,a,b,r);
 96     if( adis < r + eps) return o.cross(a,tb) * 0.5 + SectorA(o,tb,b,r);
 97     if( bdis < r + eps) return o.cross(ta,b) * 0.5 + SectorA(o,a,ta,r);
 98     return o.cross(ta,tb)*0.5 + SectorA(o,a,ta,r) + SectorA(o,tb,b,r);
 99 } 
100 
101 //多边形和圆相交的面积
102 //点从 0 开始,并且为逆时针
103 double PICA(int n,Point o,double r){
104     double res = 0;
105     for(int i  =0; i<n;++i){
106         if(o.cross(p[i],p[(i+1)%n]) > 0) res += TICA(o,p[i],p[(i+1)%n],r);
107         else res -= TICA(o,p[(i+1)%n],p[i],r);
108     }
109     return fabs(res);
110 }
111 int main(){
112     double r;
113     while(~scanf("%lf",&r)){
114         scanf("%d",&n);
115         for(int i = 0;i<n;++i) scanf("%lf %lf",&p[i].x,&p[i].y);
116         printf("%.2f\n",PICA(n,Point(0,0),r));
117     }
118     return 0;
119 }
View Code

 

posted @ 2019-10-17 15:51  小布鞋  阅读(238)  评论(0编辑  收藏  举报