【问题标题】:Javascript code for finding min distance from a point to polygon (as defined by html area)用于查找从点到多边形的最小距离的 Javascript 代码(由 html 区域定义)
【发布时间】:2012-11-02 11:39:10
【问题描述】:

我有一个定义了多个区域的图像地图,所有区域都是多边形

我想计算从图像上的一个点(通常由用户单击图像给出)到给定区域外边缘的闭合点的距离。

对于我来说,可以假设多边形的所有边都不相交,从而使任务变得更容易

检测点是在区域/多边形内部、之上还是外部也很有趣,例如,如果点在多边形内部,则距离为负,如果在边缘上,则距离为 0。

但这对我来说并不是那么重要,因为用户点击图像时给出的点很容易检测到。


这个问题的通用解决方案是here - 但我想知道是否有人已经在 javascript 中实现 来解决这个问题与图像地图和区域

我想做这样的事情:

var distance = calculateDistancePointToArea( xCoord, yCoord, areaId );

如果这适用于一个区域的所有可能形状,那将是一个额外的好处:矩形、圆形和多边形

【问题讨论】:

    标签: javascript html distance imagemap


    【解决方案1】:

    这是在javascript中计算两个坐标之间距离的函数。

    function(calculateDistancePointToArea(x2, y2, areaId))
    {
        var el1 = document.getElementById(areaId);
        var off1 = getOffset(el1);
        // center
        var x1 = off1.left;
        var y1 = off1.top;
        // distance
        var length = Math.sqrt(((x2-x1) * (x2-x1)) + ((y2-y1) * (y2-y1)));       
    }
    
    function getOffset( el ) {
        var _x = 0;
        var _y = 0;
        var _w = el.offsetWidth|0;
        var _h = el.offsetHeight|0;
        while( el && !isNaN( el.offsetLeft ) && !isNaN( el.offsetTop ) ) {
            _x += el.offsetLeft - el.scrollLeft;
            _y += el.offsetTop - el.scrollTop;
            el = el.offsetParent;
        }
        return {
            top: _y,
            left: _x,
            width: _w,
            height: _h
        };
    }
    

    希望它能给你一个想法和帮助。

    【讨论】:

      【解决方案2】:

      我为通用坐标编写了一个函数,如果您需要,可以将其转换为与您的 HTML 多边形一起使用。

      一个非常简单的解决方案:为每对多边形顶点求解一个方程。

      一种算法,用于多边形(图中灰色)的一个分段,点为 ab

      • 向量 A 只是一个坐标点
      • 向量 S(egment) = b - a
      • 向量 N 垂直于 S (-ys, xs)
      • 向量P是点的坐标

      您要检查从 pointSegment 的法线长度,并确保目标点在 Segment 内。

      这是您要解决的等式:

      在解中,i必须在0到1之间。如果是,则距离为|iN|,点为P + iN ,否则它是顶点之间最近的(a 和 b)。然后你可以找到每条边的最近点。

      这是一个搜索最近距离的 Javascript 代码,但它应该很容易修改为最近点:

      function vlen(vector) {
        return Math.sqrt(vector[0]*vector[0] + vector[1] * vector[1]);
      }
      
      function vsub(v1, v2) {
        return [v1[0] - v2[0], v1[1] - v2[1]];
      }
      
      function vscale(vector, factor) {
        return [vector[0] * factor, vector[1] * factor];
      }
      
      function vnorm(v) {
        return [-v[1], v[0]];
      }
      
      function distance_to_poly(point, poly) {
        var dists = $.map(poly, function(p1, i) {
          var prev = (i == 0 ? poly.length : i) - 1,
              p2 = poly[prev],
              line = vsub(p2, p1);
      
          if (vlen(line) == 0)
            return vlen(vsub(point, p1));
      
          var norm = vnorm(line),
              x1 = point[0],
              x2 = norm[0],
              x3 = p1[0],
              x4 = line[0],
              y1 = point[1],
              y2 = norm[1],
              y3 = p1[1],
              y4 = line[1],
      
              j = (x3 - x1 - x2 * y3 / y2 + x2 * y1 / y2) / (x2 * y4 / y2 - x4),
              i;
      
            if (j < 0 || j > 1)
              return Math.min(
                vlen(vsub(point, p1)),
                vlen(vsub(point, p2)));
      
            i = (y3 + j * y4 - y1) / y2;
      
            return vlen(vscale(norm, i));
        });
      
        return Math.min.apply(null, dists);
      }
      

      【讨论】:

        猜你喜欢
        • 2021-06-18
        • 1970-01-01
        • 2021-07-20
        • 2021-12-06
        • 2016-01-23
        • 2013-07-17
        • 1970-01-01
        • 2010-10-28
        • 1970-01-01
        相关资源
        最近更新 更多