用scala编写的多边形中的点

用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)

我想知道将这个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) && (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
  }
}