点与多边形关系

点与多边形关系可以应用的地方:几何图形直接的碰撞检测

/**
 * !#en Test whether the point is in the polygon
 * !#zh 测试一个点是否在一个多边形中
 * @method pointInPolygon
 * @param {Vec2} point - The point
 * @param {Vec2[]} polygon - The polygon, a set of points
 * @return {boolean}
 */
function pointInPolygon(point, polygon) {
    var inside = false;
    var x = point.x;
    var y = point.y;

    // use some raycasting to test hits
    // https://github.com/substack/point-in-polygon/blob/master/index.js
    var length = polygon.length;

    for (var i = 0, j = length - 1; i < length; j = i++) {
        var xi = polygon[i].x, yi = polygon[i].y,
            xj = polygon[j].x, yj = polygon[j].y,
            intersect = (
                (yi > y) !== (yj > y)) //排除不在线段之间的点  即不在yi 与 yj 之间的 点
                && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);

        if (intersect) inside = !inside;
    }

    return inside;
}

解析:

1,函数参数: point 需要判断的点,polygon  是多边形顶点集合

2,多边形点表示多边形每条边的方式

var xi = polygon[i].x, yi = polygon[i].y,
xj = polygon[j].x, yj = polygon[j].y,

//多边形点:0、1、... i-2、i-1
//多边形边: (0,1)、(1,2)、(3,4)....(i-2,i-1),(i-1,0)

3,(yi > y) !== (yj > y)) 

(yi > y) !== (yj > y)) 
//排除不在线段之间的点 即不在yi 与 yj 之间的 点
//yi>y && y>=yj  或 yi<=y && y< yj    过顶点计算两次被排除,同时排除了共线问题

4,(x < (xj - xi) * (y - yi) / (yj - yi) + xi)

// (xj - xi) * (y - yi) / (yj - yi)
1,使用了直线两点式方程:(y-yi)/(yj-yi) = (x-xi)/(xj-xi) 
=> (xj - xi) * (y - yi) / (yj - yi) = (x-xi)
2,即等于 point向右平行x轴的射线与线段(i,j)的交点  
3,x的值:  
(x-xi) = (xj - xi) * (y - yi) / (yj - yi) 
=》 x = (xj - xi) * (y - yi) / (yj - yi) + xi

5,当线段(i,j) 取point的y值时,得到的x      如果x 大于point的x 则  point的x轴正方向的射线会与线段相交。如果小于 point的x 则不会

6,if (intersect) inside = !inside;

if (intersect) inside = !inside;
/**
 * inside 奇数取反 等于 true   偶数依然是其默认值 false
 * 
 * 奇数即为 在多边形内(包括在边上) inside 等于true
 * 偶数在 多边形外  inside 等于 false
 */

 参考资料:

判断点与多边形位置关系的算法综述 - 道客巴巴

如何判定一点是否在给定顶点的不规则封闭区域内? - 知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值