簡體   English   中英

如何重寫從JavaScript到coffeescript的更復雜的for循環?

[英]how to rewrite a more complex for loop from javascript to coffeescript?

我嘗試用coffeescript重寫來自http://jsfromhell.com/math/is-point-in-poly的這段Javascript代碼。 它可以檢測點是否在多邊形中,並且可以很好地工作,但是我不確定優雅的coffeescript翻譯是什么嗎?

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;
}

作為比較點(雙關語),這是我幾年前作為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

這比其他版本多了幾行代碼,但是它再次針對速度而不是簡潔性進行了優化。

我會去

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

演示編譯

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM