简单多边形与圆交面积模板
1 /* 2 求多边形与圆相交的面积 3 */ 4 5 #include <iostream> 6 #include <cstdio> 7 #include <cmath> 8 #define max(x,y) ((x)>(y)?(x):(y)) 9 #define min(x,y) ((x)<(y)?(x):(y)) 10 #define PI acos(-1.0) 11 #define EPS 1e-10 12 using namespace std; 13 14 inline int DB(double x) { 15 if(x<-EPS) return -1; 16 if(x>EPS) return 1; 17 return 0; 18 } 19 20 21 struct point { 22 double x,y; 23 24 point() {} 25 point(double _x,double _y):x(_x),y(_y) {} 26 27 point operator-(point a) { 28 return point(x-a.x,y-a.y); 29 } 30 point operator+(point a) { 31 return point(x+a.x,y+a.y); 32 } 33 34 double operator*(point a) { 35 return x*a.y-y*a.x; 36 } 37 38 point oppose() { 39 return point(-x,-y); 40 } 41 42 double length() { 43 return sqrt(x*x+y*y); 44 } 45 46 point adjust(double L) { 47 L/=length(); 48 return point(x*L,y*L); 49 } 50 51 point vertical() { 52 return point(-y,x); 53 } 54 55 double operator^(point a) { 56 return x*a.x+y*a.y; 57 } 58 }; 59 60 61 struct segment { 62 point a,b; 63 64 segment() {} 65 segment(point _a,point _b):a(_a),b(_b) {} 66 67 point intersect(segment s) { 68 double s1=(s.a-a)*(s.b-a); 69 double s2=(s.b-b)*(s.a-b); 70 double t=s1+s2; 71 s1/=t; 72 s2/=t; 73 return point(a.x*s2+b.x*s1,a.y*s2+b.y*s1); 74 } 75 point vertical(point p) { 76 point t=(b-a).vertical(); 77 return intersect(segment(p,p+t)); 78 } 79 int isonsegment(point p) { 80 return DB(min(a.x,b.x)-p.x)<=0&& 81 DB(max(a.x,b.x)-p.x)>=0&& 82 DB(min(a.y,b.y)-p.y)<=0&& 83 DB(max(a.y,b.y)-p.y)>=0; 84 } 85 }; 86 87 struct circle { 88 point p; 89 double R; 90 }; 91 92 circle C; 93 point p[105]; 94 int n; 95 96 97 double cross_area(point a,point b,circle C) { 98 point p=C.p; 99 double R=C.R; 100 int sgn=DB((b-p)*(a-p)); 101 double La=(a-p).length(),Lb=(b-p).length(); 102 int ra=DB(La-R),rb=DB(Lb-R); 103 double ang=acos(((b-p)^(a-p))/(La*Lb)); 104 segment t(a,b); 105 point s; 106 point h,u,temp; 107 double ans,L,d,ang1; 108 109 if(!DB(La)||!DB(Lb)||!sgn) ans=0; 110 else if(ra<=0&&rb<=0) ans=fabs((b-p)*(a-p))/2; 111 else if(ra>=0&&rb>=0) { 112 h=t.vertical(p); 113 L=(h-p).length(); 114 if(!t.isonsegment(h)||DB(L-R)>=0) ans=R*R*(ang/2); 115 else { 116 ans=R*R*(ang/2); 117 ang1=acos(L/R); 118 ans-=R*R*ang1; 119 ans+=R*sin(ang1)*L; 120 } 121 } else { 122 h=t.vertical(p); 123 L=(h-p).length(); 124 s=b-a; 125 d=sqrt(R*R-L*L); 126 s=s.adjust(d); 127 if(t.isonsegment(h+s)) u=h+s; 128 else u=h+s.oppose(); 129 if(ra==1) temp=a,a=b,b=temp; 130 ans=fabs((a-p)*(u-p))/2; 131 ang1=acos(((u-p)^(b-p))/((u-p).length()*(b-p).length())); 132 ans+=R*R*(ang1/2); 133 } 134 return ans*sgn; 135 } 136 137 double cal_cross(circle C,point p[],int n) { 138 double ans=0; 139 int i; 140 p[n]=p[0]; 141 for(i=0; i<n; i++) ans+=cross_area(p[i],p[i+1],C); 142 return fabs(ans); 143 } 144 145 double x,y,v,det,t,g,R; 146 147 int input() { 148 scanf("%lf%lf%lf%lf%lf%lf%lf",&x,&y,&v,&det,&t,&g,&R); 149 return x||y||v||det||t||g||R; 150 } 151 152 153 int main() { 154 //freopen("test.in","r",stdin); 155 while(input()) { 156 scanf("%d",&n); 157 int i; 158 for(i=0; i<n; i++) scanf("%lf%lf",&p[i].x,&p[i].y); 159 det=det/180*PI; 160 C.R=R; 161 C.p.x=x+v*cos(det)*t; 162 C.p.y=y+v*sin(det)*t-0.5*g*t*t; 163 double area=cal_cross(C,p,n); 164 printf("%.2lf\n",area); 165 } 166 return 0; 167 }
转自:http://blog.csdn.net/acm_baihuzi/article/details/48473725
多边形面积求法:https://www.cnblogs.com/xiexinxinlove/p/3708147.html