[英]how to rewrite a more complex for loop from javascript to coffeescript?
I try to rewrite this piece of Javascript code, coming from http://jsfromhell.com/math/is-point-in-poly , in coffeescript. 我尝试用coffeescript重写来自http://jsfromhell.com/math/is-point-in-poly的这段Javascript代码。 It detects if a point is in a polygon, and works perfectly fine, but I am not sure what an elegant coffeescript translation would be?
它可以检测点是否在多边形中,并且可以很好地工作,但是我不确定优雅的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;
}
Just as a point of comparison (pun intended), here's a version of this algorithm I wrote several years ago as part of PolyGonzo (a fast polygon drawing library I used in Google's election maps). 作为比较点(双关语),这是我几年前作为PolyGonzo(我在Google的选举地图中使用的快速多边形图形库)的一部分编写的该算法的一个版本。 This is adapted from the original, which handled multipolygons as commonly used in geographic work instead of just single polygons.
这是从原始版本改编而来的,它处理了地理工作中常用的多面体,而不仅仅是单个面体。
I wrote this code for speed - it should be quite a bit faster than the code in the question for old browsers, and somewhat faster in new browsers. 我写这个代码是为了提高速度-它应该比旧浏览器中的问题代码快很多,而在新浏览器中则要快一些。 (I haven't benchmarked it in a while, but I suspect the difference is less now that browsers have gotten better at optimizing JavaScript.)
(我已经有一段时间没有对其进行基准测试了,但是我怀疑现在的差异已经越来越小,因为浏览器在优化JavaScript方面已经变得更好。)
For example, it avoids all of the repeated array and property dereferencing used in the jsfromhell example. 例如,它避免了jsfromhell示例中使用的所有重复数组和属性解引用。 I think it's a bit easier to read too.
我认为它也更容易阅读。 Of course the algorithm itself is still a bit complicated!
当然,算法本身仍然有点复杂!
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;
}
I don't really like the translation that js2coffee.org produces for that code. 我不太喜欢js2coffee.org为该代码生成的翻译。 In particular, the nested
if
statements in the loop turn into a long one-liner: 特别是,循环中的嵌套
if
语句变成了很长的单行代码:
inside = not inside if x1 + (y - y1) / (y2 - y1) * (x2 - x1) < x unless (y1 < y) is (y2 < y)
But it was easy to use that as a starting point and turn it into a nicer CoffeeScript version: 但是很容易以此为起点,并将其转换为更好的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
This is a few more lines of code than the other version, but again it's optimized more for speed than brevity. 这比其他版本多了几行代码,但是它再次针对速度而不是简洁性进行了优化。
I'd go with 我会去
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
( demo compilation ) ( 演示编译 )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.