Skip to content

Commit a44cb51

Browse files
committed
添加凸包算法
1 parent 49e403e commit a44cb51

File tree

1 file changed

+89
-2
lines changed

1 file changed

+89
-2
lines changed

computationGeometry/planeGeometry.cpp

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
1+
#include<bits/stdc++.h>
2+
#define pb push_back
3+
#define mp make_pair
4+
#define PI acos(-1)
5+
#define fi first
6+
#define se second
7+
#define INF 0x3f3f3f3f
8+
#define INF64 0x3f3f3f3f3f3f3f3f
9+
#define random(a,b) ((a)+rand()%((b)-(a)+1))
10+
#define ms(x,v) memset((x),(v),sizeof(x))
11+
#define scint(x) scanf("%d",&x );
12+
#define scf(x) scanf("%lf",&x );
13+
#define eps 1e-10
14+
#define dcmp(x) (fabs(x) < eps? 0:((x) <0?-1:1))
15+
#define torad(x) (PI*x/180)
16+
#define lc o<<1
17+
#define rc o<<1|1
18+
using namespace std;
119
#define dcmp(x) (fabs(x) < eps? 0:((x) <0?-1:1))
220
struct Point{
321
double x,y;
4-
Point(double _x=0,double _y=0):x(_x),y(_y){}
22+
Point( double _x=0,double _y=0):x(_x),y(_y){}
523
};
624
typedef Point Vector;
725

@@ -14,7 +32,7 @@ bool operator == (const Point A,const Point B){return !dcmp(A.x-B.x) && !dcmp(A
1432
double Dot(Vector A, Vector B){return A.x*B.x+A.y*B.y;}
1533
double Length(Vector & A){return sqrt(Dot(A,A));}
1634
double Angle(Vector &A,Vector & B){return acos(Dot(A,B)/Length(A)/Length(B));}
17-
Vector Rotate(Vector &A,double rad){return Vector(A.x*cos(rad)-sin(rad)*A.y,A.x*sin(rad)+A.y*cos(rad));}
35+
Vector Rotate(const Vector &A,double rad){return Vector(A.x*cos(rad)-sin(rad)*A.y,A.x*sin(rad)+A.y*cos(rad));}
1836
Vector Normal(Vector A){//A 的单位法向量
1937
double L = Length(A);
2038
return Vector(-A.y/L,A.x/L);
@@ -56,3 +74,72 @@ double polygonArea(Point *p,int n){
5674
area += Cross(p[i]-p[0],p[i+1]-p[0]);
5775
return area/2;
5876
}
77+
//点在多边型内的判定
78+
int isPointInPolygon(Point P,Point* poly,int n){
79+
int wn =0;
80+
for(int i=0 ; i<n ; ++i){
81+
if(onSegment(P,poly[i],poly[(i+1)%n]))return -1;//在直线上
82+
int k = dcmp(Cross(poly[(i+1)%n]-poly[i],P - poly[i]));
83+
int d1 = dcmp(poly[i].y - P.y);
84+
int d2 = dcmp(poly[(i+1)%n].y - P.y);
85+
if(k>0 && d1 <= 0 && d2>0)wn++;//逆时针穿过
86+
else if(k<0 && d2<=0 && d1 >0)wn--;
87+
}
88+
return wn !=0;
89+
}
90+
91+
int ConvexHull(Point * p,int n,Point* ch){
92+
sort(p,p+n);
93+
int m=0;
94+
for(int i=0 ; i<n ; ++i){
95+
while (m>1 && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2])<=0)m--;//下凸包
96+
ch[m++] = p[i];
97+
}
98+
int k =m;
99+
for(int i=n-2 ; i>=0 ; --i){
100+
while (m >k && Cross(ch[m-1]-ch[m-2],p[i]-ch[m-2]) <=0)m--;
101+
ch[m++] = p[i];
102+
}
103+
if(n>1)m--;//第一个点
104+
return m;
105+
}
106+
107+
//test
108+
const int maxn = 2500+10;
109+
Point p[maxn];
110+
Point ch[maxn];
111+
112+
int main(int argc, char const *argv[]) {
113+
// ios_base::sync_with_stdio(0);
114+
// cin.tie(0);
115+
// cout.tie(0);
116+
117+
int T;
118+
cin>>T;
119+
while (T--) {
120+
int n;
121+
int cnt =0;
122+
cin>>n;
123+
double area = 0;
124+
for(int i=0 ; i<n ; ++i){
125+
double x,y,w,h,j;
126+
cin>>x>>y>>w>>h>>j;
127+
Point o(x,y);
128+
double rad = -torad(j);
129+
// std::cout << rad << '\n';
130+
// std::cout << "rad" << '\n';
131+
// std::cout << j << '\n';
132+
p[cnt++] = o+Rotate(Vector(-w/2,-h/2),rad);
133+
p[cnt++] = o+Rotate(Vector(-w/2,h/2),rad);
134+
p[cnt++] = o + Rotate(Vector(w/2,-h/2),rad);
135+
p[cnt++] = o + Rotate(Vector(w/2,h/2),rad);
136+
area+= w*h;
137+
}
138+
// std::cout << area << '\n';
139+
int m = ConvexHull(p,cnt , ch);
140+
double ans = area / polygonArea(ch,m);
141+
142+
printf("%.1lf %%\n", ans*100);
143+
}
144+
return 0;
145+
}

0 commit comments

Comments
 (0)