题目:顺序输入一系列n个点,输入m个测试点,如果点在形内,那么输出Within,否则输出Outside;
算法:采用环顾法(汝亮书上的P381),用差积(测试点p和 多边形同向相邻两个顶点的差积 m),如果m> 0,就对求出来的夹角+,否则-(m==0,考虑p在线段上就跳出返回Within , 否则不在线段上,那么就忽略,继续) 最后 ,夹角和取绝对值 跟3.0比较,大于3.0,那么在里面,否则在外面。
//---以下是我的AC源码,之前wa了好久,原来就是忘了考虑输入的顺时针或逆时针,只要加上fabs()!
//就可以了,呵呵
#include
<
iostream.h
>
#include < math.h >
struct Point
... {
double x;
double y;
} pt[ 1000 ]; // 依顺时针或逆时针存储简单多边形的点
int n;
Point p;
double MIN( double a, double b)
... {
return a<b?a:b;
}
double MAX( double a, double b)
... {
return a>b?a:b;
}
double mulpti(Point ps , Point pe , Point p)
... {
double m;
m=(pe.x-ps.x)*(p.y-ps.y)-(p.x-ps.x)*(pe.y-ps.y);
return m;
}
void p_in_ploygon(Point p) // 要判断的点
... {
int i;
double xa,ya,xb,yb;
double cos0;
double flag=0;//用于累加角度
bool tag=false;
double m;
for(i=n-1;i>=1;i--)
...{
//差积判断点是否在线段
m=mulpti(pt[i+1] , pt[i] , p);
if( m==0 )
...{
if(p.x>=MIN(pt[i+1].x,pt[i].x) && p.x<=MAX(pt[i+1].x,pt[i].x) && p.y>=MIN(pt[i+1].y,pt[i].y) && p.y<=MAX(pt[i+1].y,pt[i].y) )
...{
tag=true;
break;
}
continue;
}
xa=pt[i+1].x-p.x;
ya=pt[i+1].y-p.y;
xb=pt[i].x-p.x;
yb=pt[i].y-p.y;
cos0=(xa*xb + ya*yb)/(sqrt(xa*xa+ya*ya)* sqrt(xb*xb+yb*yb));
if( m > 0 )
...{
flag+=acos(cos0);
}
else
...{
flag-=acos(cos0);
}
}
if( fabs(flag)<3.0 && !tag) //注意求绝对值
...{
cout<<"Outside"<<endl;
}
else
...{
cout<<"Within"<<endl;
}
}
void s(Point p) // 当输入的多边形只有一个点
... {
if(p.x == pt[1].x && p.y == pt[1].y )
cout<<"Within"<<endl;
else
cout<<"Outside"<<endl;
}
int main()
... {
int i,m;
int c=0;
while(cin>>n&&n!=0)
...{
cin>>m;
for(i=1;i<=n;i++)
...{
cin>>pt[i].x>>pt[i].y;
}
n++;
pt[n]=pt[1];
if(c!=0)cout<<endl;
cout<<"Problem "<<++c<<":"<<endl;
for(i=1;i<=m;i++)
...{
cin>>p.x>>p.y;
if(n==2)
...{
s(p);
}
else
...{
p_in_ploygon(p);
}
}
}
return 0;
#include < math.h >
struct Point
... {
double x;
double y;
} pt[ 1000 ]; // 依顺时针或逆时针存储简单多边形的点
int n;
Point p;
double MIN( double a, double b)
... {
return a<b?a:b;
}
double MAX( double a, double b)
... {
return a>b?a:b;
}
double mulpti(Point ps , Point pe , Point p)
... {
double m;
m=(pe.x-ps.x)*(p.y-ps.y)-(p.x-ps.x)*(pe.y-ps.y);
return m;
}
void p_in_ploygon(Point p) // 要判断的点
... {
int i;
double xa,ya,xb,yb;
double cos0;
double flag=0;//用于累加角度
bool tag=false;
double m;
for(i=n-1;i>=1;i--)
...{
//差积判断点是否在线段
m=mulpti(pt[i+1] , pt[i] , p);
if( m==0 )
...{
if(p.x>=MIN(pt[i+1].x,pt[i].x) && p.x<=MAX(pt[i+1].x,pt[i].x) && p.y>=MIN(pt[i+1].y,pt[i].y) && p.y<=MAX(pt[i+1].y,pt[i].y) )
...{
tag=true;
break;
}
continue;
}
xa=pt[i+1].x-p.x;
ya=pt[i+1].y-p.y;
xb=pt[i].x-p.x;
yb=pt[i].y-p.y;
cos0=(xa*xb + ya*yb)/(sqrt(xa*xa+ya*ya)* sqrt(xb*xb+yb*yb));
if( m > 0 )
...{
flag+=acos(cos0);
}
else
...{
flag-=acos(cos0);
}
}
if( fabs(flag)<3.0 && !tag) //注意求绝对值
...{
cout<<"Outside"<<endl;
}
else
...{
cout<<"Within"<<endl;
}
}
void s(Point p) // 当输入的多边形只有一个点
... {
if(p.x == pt[1].x && p.y == pt[1].y )
cout<<"Within"<<endl;
else
cout<<"Outside"<<endl;
}
int main()
... {
int i,m;
int c=0;
while(cin>>n&&n!=0)
...{
cin>>m;
for(i=1;i<=n;i++)
...{
cin>>pt[i].x>>pt[i].y;
}
n++;
pt[n]=pt[1];
if(c!=0)cout<<endl;
cout<<"Problem "<<++c<<":"<<endl;
for(i=1;i<=m;i++)
...{
cin>>p.x>>p.y;
if(n==2)
...{
s(p);
}
else
...{
p_in_ploygon(p);
}
}
}
return 0;