分析:就是給一些多邊形,多邊形的邊不會自交(簡單多邊形),求它們的相交情況(當某個多邊形完全包含於某個多邊形,不算相交)。
代碼:
#include <cstdio>
#include <iostream>
#include <cmath>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
const double EPS=1e-8;
struct Point;
typedef Point Vector;
int dblcmp(double x){
return fabs(x)<EPS?0:(x>0?1:-1);
}
struct Point{
double x,y;
Point(){}
Point(double xx,double yy):x(xx),y(yy){}
Vector operator -(Point p){
return Vector(x-p.x,y-p.y);
}
Point operator +(Point p){
return Point(x+p.x,y+p.y);
}
double operator ^(Vector v){
return x*v.y-y*v.x;
}
};
struct Segment{
Point p1,p2;
Segment(){}
Segment(Point pp1,Point pp2):p1(pp1),p2(pp2){}
bool isCross(Segment s){ //線段相交判斷,允許端點相交,但不允許延長線相交
return max(p1.x,p2.x)>=min(s.p1.x,s.p2.x)&&
max(p1.y,p2.y)>=min(s.p1.y,s.p2.y)&&
max(s.p1.x,s.p2.x)>=min(p1.x,p2.x)&&
max(s.p1.y,s.p2.y)>=min(p1.y,p2.y)&&
dblcmp((p2-p1)^(s.p1-p1))*dblcmp((p2-p1)^(s.p2-p1))<=0&&
dblcmp((s.p2-s.p1)^(p1-s.p1))*dblcmp((s.p2-s.p1)^(p2-s.p1))<=0;
}
};
struct Polygon{
char identifier;
vector<Point> p;
vector<Segment> e;
vector<char> interP;
void buildEdge(){
int n=p.size();
for(int i=0;i<n;++i){
e.push_back(Segment(p[i],p[(i+1)%n]));
}
}
bool intersection(Polygon p){
int n1=e.size(),n2=p.e.size();
for(int i=0;i<n1;++i){
for(int j=0;j<n2;++j){
if(e[i].isCross(p.e[j])) return true;
}
}
return false;
}
bool input();
void clear();
};
vector<Polygon> p;
bool compare(const Polygon& p1,const Polygon& p2){
return p1.identifier<p2.identifier;
}
bool Polygon::input(){
scanf("%c",&identifier);
if(identifier=='-'||identifier=='.'){
getchar();
return false;
}
char polyType[10];
scanf("%s",polyType);
double x0,y0,x1,y1,x2,y2;
if(polyType[0]=='s'){
scanf(" (%lf,%lf) (%lf,%lf)",&x0,&y0,&x2,&y2);
p.push_back(Point(x0,y0));
p.push_back(Point((x0+x2+y2-y0)/2.0,(y0+y2+x0-x2)/2.0));
p.push_back(Point(x2,y2));
p.push_back(Point((x0+x2+y0-y2)/2.0,(y0+y2-x0+x2)/2.0));
}
else if(polyType[0]=='l'){
scanf(" (%lf,%lf) (%lf,%lf)",&x0,&y0,&x1,&y1);
p.push_back(Point(x0,y0));
p.push_back(Point(x1,y1));
}
else if(polyType[0]=='t'){
scanf(" (%lf,%lf) (%lf,%lf) (%lf,%lf)",&x0,&y0,&x1,&y1,&x2,&y2);
p.push_back(Point(x0,y0));
p.push_back(Point(x1,y1));
p.push_back(Point(x2,y2));
}
else if(polyType[0]=='p'){
int n;
scanf(" %d",&n);
for(int i=0;i<n;++i){
scanf(" (%lf,%lf)",&x0,&y0);
p.push_back(Point(x0,y0));
}
}
else if(polyType[0]=='r'){
scanf(" (%lf,%lf) (%lf,%lf) (%lf,%lf)",&x0,&y0,&x1,&y1,&x2,&y2);
p.push_back(Point(x0,y0));
p.push_back(Point(x1,y1));
p.push_back(Point(x2,y2));
p.push_back(Point(x0,y0)+(Point(x2,y2)-Point(x1,y1)));
}
getchar();
buildEdge();
return true;
}
void Polygon::clear(){
p.clear();
e.clear();
interP.clear();
}
void output(){
int n=p.size();
for(int i=0;i<n;++i){
int m=p[i].interP.size();
char id=p[i].identifier;
if(!m){
printf("%c has no intersections\n",id);
}
else if(m==1){
printf("%c intersects with %c\n",id,p[i].interP[0]);
}
else if(m==2){
printf("%c intersects with %c and %c\n",id,p[i].interP[0],p[i].interP[1]);
}
else{
printf("%c intersects with ",id);
for(int j=0;j<m-1;++j){
printf("%c, ",p[i].interP[j]);
}
printf("and %c\n",p[i].interP[m-1]);
}
}
putchar('\n');
}
void solve(){
int n=p.size();
for(int i=0;i<n;++i){
for(int j=i+1;j<n;++j){
if(p[i].intersection(p[j])){
p[i].interP.push_back(p[j].identifier);
p[j].interP.push_back(p[i].identifier);
}
}
sort(p[i].interP.begin(),p[i].interP.end());
}
sort(p.begin(),p.end(),compare);
output();
}
int main(){
Polygon polygon;
while(polygon.input()){
p.clear();
p.push_back(polygon);
polygon.clear();
while(polygon.input()){
p.push_back(polygon);
polygon.clear();
}
solve();
}
return 0;
}