计算几何问题,基本思想从要判断的点引一条射线看和多边形交点的个数,如果是奇数个,那么就在多边形内,否则在多边形外。先判断点是否在多边形边上的情况判掉,再判断线段相交。
<!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->#include<iostream>
#include<vector>
usingnamespacestd;
constintMAXSIZE=100;
constdoubleMax=100000000;
structPoint
{
doublex;
doubley;
}points[MAXSIZE];
Pointpc;//选择的射线点
doubleCrossMultiply(constPoint&a,constPoint&b,constPoint&c)
{//叉乘
doublex1,y1,x2,y2;
x1=b.x-a.x;
y1=b.y-a.y;
x2=c.x-b.x;
y2=c.y-b.y;
returnx1*y2-x2*y1;
}
doubleinterSect(constPoint&a,constPoint&b,constPoint&c,constPoint&d)
{
doubled1,d2,d3,d4;
d1=CrossMultiply(a,b,c),
d2=CrossMultiply(a,b,d),
d3=CrossMultiply(c,d,a),
d4=CrossMultiply(c,d,b);
if((d1*d2)<0&&(d3*d4)<0)
return1.;
elseif((d1*d2)==0||(d3*d4)==0)
return0;
else
return-1.;
}
boolIsOnEdge(constPoint&p,constvector<Point>&ptVect)
{//点是否在边上
inti,j,size,minX,maxX,minY,maxY;
size=ptVect.size();//点的数目
for(i=0;i<size;++i)
{
j=i+1;
if(j==size)
{
j=0;
}
if(CrossMultiply(ptVect[i],ptVect[j],p)==0)
{//在同一直线上
if(p.x>=min(ptVect[i].x,ptVect[j].x)&&p.x<=max(ptVect[i].x,ptVect[j].x)&&p.y>=min(ptVect[i].y,ptVect[j].y)&&p.y<=max(ptVect[i].y,ptVect[j].y))
{//在线段内
returntrue;
}
}
}
returnfalse;
}
boolisInside(constPoint&p,constvector<Point>&ptVect)
{//判断点是否在多边形内部
inti,j,num,size;
doubled;
num=0;//射线与线段相交的点的个数
size=ptVect.size();
for(i=0;i<size;++i)
{//处理每条线段
j=i+1;
if(j==size)
{
j=0;
}
d=interSect(p,pc,ptVect[i],ptVect[j]);
if(d>0)
num++;//严格相交
elseif(d==0)
{//有一端点在另一直线上
if(ptVect[i].y>0||ptVect[j].y>0)
num++;
}
}
if(num%2==0)
returnfalse;
else
returntrue;
}
intmain(void)
{
intN,M,i,pX,pY,cases=0;
while(cin>>N&&N!=0)
{
cin>>M;
if(cases!=0)
cout<<endl;
vector<Point>pointVect;
for(i=0;i<N;++i)
{
cin>>points[i].x>>points[i].y;
pointVect.push_back(points[i]);
}
cout<<"Problem"<<++cases<<":"<<endl;
for(i=0;i<M;++i)
{
Pointp;
cin>>p.x>>p.y;
pc.x=Max,pc.y=p.y;//故意把射线点选择在同一水平线,无穷远处
if(IsOnEdge(p,pointVect))
{//在一条边上
cout<<"Within"<<endl;
continue;
}
elseif(isInside(p,pointVect))
{//在多边形内部
cout<<"Within"<<endl;
}
else
{
cout<<"Outside"<<endl;
}
}
}
return0;
}
#include<vector>
usingnamespacestd;
constintMAXSIZE=100;
constdoubleMax=100000000;
structPoint
{
doublex;
doubley;
}points[MAXSIZE];
Pointpc;//选择的射线点
doubleCrossMultiply(constPoint&a,constPoint&b,constPoint&c)
{//叉乘
doublex1,y1,x2,y2;
x1=b.x-a.x;
y1=b.y-a.y;
x2=c.x-b.x;
y2=c.y-b.y;
returnx1*y2-x2*y1;
}
doubleinterSect(constPoint&a,constPoint&b,constPoint&c,constPoint&d)
{
doubled1,d2,d3,d4;
d1=CrossMultiply(a,b,c),
d2=CrossMultiply(a,b,d),
d3=CrossMultiply(c,d,a),
d4=CrossMultiply(c,d,b);
if((d1*d2)<0&&(d3*d4)<0)
return1.;
elseif((d1*d2)==0||(d3*d4)==0)
return0;
else
return-1.;
}
boolIsOnEdge(constPoint&p,constvector<Point>&ptVect)
{//点是否在边上
inti,j,size,minX,maxX,minY,maxY;
size=ptVect.size();//点的数目
for(i=0;i<size;++i)
{
j=i+1;
if(j==size)
{
j=0;
}
if(CrossMultiply(ptVect[i],ptVect[j],p)==0)
{//在同一直线上
if(p.x>=min(ptVect[i].x,ptVect[j].x)&&p.x<=max(ptVect[i].x,ptVect[j].x)&&p.y>=min(ptVect[i].y,ptVect[j].y)&&p.y<=max(ptVect[i].y,ptVect[j].y))
{//在线段内
returntrue;
}
}
}
returnfalse;
}
boolisInside(constPoint&p,constvector<Point>&ptVect)
{//判断点是否在多边形内部
inti,j,num,size;
doubled;
num=0;//射线与线段相交的点的个数
size=ptVect.size();
for(i=0;i<size;++i)
{//处理每条线段
j=i+1;
if(j==size)
{
j=0;
}
d=interSect(p,pc,ptVect[i],ptVect[j]);
if(d>0)
num++;//严格相交
elseif(d==0)
{//有一端点在另一直线上
if(ptVect[i].y>0||ptVect[j].y>0)
num++;
}
}
if(num%2==0)
returnfalse;
else
returntrue;
}
intmain(void)
{
intN,M,i,pX,pY,cases=0;
while(cin>>N&&N!=0)
{
cin>>M;
if(cases!=0)
cout<<endl;
vector<Point>pointVect;
for(i=0;i<N;++i)
{
cin>>points[i].x>>points[i].y;
pointVect.push_back(points[i]);
}
cout<<"Problem"<<++cases<<":"<<endl;
for(i=0;i<M;++i)
{
Pointp;
cin>>p.x>>p.y;
pc.x=Max,pc.y=p.y;//故意把射线点选择在同一水平线,无穷远处
if(IsOnEdge(p,pointVect))
{//在一条边上
cout<<"Within"<<endl;
continue;
}
elseif(isInside(p,pointVect))
{//在多边形内部
cout<<"Within"<<endl;
}
else
{
cout<<"Outside"<<endl;
}
}
}
return0;
}
本文介绍了一种计算几何中的基本算法——判断一个点是否位于一个多边形内部的方法。该方法通过从待判断的点出发绘制一条射线,并统计射线与多边形边界相交的次数来实现。如果交点数量为奇数,则认为该点在多边形内;反之则在外部。此外还考虑了特殊情况,如点恰好位于多边形的边上。
1051

被折叠的 条评论
为什么被折叠?



