用scala编写的多边形中的点
我想知道将这个C#方法转换为Scala函数的最佳方法,似乎使用Scala的sytax可以更简洁用scala编写的多边形中的点,scala,Scala,我想知道将这个C#方法转换为Scala函数的最佳方法,似乎使用Scala的sytax可以更简洁 bool IsPointInPolygon(List<Loc> poly, Loc point) { int i, j; bool c = false; for (i = 0, j = poly.Count - 1; i < poly.Count; j = i++) { if ((((poly[i].Lt <= point.Lt)
bool IsPointInPolygon(List<Loc> poly, Loc point)
{
int i, j;
bool c = false;
for (i = 0, j = poly.Count - 1; i < poly.Count; j = i++)
{
if ((((poly[i].Lt <= point.Lt) && (point.Lt < poly[j].Lt)) ||
((poly[j].Lt <= point.Lt) && (point.Lt < poly[i].Lt))) &&
(point.Lg < (poly[j].Lg - poly[i].Lg) * (point.Lt - poly[i].Lt) /
(poly[j].Lt - poly[i].Lt) + poly[i].Lg))
c = !c;
}
return c;
}
bool IsPointInPolygon(列表多边形,定位点)
{
int i,j;
boolc=假;
对于(i=0,j=poly.Count-1;i 如果(((poly[i].Lt认为您的算法是正确的,您可以观察到,每次满足某个条件时,通过切换得到的boolean
。因此您可以计算这些条件
此外,您正在成对迭代点(j
基本上是i-1
,如果我理解代码正确,除了初始迭代,其中j
必须包装回poly.Count-1
)
要获取对,如果poly
是scala.List
:
val pairs = (poly.last :: poly).sliding(2, 1)
在使用滑动
形成对之前,将最后一个元素放在列表的前面,例如
val x = List("a", "b", "c")
(x.last :: x).sliding(2,1).toList // gives List(List(c, a), List(a, b), List(b, c))
(严格地说,last
在scala.List
上不是一个非常有效的方法,但它是有效的)
那你会的
pairs.count { case Seq(pi, pj) => checkCondition } % 2 == 1
其中,case Seq(pi,pj)
再次为您提取相邻点,%2==1
询问您是否计数了奇数次
滑动的另一种替代方法是使用foldLeft
方法。这可能更具执行力,因为没有创建嵌套集合,但更像是一个SmartPass解决方案。诀窍是传递上一点和当前结果(原始代码中的c
):
这再次使用模式匹配(case…
)对折叠参数进行优雅的解包。如何:
sealed case class Loc(lat: Double, long: Double)
def isPointInPolygon(poly: List[Loc], x: Loc): Boolean = {
(poly.last :: poly).sliding(2).foldLeft(false) { case (c, List(i, j)) =>
val cond = {
(
(i.lat <= x.lat && x.lat < j.lat) ||
(j.lat <= x.lat && x.lat < i.lat)
) &&
(x.long < (j.long - i.long) * (x.lat - i.lat) / (j.lat - i.lat) + i.long)
}
if (cond) !c else c
}
}
密封箱等级Loc(横向:双,纵向:双)
def isPointInPolygon(多边形:列表[Loc],x:Loc):布尔={
(poly.last::poly).slideing(2).foldLeft(false){case(c,List(i,j))=>
val cond={
(
(i.lat我不确定我是否了解您是如何对照此处的实际点坐标进行检查的?
sealed case class Loc(lat: Double, long: Double)
def isPointInPolygon(poly: List[Loc], x: Loc): Boolean = {
(poly.last :: poly).sliding(2).foldLeft(false) { case (c, List(i, j)) =>
val cond = {
(
(i.lat <= x.lat && x.lat < j.lat) ||
(j.lat <= x.lat && x.lat < i.lat)
) &&
(x.long < (j.long - i.long) * (x.lat - i.lat) / (j.lat - i.lat) + i.long)
}
if (cond) !c else c
}
}