POJ 3449 Geometric Shapes
判断两个多边形是否相交,只需判断边是否有相交。
编码量有点大,不过思路挺简单的。
#include<cstdio> #include<cstring> #include<vector> #include<cmath> #include<string> #include<queue> #include<list> #include<algorithm> #include<iostream> using namespace std; string s; struct point { double x; double y; point (double a,double b){x=a;y=b;} }; struct Sharp { string name; vector<point>v; vector<string> ans; }sharp[100]; int tot; bool cmp(const Sharp&a,const Sharp&b) { return a.name<b.name; } void work() { int a,b,c,d,e,f; if(s=="square") { scanf(" (%d,%d)",&a,&b); scanf(" (%d,%d)",&c,&d); point p1(1.0*a,1.0*b); point p2(1.0*(a+b+c-d)/2.0,1.0*(-a+b+c+d)/2.0); point p3(1.0*c,1.0*d); point p4(1.0*(a-b+c+d)/2.0,1.0*(a+b-c+d)/2.0); sharp[tot].v.push_back(p1); sharp[tot].v.push_back(p2); sharp[tot].v.push_back(p3); sharp[tot].v.push_back(p4); } if(s=="rectangle") { scanf(" (%d,%d)",&a,&b); scanf(" (%d,%d)",&c,&d); scanf(" (%d,%d)",&e,&f); point p1(1.0*a,1.0*b); point p2(1.0*c,1.0*d); point p3(1.0*e,1.0*f); point p4(p1.x+p3.x-p2.x,p1.y+p3.y-p2.y); sharp[tot].v.push_back(p1); sharp[tot].v.push_back(p2); sharp[tot].v.push_back(p3); sharp[tot].v.push_back(p4); } if(s=="line") { for(int i=1;i<=2;i++) { scanf(" (%d,%d)",&a,&b); point p(1.0*a,1.0*b); sharp[tot].v.push_back(p); } } if(s=="triangle") { for(int i=1;i<=3;i++) { scanf(" (%d,%d)",&a,&b); point p(1.0*a,1.0*b); sharp[tot].v.push_back(p); } } if(s=="polygon") { int x; scanf("%d",&x); for(int i=1;i<=x;i++) { scanf(" (%d,%d)",&a,&b); point p(1.0*a,1.0*b); sharp[tot].v.push_back(p); } } tot++; } const double eps=1e-8; #define zero(x)(((x)>0?(x):(-x))<eps) double xmult(point p1,point p2,point p0) { return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); } int dots_inline(point p1,point p2,point p3) { return zero(xmult(p1,p2,p3)); } int same_side(point p1,point p2,point l1,point l2) { return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps; } int dot_online_in(point p,point l1,point l2) { return zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps; } int intersect_in(point u1,point u2,point v1,point v2) { if(!dots_inline(u1,u2,v1)||!dots_inline(u1,u2,v2)) return !same_side(u1,u2,v1,v2)&&!same_side(v1,v2,u1,u2); return dot_online_in(u1,v1,v2)||dot_online_in(u2,v1,v2)||dot_online_in(v1,u1,u2)||dot_online_in(v2,u1,u2); } bool judge(int a,int b) { for(int i=0;i<sharp[a].v.size();i++) { for(int j=0;j<sharp[b].v.size();j++) { point p1=sharp[a].v[i]; point p2=sharp[a].v[(i+1)%sharp[a].v.size()]; point p3=sharp[b].v[j]; point p4=sharp[b].v[(j+1)%sharp[b].v.size()]; if(intersect_in(p1,p2,p3,p4)) return 1; } } return 0; } void init() { tot=0; for(int i=0;i<100;i++) { sharp[i].ans.clear(); sharp[i].v.clear(); } } int main() { while(1) { cin>>s; if(s==".") break; init(); sharp[tot].name=s; cin>>s; work(); while(1) { cin>>s; if(s=="-") break; sharp[tot].name=s; cin>>s; work(); } sort(sharp,sharp+tot,cmp); for(int i=0;i<tot;i++) { for(int j=i+1;j<tot;j++) { if(judge(i,j)) { sharp[i].ans.push_back(sharp[j].name); sharp[j].ans.push_back(sharp[i].name); } } } for(int i=0;i<tot;i++) { cout<<sharp[i].name<<" "; if(sharp[i].ans.size()==0) printf("has no intersections\n"); else if(sharp[i].ans.size()==1) cout<<"intersects with "<<sharp[i].ans[0]<<endl; else if(sharp[i].ans.size()==2) cout<<"intersects with "<<sharp[i].ans[0]<<" and "<<sharp[i].ans[1]<<endl; else { printf("intersects with"); for(int k=0;k<sharp[i].ans.size();k++) { if(k<sharp[i].ans.size()-1) cout<<" "<<sharp[i].ans[k]<<","; else cout<<" and "<<sharp[i].ans[k]<<endl; } } } printf("\n"); } return 0; }