简单多边形与圆交面积模板
生活随笔
收集整理的這篇文章主要介紹了
简单多边形与圆交面积模板
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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 } View Code
轉自:http://blog.csdn.net/acm_baihuzi/article/details/48473725
多邊形面積求法:https://www.cnblogs.com/xiexinxinlove/p/3708147.html
轉載于:https://www.cnblogs.com/zmin/p/8329118.html
總結
以上是生活随笔為你收集整理的简单多边形与圆交面积模板的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 二叉树的深度优先遍历和广度优先遍历
- 下一篇: 3D Computer Grapihcs