判断点在多边形内

1. 角度和判别法(适用于任意多边形)

double angle = 0;

realPointList::iterator iter1 = points.begin();

for (realPointList::iterator iter2 = (iter1 + 1); iter2 < points.end();++iter1, ++iter2)

{

double x1 = (*iter1).x - p.x;

double y1 = (*iter1).y - p.y;

double x2 = (*iter2).x - p.x;

double y2 = (*iter2).y - p.y;

angle += angle2D(x1, y1, x2, y2);

}

if (fabs(angle - span::PI2) < 0.01) return true;

else return false;

另外,可以使用bounding box来加速。

if (p.x < (*iter)->boundingBox.left ||

p.x > (*iter)->boundingBox.right ||

p.y < (*iter)->boundingBox.bottom ||

p.y > (*iter)->boundingBox.top) 。。。。。。

对于多边形来说,计算bounding box非常的简单。只需要把水平和垂直方向上的最大最小值找出来就可以了。

1. 角度和判别法(适用于任意多边形)

double angle = 0;
realPointList::iterator iter1 = points.begin();
for (realPointList::iterator iter2 = (iter1 + 1); iter2 < points.end();++iter1, ++iter2)
{
double x1 = (*iter1).x - p.x;
double y1 = (*iter1).y - p.y;
double x2 = (*iter2).x - p.x;
double y2 = (*iter2).y - p.y;
angle += angle2D(x1, y1, x2, y2);
}

if (fabs(angle - span::PI2) < 0.01) return true;
else return false;

另外,可以使用bounding box来加速。
if (p.x < (*iter)->boundingBox.left ||
p.x > (*iter)->boundingBox.right ||
p.y < (*iter)->boundingBox.bottom ||
p.y > (*iter)->boundingBox.top) 。。。。。。

对于多边形来说,计算bounding box非常的简单。只需要把水平和垂直方向上的最大最小值找出来就可以了。

对于三角形:第四点分别与三角形的两个点的交线组成的角度分别设为j1,j2,j3,只要j1+j2+j3>360就不在三角形范围中。

2. 水平/垂直交叉点数判别法(适用于任意多边形)

注意到如果从P作水平向左的射线的话,如果P在多边形内部,那么这条射线与多边形的交点必为奇数,如果P在多边形外部,则交点个数必为偶数(0也在内)。所以,我们可以顺序考虑多边形的每条边,求出交点的总个数。还有一些特殊情况要考虑。假如考虑边(P1,P2),
1)如果射线正好穿过P1或者P2,那么这个交点会被算作2次,处理办法是如果P的从坐标与P1,P2中较小的纵坐标相同,则直接忽略这种情况
2)如果射线水平,则射线要么与其无交点,要么有无数个,这种情况也直接忽略。
3)如果射线竖直,而P0的横坐标小于P1,P2的横坐标,则必然相交。
4)再判断相交之前,先判断P是否在边(P1,P2)的上面,如果在,则直接得出结论:P再多边形内部。

对于三角形:第四点分别与三角形的两个点的交线组成的角度分别设为j1,j2,j3,只要j1+j2+j3>360就不在三角形范围中。

2. 水平/垂直交叉点数判别法(适用于任意多边形)

注意到如果从P作水平向左的射线的话,如果P在多边形内部,那么这条射线与多边形的交点必为奇数,如果P在多边形外部,则交点个数必为偶数(0也在内)。所以,我们可以顺序考虑多边形的每条边,求出交点的总个数。还有一些特殊情况要考虑。假如考虑边(P1,P2),

1)如果射线正好穿过P1或者P2,那么这个交点会被算作2次,处理办法是如果P的从坐标与P1,P2中较小的纵坐标相同,则直接忽略这种情况

2)如果射线水平,则射线要么与其无交点,要么有无数个,这种情况也直接忽略。

3)如果射线竖直,而P0的横坐标小于P1,P2的横坐标,则必然相交。

4)再判断相交之前,先判断P是否在边(P1,P2)的上面,如果在,则直接得出结论:P再多边形内部。

==================================================================================

int CUtility::IsPtOnGon(const AcGePoint2dArray& ptArr,AcGePoint2d& pt)
{
if(ptArr.length()<=2) return 0;
//判是否在线上===================================================
AcGeCurve2d* pCurve = (AcGeCurve2d*) new AcGePolyline2d(ptArr);
if(pCurve->isOn(pt))
{
delete pCurve;
pCurve= NULL;
return 1;
}
delete pCurve;
pCurve = NULL;
//三角形===========================================================
if(ptArr.length() == 3)
{
AcGeVector2d a,b,c;
a = ptArr[0] - pt;
b = ptArr[1] - pt;
c = ptArr[2] - pt;
double angle = a.angleTo(b);
angle += b.angleTo(c);
angle += c.angleTo(a);

if(fabs(angle - PI*2.0) < 0.001) return 1;
return 0;
}

//多边形===============================================================
//判是否在Extend外
AcGePoint2d ptMin,ptMax;
FindExtInPtArr(ptArr,ptMin,ptMax);
if(pt.x - ptMin.x < 0.0001 || pt.x - ptMax.x > 0.0001) return 0;
if(pt.y - ptMin.y < 0.0001 || pt.y - ptMax.y > 0.0001) return 0;

//点到各顶点的夹角和=2PI
AcGeVector3dArray vArr;
AcGeVector3d pRef;
for(int i=0;i<ptArr.length();i++)
{
AcGeVector3d pVec = AcGePoint3d(ptArr[i].x,ptArr[i].y,0) - AcGePoint3d(pt.x,pt.y,0);
vArr.append(pVec);
}
double angle = 0.0;
int j=0;
for(int i=0;i<vArr.length()-1;i++)
{
pRef = vArr[i].crossProduct(vArr[i+1]);
pRef.normalize();
angle += -pRef.z * vArr[i].angleTo(vArr[i+1]);
j++;
}
pRef = vArr[j].crossProduct(vArr[0]);
pRef.normalize();

angle += -pRef.z * vArr[j].angleTo(vArr[0],pRef);
double sumAngle = PI*2.0;
if(fabs(fabs(angle) - sumAngle) < 0.001) return 1;
else return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值