向量叉乘法,只对非凹多边形有效,对于凹多边形需要切割为凸多边形。
设多边形的顶点依次为A1, A2 … An,要判断的点为P,那么:
判断目标点与多边形的每条边组成的三角形面积和,是否等于该多边形,相等则在多边形内部。
设多边形的顶点依次为1,2,...,n,要判断的点为P。用P点连接多边形各顶点:
夹角和判别法,只对非凹多边形有效,对于凹多边形需要切割为凸多边形。
判断目标点与所有边的夹角和是否为360度,为360度则在多边形内部。
从目标点出发引一条射线,看这条射线和多边形所有边的交点数目:
射线法就是做一条从P点出发的射线,当穿过区域边界的次数为偶数时该点在区域外,如果是奇数则在区域内:

一条射线穿过区域的边界只有两种情况,穿入和穿出:
一般为处理方便,都做水平方向的射线;以下几种情况需要特殊处理:
点在边界上,根据实际需要做区域内或区域外处理;
射线穿过交点:

射线穿过边(与边重合):与交点类似,可看做不穿越
W. Randolph Franklin提出的PNPoly可以非常方便地判断点是否在多边形内;假设多边形的坐标存放在一个数组里。
先分别找出多边形顶点的X坐标和Y坐标的最小/最大值,然后判断目标坐标点是否在这个四边形之内:
if (p.x < minX || p.x > maxX || p.y < minY || p.y > maxY) {
// 这个测试都过不了。。。直接返回false;
}
判断点是否在多边形内:
// nSize:多边形中的顶点数
// vert:包含多边形顶点的x和y坐标的数组。
// test:需要判断的点位置
int pnpoly (Point[] vert, int nSize, Point test) {
int i, j, c = 0;
for (i = 0, j = nSize-1; i < nSize; j = i++) {
if ( ( (vert.y[i]>test.y) != (vert.y[j]>test.y) ) && (test.x < (vert.x[j]-vert.x[i]) * (test.y-vert.y[i]) / (vert.y[j]-vert.y[i]) + vert.x[i]) )
c = !c;
}
return c;
}
每次计算都涉及到相邻的两个点和待测试点:
vert.y[i] ; 
相交点c的坐标为:
x
2
−
x
1
y
2
−
y
1
=
x
′
−
x
1
y
−
y
1
⇒
x
′
=
x
1
+
(
x
2
−
x
1
)
(
y
−
y
1
)
y
2
−
y
1
\frac{x_2-x_1}{y_2-y_1}=\frac{x'-x_1}{y-y_1} \\ \Rightarrow x'=x_1 + \frac{(x_2-x_1)(y-y_1)}{y_2-y_1}
y2−y1x2−x1=y−y1x′−x1⇒x′=x1+y2−y1(x2−x1)(y−y1)