多边形扩展和收缩(凸多边形和凹多边形)

本文介绍了如何使用向量知识和三角公式在ES6环境下处理多边形的扩展和收缩。通过将经纬度转换为像素坐标,计算单位向量、点乘积和叉乘积,确定扩展或收缩的距离,最后将结果转换回经纬度坐标。适用于凸多边形和凹多边形的处理。
摘要由CSDN通过智能技术生成

背景介绍:

如下图所示,黑色是原多边形,红色是扩展的多边形,蓝色是收缩的多边形。这是最终的效果。
在这里插入图片描述
PS:楼主使用的是ES6的语法,地图是高德地图API

知识积累:

使用的是高中所学的向量的知识和三角公式知识。
对于向量:

  • 设二维向量:a = (a1, a2); b = (b1, b2);
  • 设三维向量:OA = (x1, y1, z1); OB = (x2, y2, z2);
  1. 向量点乘积:a · b = a1 * b1 + a2 * b2 = |a| |b| cos<a, b>
  2. 向量单位化:a 单位化后的 na = (a1 / Math.sqrt(a1 * a1 + a2 * a2), a1 / Math.sqrt(a1 * a1 + a2 * a2))
  3. 向量叉乘积:
    二维: a X b = (a1 * b2) - (a2 * b1)
    三维:OA X OB = (y1 * z2 - y2 * z1, x2 * z1 - x1 * z2, x1 * y2 - x2 * y1)
  4. 半角公式:

思路点拨:

在这里插入图片描述

  1. 用一个数组paths表示要操作的多边形。其中paths的格式为:[[117.14589,36.659714],[117.145278,36.658952],[117.14626,36.658505],[117.147017,36.659628]]
  2. 需要将paths的经纬度换成像素坐标。原因:如果使用经纬度和要扩展(收缩)大小做对比会有单位不统一的问题。解决方案:使用map.lnglatToPixel将经纬度换成像素坐标;使用map.pixelToLngLat将像素坐标转换成经纬度坐标。
  3. 如上图所示,PP1 = (x1 - x, y1 - y); PP2 = (x2 - x, y2 - y); 令vx1 = x1 - x;vy1 = y1 - y;vx2 = x2 - x;vy2 = y2 - y;则 PP1 = (vx1, vy1); PP2 = (vx2, vy2);
  4. PP1PP2 单位化后,就得到了v1 = (vx1 / n1, vy1 / n1) 和 v2 = (vx2 / n2, vy2 / n2)。其中n1 = norm(vx1, vy1);n2 = norm(vx2, vy2)
  5. PQ = v1 + v2 = (vx1 / n1 + vx2 / n2, vy1 / n1 + vy2 / n2)。设 vx = vx1 / n1 + vx2 / n2;vy = vy1 / n1 + vy2 / n2,则PQ = (vx, vy)。还需要对PQ做单位化,则PQ = (vx / n, vy / n),其中n = norm(vx, vy)。
  6. 根据向量点乘积的含义,可以得到cos<v1, v2> = (vx1 * vx2 + vy1 * vy2) / (n1 * n2);
  7. |PQ| = L / sin(<v1, v2> / 2) 经化简可得 L / Math.sqrt(1 - (v1x * v2x + v1y * v2y) / 2)
  8. 根据上述所说,就可以得到完整的PQ,现在加上P点坐标,就可以得到Q点坐标。
  9. 处理完成后,记得将像素坐标转成经纬度坐标。
  10. 在处理凹多边形时,需要使用叉乘积。用来判断是两向量的夹角是凹角还是凸角。
    若叉乘积 < 0,向量夹角为 凹角;若叉乘为OP1 X OP2,则 P1 - O - P2 为顺时针。
    若叉乘积 > 0,向量夹角为 凸角;若叉乘为OP1 X OP2,则 P1 - O - P2 为逆时针。
    若叉乘积 = 0,向量夹角为 平角;若叉乘为OP1 X OP2,则 P1 - O - P2 在一条直线上。
    因此在计算PQ 方向的时候,若为凸角, PQ = PP1 + PP2;若为凸角,PQ = P1P + P2P。无论是凸角还是凹角,|PQ| 是 恒定不变的,都为:|PQ| = L / Math.sqrt(1 - (v1x * v2x + v1y * v2y) / 2)

代码区域:

废话不多说,下面是完整代码(ES6),地图使用的是高德地图

评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值