从这个点画条任意方向的射线, 判断与区域的边的交点, 交点是奇数个就是在区域内,偶数个不在。
/**
* 判断 点是否在多边形区域
* @param point 点
* @param vs 多边形区域的点的集合
* 三种传参方式
* 1. [[1,2],[2,3]]
* 2. [{x:1,y:2},{x:2,y:3}]
* 3. [1,2,2,3,3,4]
* @param start
* @param end
* @returns {*|boolean}
*/
function pointInPolygon(point, vs, start, end) {
if (vs.length > 0)
if (Array.isArray(vs[0])) {
return pointInPolygonNested(point, vs, start, end, false);
} else {
if (typeof vs[0].x !== 'undefined')
return pointInPolygonNested(point, vs, start, end, true);
else
return pointInPolygonFlat(point, vs, start, end);
}
}
// private
function pointInPolygonFlat(point, vs, start, end) {
var x = point[0], y = point[1];
var inside = false;
if (start === undefined) start = 0;
if (end === undefined) end = vs.length;
var len = (end - start) / 2;
for (var i = 0, j = len - 1; i < len; j = i++) {
var xi = vs[start + i * 2 + 0], yi = vs[start + i * 2 + 1];
var xj = vs[start + j * 2 + 0], yj = vs[start + j * 2 + 1];
var intersect = ((yi > y) !== (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
}
// private
function pointInPolygonNested(point, vs, start, end, isObject) {
var x = point[0], y = point[1];
var inside = false;
if (start === undefined) start = 0;
if (end === undefined) end = vs.length;
var len = end - start;
for (var i = 0, j = len - 1; i < len; j = i++) {
var xi, yi, xj, yj;
if (isObject) {
xi = vs[i + start].x;
yi = vs[i + start].y;
xj = vs[j + start].x;
yj = vs[j + start].y;
} else {
xi = vs[i + start][0];
yi = vs[i + start][1];
xj = vs[j + start][0];
yj = vs[j + start][1];
}
var intersect = ((yi > y) !== (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
}
// var polygon = [[1, 1], [1, 2], [2, 2], [2, 1]];
//
// console.log(pointInPolygon([1.5, 1.5], polygon)); // true
// console.log(pointInPolygon([4.9, 1.2], polygon)); // false
// console.log(pointInPolygon([1.8, 1.1], polygon)); // true
评论区