如何判断一个点在矩形或多边形内

先说一下,两个方法均是js实现,均是转载自其他大佬的文章,地址贴在下面

我最近接了个单子,里面有很多大棚,要求鼠标进入大棚范围高亮,我试过网上很多方法。大多不准确,或者说不适合有很多矩形、多边形的这种环境。后来找到了两种方法,可以实现。

放心,能满足我这种有很多矩形、多边形的 ,肯定也能满足你们那些多边形不多的需求

方法一:转载自JS实现判断点是否在多边形范围内 - 馨语随风 - 博客园 (cnblogs.com)

原理:在GIS领域,判断点是否在多边形范围内是一个基础方法,这里主要说下实现原理。原理比较简单,就是有一个GIS理论,一个点向一个方向发送射线,射线与多边形各个边相交的交点如果是奇数说明点在多边形范围内。

说一下我个人使用存在的误差:由于做鼠标的射线会穿过很多多边形,当这个线擦着其他多边形的点经过的时候,会判定相交一个点,这个时候那个多边形也会被点亮,还是有误差的。但如果多边形数量少的话可以使用,没问题

//判断点是否在多边形范围内
    function queryPtInPolygon(point, polygon) {
        var p1, p2, p3, p4;
 
        p1 = point;
        p2 = { x: 1000000000000, y: point.y };
 
        var count = 0;
        //对每条边都和射线作对比
        for (var i = 0; i < polygon.length - 1; i++) {
            p3 = polygon[i];
 
            p4 = polygon[i + 1];
            if (checkCross(p1, p2, p3, p4) == true) {
                count++;
            }
        }
        p3 = polygon[polygon.length - 1];
 
        p4 = polygon[0];
        if (checkCross(p1, p2, p3, p4) == true) {
            count++;
        }
 
        return (count % 2 == 0) ? false : true;
    }
 
        //判断两条线段是否相交
        function checkCross(p1, p2, p3, p4) {
            var v1 = { x: p1.x - p3.x, y: p1.y - p3.y },
            v2 = { x: p2.x - p3.x, y: p2.y - p3.y },
 
            v3 = { x: p4.x - p3.x, y: p4.y - p3.y },
            v = crossMul(v1, v3) * crossMul(v2, v3);
 
            v1 = { x: p3.x - p1.x, y: p3.y - p1.y };
            v2 = { x: p4.x - p1.x, y: p4.y - p1.y };
 
            v3 = { x: p2.x - p1.x, y: p2.y - p1.y };
            return (v <= 0 && crossMul(v1, v3) * crossMul(v2, v3) <= 0) ? true : false;
 
        }
 
        //计算向量叉乘
        function crossMul(v1, v2) {
            return v1.x * v2.y - v1.y * v2.x;
        }

使用示例

var point={x:10,y:10};
var polygon=[{x:0,y:0},{x:100,y:0},{x:100,y:100},{x:0,y:100},{x:0,y:0}];
     
var pts=queryPtInPolygon(points,polygon); //pts即为和多边形交叉的点集合,判断为奇数说明在多边形范围内

 

方法二:最牛逼的方法  转载自判断点是否在多边形内部 - 知乎 (zhihu.com)

function ContainsPoint(polygon, pointX, pointY) {
  let n = polygon.length >> 1;

  let ax, lup;
  let ay = polygon[2 * n - 3] - pointY;
  let bx = polygon[2 * n - 2] - pointX;
  let by = polygon[2 * n - 1] - pointY;

  if (bx === 0 && by === 0) return false; // point on edge

  // let lup = by > ay;
  for (let ii = 0; ii < n; ii++) {
    ax = bx;
    ay = by;
    bx = polygon[2 * ii] - pointX;
    by = polygon[2 * ii + 1] - pointY;
    if (bx === 0 && by === 0) return false; // point on edge
    if (ay === by) continue;
    lup = by > ay;
  }

  let depth = 0;
  for (let i = 0; i < n; i++) {
    ax = bx;
    ay = by;
    bx = polygon[2 * i] - pointX;
    by = polygon[2 * i + 1] - pointY;
    if (ay < 0 && by < 0) continue; // both 'up' or both 'down'
    if (ay > 0 && by > 0) continue; // both 'up' or both 'down'
    if (ax < 0 && bx < 0) continue; // both points on the left

    if (ay === by && Math.min(ax, bx) < 0) return true;
    if (ay === by) continue;

    let lx = ax + ((bx - ax) * -ay) / (by - ay);
    if (lx === 0) return false; // point on edge
    if (lx > 0) depth++;
    if (ay === 0 && lup && by > ay) depth--; // hit vertex, both up
    if (ay === 0 && !lup && by < ay) depth--; // hit vertex, both down
    lup = by > ay;
  }
  return (depth & 1) === 1;
}

polygon---组成多边形的点 [x1, y1, x2, y2, x3, y3, ...] 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值