0

我尝试用咖啡脚本重写这段来自http://jsfromhell.com/math/is-point-in-poly的 Javascript 代码。它检测一个点是否在多边形中,并且工作得很好,但我不确定优雅的咖啡脚本翻译会是什么?

function isPointInPoly(poly, pt){
  for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
    ((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y))
    && (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)
    && (c = !c);
return c;
}
4

2 回答 2

4

作为一个比较点(双关语),这是我几年前作为 PolyGonzo(我在 Google 的选举地图中使用的快速多边形绘图库)的一部分编写的该算法的一个版本。这改编自原始版本,它处理地理工作中常用的多面体,而不仅仅是单个多边形。

我写这段代码是为了速度——它应该比旧浏览器问题中的代码快很多,在新浏览器中要快一些。(我已经有一段时间没有对它进行基准测试了,但我怀疑现在浏览器在优化 JavaScript 方面做得更好了,差异会变小。)

例如,它避免了 jsfromhell 示例中使用的所有重复数组和属性取消引用。我认为它也更容易阅读。当然算法本身还是有点复杂的!

function pointInPoly( poly, point ) {
    var inside = false,
        x = point.x, y = point.y,
        n = poly.length,
        vertex = poly[ n - 1 ],
        x1 = vertex.x, y1 = vertex.y;

    for( var i = 0;  i < n;  ++i ) {
        vertex = poly[i];
        var x2 = vertex.x, y2 = vertex.y;

        if( ( y1 < y ) != ( y2 < y ) )
            if( x1 + ( y - y1 ) / ( y2 - y1 ) * ( x2 - x1 ) < x )
                inside = ! inside;

        x1 = x2, y1 = y2;
    }

    return inside;
}

我不太喜欢 js2coffee.org 为该代码生成的翻译。特别是,if循环中的嵌套语句变成了一个很长的单行语句:

inside = not inside  if x1 + (y - y1) / (y2 - y1) * (x2 - x1) < x  unless (y1 < y) is (y2 < y)

但是很容易将其用作起点并将其变成更好的 CoffeeScript 版本:

pointInPoly = ( poly, point ) ->
    inside = false
    x = point.x
    y = point.y

    vertex = poly[ poly.length - 1 ]
    x1 = vertex.x
    y1 = vertex.y

    for vertex in poly
        x2 = vertex.x
        y2 = vertex.y
        if ( y1 < y ) != ( y2 < y )
            if x1 + ( y - y1 ) / ( y2 - y1 ) * ( x2 - x1 ) < x
                inside = not inside
        x1 = x2
        y1 = y2

    inside

这比其他版本多几行代码,但它再次优化速度而不是简洁。

于 2013-09-30T17:39:53.870 回答
1

我会去

isPointInPoly = (poly, pt) ->
  c = false
  j = poly.length - 1
  for b, i in poly
    a = poly[j]
    if ((a.y <= pt.y && pt.y < b.y) || (b.y <= pt.y && pt.y < a.y)) && (pt.x < (b.x - a.x) * (pt.y - a.y) / (b.y - a.y) + a.x)
      c = not c
    j = i
  c

演示编译

于 2013-09-30T15:50:51.190 回答