微信小程序 地图 使用 射线法 判断目标点是否在多边形内部(可用于判断当前位置是否在某个区域内部)

请添加图片描述

射线法

原理

使用射线法来判断,目标点是否在多边形内部

这里简单说下,具体细节可以看这篇文章

平面几何:判断点是否在多边形内(射线法)

原理很简单,从点引出一条射线,计算射线和多边形的交点数量。

交点数如果是 奇数,说明点 多边形内;如果是 偶数,则点 不在 多边形内。

射线方向没有要求,通常选择水平或垂直方向的射线,能够有效减少计算量。这里选择 向右的射线

然后就是遍历多边形的所有边,判断边线段和射线是否有交点,有交点就给相交数加 1。

在这里插入图片描述

还需要处理一些特殊情况,就是 射线刚好穿过多边形的顶点的情况

① 点的两边都在射线同一侧
② 点的两边在射线不同侧
③ 与多边形的一条边共线

在这里插入图片描述

此时可以使用 叉积 判断 目标点是否在边的左侧/右侧

在这里插入图片描述

在这里插入图片描述

简要逻辑代码

const isPointInPolygon = (polygon, pt) => {
   
   
  let count = 0;
  for (let i = 0; i < polygon.length; i++) {
   
   
    let a = polygon[i];
    let b = polygon[(i + 1) % polygon.length];

    if (a.y > b.y) {
   
   
      [a, b] = [b, a];
    }

    if (a.y <= pt.y && b.y > pt.y) {
   
   
      const crossProduct = 
        (pt.x - a.x) * (b.y - a.y) - (b.x - a.x) * (pt.y - a.y);
      if (crossProduct === 0) {
   
   
        return true;
      }
      if (crossProduct > 0) {
   
   
        count++;
      }
    }
  }

  return count % 2 === 1;
};

小程序代码

项目结构树

.
├── app.js
├── app.json
├── app.wxss
├── data
│   └── map_data.js
├── pages
│   ├── polygons
│   │   ├── polygons.js
│   │   ├── polygons.json
│   │   ├── polygons.wxml
│   │   └── polygons.wxss
│   └── range
│       ├── range.js
│       ├── range.json
│       ├── range.wxml
│       └── range.wxss
├── project.config.json
├── project.private.config.json
└── sitemap.json

调试基础库

3.8.0

小程序配置

app.json

{
   
   
  "pages": [
      "pages/polygons/polygons",
      "pages/range/range"
  ],
  "window": {
   
   
      "backgroundTextStyle": "light",
      "navigationBarBackgroundColor": "#ffffff",
      "navigationBarTitleText": "点与多边形",
      "navigationBarTextStyle": "black"
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json",
  "lazyCodeLoading": "requiredComponents",
  "useExtendedLib": {
   
   
      "weui": true
  },
  "resolveAlias": {
   
   
    "@data/*": "data/*"
  }
}

地图数据

data/map_data.js

/* data/map_data.js */
// 地图相关
module.exports = {
   
   
  // 地图部分参数

  // 学校中心点坐标
  longitude: 110.27672,
  latitude: 25.0937,

  // 是否展示 POI 点
  enablepoi: true,
  // 是否显示带有方向的当前定位点
  showLocation: true,
  // 缩放级别
  scale: 16,

  // 闭合多边形
  points: [
    {
   
   
      "latitude": 25.098567,
      "longitude": 110.280995
    },
    {
   
   
      "latitude": 25.097711,
      "longitude": 110.281167
    },
    {
   
   
      "latitude": 25.096842,
      "longitude": 110.281137
    },
    {
   
   
      "latitude": 25.095527,
      "longitude": 110.280778
    },
    {
   
   
      "latitude": 25.092988,
      "longitude": 110.279991
    },
    {
   
   
      "latitude": 25.090947,
      "longitude": 110.279089
    },
    {
   
   
      "latitude": 25.088824,
      "longitude": 110.277994
    },
    {
   
   
      "latitude": 25.088921,
      "longitude": 110.277342
    },
    {
   
   
      "latitude": 25.088633,
      "longitude": 110.277057
    },
    {
   
   
      "latitude": 25.089162,
      "longitude": 110.275070
    },
    {
   
   
      "latitude": 25.090355,
      "longitude": 110.272274
    },
    {
   
   
      "latitude": 25.094758,
      "longitude": 110.274553
    },
    {
   
   
      "latitude"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值