题目链接:http://poj.org/problem?id=3335
题目中点的顺序均为顺时针。
第一道多边形求交的题,有别人的代码做参考还写的各种水……最惨的是WA的原因居然是调试用的代码没有引掉…………
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const double STD=1e-8;
const int NUM=110;
struct Point
{
double x,y;
Point() {}
Point(double _x,double _y)
{
x=_x;
y=_y;
}
void get()
{
scanf("%lf%lf",&x,&y);
}
}points[NUM],p[NUM],q[NUM];
int n;
double r;
int cCnt,curCnt;
inline void getline (Point x,Point y,double &a,double &b,double &c)
{
a = y.y - x.y;
b = x.x - y.x;
c = y.x * x.y - x.x * y.y;
}
void initial ()
{
for (int i=1;i<=n;i++)
p[i] = points[i];
p[n+1] = p[1];
p[0] = p[n];
cCnt = n;
}
Point intersect (Point x,Point y,double a,double b,double c) //相交
{
double u = fabs(a * x.x + b * x.y + c);
double v = fabs(a * y.x + b * y.y + c);
return Point( (x.x * v + y.x * u) / (u + v) , (x.y * v + y.y * u) / (u + v) );
}
int DB (double x)
{
if (x>STD)
return 1;
if (x<-STD)
return -1;
return 0;
}
void cut (double a,double b ,double c)
{
int i;
curCnt = 0;
for (i=1;i<=cCnt;i++)
{
if (DB(a*p[i].x + b*p[i].y + c) >= 0) // >=EPS会WA
q[++curCnt] = p[i];
else
{
if (DB(a*p[i-1].x + b*p[i-1].y + c) > 0)
q[++curCnt] = intersect(p[i],p[i-1],a,b,c);
if (DB(a*p[i+1].x + b*p[i+1].y + c) > 0)
q[++curCnt] = intersect(p[i],p[i+1],a,b,c);
}
}
for (i=1;i<=curCnt;i++)
p[i] = q[i];
p[curCnt+1] = q[1];
p[0] = p[curCnt];
cCnt = curCnt;
}
bool Deal () /*半平面相交(直线切割多边形)(点标号从1开始)*/
{ //此时cCnt为最终切割得到的多边形的顶点数,p为存放顶点的数组
int i;
//注意:默认点是顺时针
initial();
for (i=1;i<=n;i++)
{
double a,b,c;
getline (points[i],points[i+1],a,b,c);
cut(a,b,c);
}
if (cCnt==0)
return false;
return true;
}
int main ()
{
int T;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
points[i].get();
points[n+1] = points[1];
if (Deal())
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
/*
3
16 2 -1 2 -2 1 -2 0 -1 -1 -2 -2 -2 -2 -1 -1 0 -2 1 -2 2 -1 2 0 1 1 2 2 2 2 1 1 0
17 2 -1 2 -2 1 -2 0 -1 -1 -2 -2 -2 -2 -1 -1 0 -2 1 -2 2 -1 2 0 1 1 2 3 2 3 1 2 1 1 0
17 2 -1 2 -2 1 -2 0 -1 -1 -2 -2 -2 -2 -1 -1 0 -2 1 -2 2 -1 2 0 1 1 2 3 2 3 0 2 1 1 0
Out
YES
YES
NO
*/