scala - 用scala编写的多边形中的点

标签 scala

我想知道将此 C# 方法转换为 Scala 函数的最佳方法,看起来使用 scala 的语法可能会更简洁。

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 值是通过每次满足特定条件时进行切换来获得的。因此您可以计算这些条件。

此外,您将逐对迭代点(如果我正确理解代码,j 基本上是 i - 1,除了初始迭代,其中 j 必须换回 poly.Count - 1)。

要获取对,如果 polyscala.List:

val pairs = (poly.last :: poly).sliding(2, 1)

在与 sliding 形成对之前,将最后一个元素添加到列表中,例如

val x = List("a", "b", "c")
(x.last :: x).sliding(2,1).toList // gives List(List(c, a), List(a, b), List(b, c))

(严格来说,lastscala.List 上并不是一个非常有效的方法,但它确实有效)

那么你就会有

pairs.count { case Seq(pi, pj) => checkCondition } % 2 == 1

其中,case Seq(pi, pj) 再次为您提取相邻点,% 2 == 1 询问您是否计算了奇数次。


滑动的替代方法是使用 foldLeft 方法。这可能更具性能,因为没有创建嵌套集合,但更像是一个聪明的解决方案。诀窍是传递前一点当前结果(原始代码中的c):

poly.foldLeft(poly.last -> false) { case ((pj, c), pi) => pi -> (c ^ checkCondition)}

这再次使用模式匹配(case ...)来优雅地解包折叠参数。

关于scala - 用scala编写的多边形中的点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11640630/

相关文章:

scala - 如何使用 Scrooge 生成的 Thrift Scala 类?

scala - 如何在 Phantom 中从 SetColumn[String] 选择字段

java.lang.NoClassDefFoundError : org/apache/logging/log4j/Logger 错误

scala - Scala 中的惯用 Haskell 式迭代?

scala - destroy() 和 unpersist() 有什么区别?

用于 Euler 项目的 Scala 无形代码 #1

scala - 将 Scala Set 转换为 Java (java.util.Set)?

scala - Scala 中固有层次结构中的对象初始化序列

scala - 如何在Spark中读取多个行元素,其中每个日志记录都以yyyy-MM-dd格式开头,并且每个日志记录都是多行?

scala - Ga特林 - Scala - 每个并发用户的随机字符串