24

标准凸包算法不适用于(经度、纬度)点,因为标准算法假定您需要一组笛卡尔点的包。纬度-经度点不是笛卡尔坐标,因为经度在反子午线(+/- 180 度)处“环绕”。即,经度179以东2度为-179。

因此,如果您的点集恰好跨越了反子午线,您将错误地计算出环绕世界的虚假船体。

关于我可以使用标准凸包算法来纠正这个问题的技巧的任何建议,或者指向正确的“地球”船体算法的指针?

现在我想起来了,除了跨越反经线之外,还有更多有趣的案例需要考虑。考虑一个环绕地球的点“带”——它的凸包没有东/西边界。或者更进一步,{(0,0), (0, 90), (0, -90), (90, 0), (-90, 0), (180, 0)} 的凸包是什么?——它似乎包含了地球的整个表面,那么它的周边有哪些点?

4

6 回答 6

8

标准的凸包算法并没有被地球表面坐标的环绕所打败,而是被一个更基本的问题所打败。球体的表面(让我们忘记地球的不完全球形)不是欧几里得空间,因此欧几里得几何学不起作用,而凸包例程假设基础空间是欧几里得(给我看一个不是) t,拜托)不会工作。

球体的表面符合椭圆几何的概念,其中线是大圆,对映点被认为是同一个点。您已经开始体验将欧几里得的凸性概念应用于椭圆空间所产生的问题。

对您开放的一种方法是采用测地线凸度的定义实施测地线凸包例程。这看起来很毛茸茸的。它可能不会产生符合您(通常是欧几里得)期望的结果。在许多情况下,对于 3 个任意点,凸包原来是球体的整个表面。

导航员和制图师多年来采用的另一种方法是将球体表面的一部分(包含所有点的部分)投影到欧几里得空间(这是地图投影的主题,我不会打扰你参考大量文献)并找出投影点的凸包。将您感兴趣的区域投影到平面上并调整坐标,使其不会环绕;例如,如果您对法国感兴趣,您可以通过添加 30 度来调整所有经度,以便整个国家由 +ve 数字协调。

在我写作时,@Li-aung Yip 的回答中提出的使用 3D 凸包算法的想法让我觉得被误导了。表面点集的 3D 凸包将包括位于球体内的点、边和面。这些实际上并不存在于球体的 2D 表面上,只会将您的困难从 2D 中不太正确的概念转变为 3D 中完全错误的概念。此外,我从我引用的维基百科文章中了解到,封闭的半球(即包括其“赤道”的半球)在球体表面的几何形状中不是凸的。

于 2012-03-13T09:25:25.870 回答
2

与其将您的数据视为经纬度数据,不如在 3D 空间中考虑它并应用3D 凸包算法?然后,您可以通过分析 3D 凸包找到您想要的 2D 凸包。

这将使您返回到用于笛卡尔凸包(尽管是三个维度)的广为人知的算法,并且没有坐标环绕的问题。

或者,还有这篇论文:Computing the Convex Hull of a Simple Polygon on the Sphere (1996),它似乎处理了您正在处理的一些相同问题(坐标环绕等)

于 2012-03-13T05:28:45.650 回答
1

未来书呆子:

你是绝对正确的。我必须为我的应用程序解决与 Maxy-B 完全相同的问题。作为第一次迭代,我只是将 (lng,lat) 视为 (x,y) 并运行标准的 2D 算法。只要没有人看得太近,这工作就很好,因为我所有的数据都在连续的美国。不过,作为第二次迭代,我使用了你的方法并证明了这个概念。

这些点必须在同一个半球。事实证明,选择这个半球并非易事(它不仅仅是点的中心,正如我最初猜测的那样。)为了说明,考虑以下四个点:(0,0),(-60,0), (+60,0) 沿赤道,和 (0,90) 北极。无论您选择如何定义“中心”,它们的中心对称地位于北极,并且所有四个点都在北半球。但是,请考虑将第四点替换为 (-19, 64) 冰岛。现在他们的中心不在北极,而是不对称地拉向冰岛。然而,这四个点仍然在北半球。此外,由北极唯一定义的北半球是它们共享的唯一半球。所以计算这个“极点”变成了算法,而不是代数。

请参阅我的 Python 代码存储库: https ://github.com/VictorDavis/GeoConvexHull

于 2014-08-29T18:22:31.703 回答
1

如果你所有的点都在一个半球内(也就是说,如果你能找到一个穿过地球中心的剖切面,把它们都放在一边),那么你可以从中心做一个中心又名 gnomic aka gnomonic 投影接地到平行于剖切面的平面。然后所有大圆在投影中变成直线,因此投影中的凸包将映射回地球上正确的凸包。您可以通过查看此处“Gnomonic Projection”部分中的纬度线来了解纬度/经度点的错误程度(注意经度线保持笔直)。

(将地球视为球体仍然不太正确,但它是一个很好的第二近似值。我不认为穿过更真实的地球(例如WGS84)的真正最短距离路径上的点通常位于通过中心。也许假装它们确实给你一个比你用球体得到的更好的近似值。)

于 2014-06-17T23:23:44.087 回答
0

球形凸包的所有边缘都可以视为/视为大圆(本质上,欧几里得空间中凸包的所有边缘都可以视为线(而不是线段))。这些大圆圈中的每一个都将球体切割成两个半球。因此,您可以将每个大圆圈视为一个约束。凸包内的一个点将位于每个约束定义的每个半球上。

原始多边形的每条边都是凸包的候选边。要验证它是否确实是凸包的边缘,您只需要验证多边形的所有节点是否都位于由穿过相关边缘的两个节点的大圆定义的半球上。但是,我们仍然需要创建超过多边形凹节点的新边。

但是让我们更快捷/蛮力地这样做:在多边形中的每对节点之间画一个大圆圈。在两个方向上都这样做(即连接 A 到 B 的大圆和连接 B 到 A 的大圆)。对于具有 N 个节点的多边形,您最终将得到 N^2 个大圆。这些大圆中的每一个都是一个候选约束(即凸多边形的候选边)。其中一些大圆圈将与原始多边形的边缘重叠,但大多数不会。现在,再次记住:每个大圆都是将球体约束到一个半球的约束。现在验证原始多边形的所有节点是否满足约束(即所有节点是否都在大圆定义的半球上)。如果是,那么这个大圆就是凸包的边缘。如果,

这样做的美妙之处在于,一旦将纬度和经度转换为指向单位球体的笛卡尔向量,它实际上只需要点积和叉积 - 你会通过叉积找到穿过球体上两个点的大圆 -如果大圆和该点的点积大于(或等于)0,则该点位于由大圆定义的半球上。因此,即使对于具有大量边的多边形,这种蛮力方法也应该可以正常工作.

于 2020-03-31T19:15:07.767 回答
0

这个问题已经回答了一段时间,但我想总结一下我的研究结果。

球形凸包基本上只针对非对映点定义。假设所有点都在同一个半球上,您可以通过两种主要方式计算它们的凸包:

  1. 使用 gnomonic/central 投影将点投影到平面并应用平面凸包算法。参见 Lin-Lin Chen, TC Woo,“球面上的计算几何与自动加工的应用”(1992 年)。如果这些点位于已知的半球上,您可以硬编码将这些点投影到哪个平面上。
  2. 使平面凸包算法适应球体。参见 C. Grima 和 A. Marquez,“曲面上的计算几何:在圆柱、球体、圆环和圆锥上执行计算几何”,Springer (2002)。这个参考似乎给出了与上面叶丽昂引用的摘要类似的方法。

作为参考,在 Python 中,我正在开发自己的实现,目前仅适用于北半球的点。

另请参阅有关数学溢出的这个问题。

于 2020-01-05T00:26:17.247 回答