如何从一组重叠的圆中计算出一组多边形?

Posted

技术标签:

【中文标题】如何从一组重叠的圆中计算出一组多边形?【英文标题】:How to compute the set of polygons from a set of overlapping circles? 【发布时间】:2021-12-22 06:08:31 【问题描述】:

这个问题是对this question的一些计算细节的扩展。

假设一个人有一组(可能重叠的)圆,并且希望计算这组圆所覆盖的面积。 (为简单起见,可以假设已经进行了一些预计算步骤,例如去掉完全包含在其他圆中的圆,以及这些圆诱导出一个连通分量。)

in Ants Aasma's and Timothy's Shields' answers 提到了一种方法,即重叠圆的面积只是圆切片和多边形的集合,两者的面积都很容易计算。

然而,我遇到的麻烦是这些多边形的计算。多边形的节点(由圆心和“外部”交点组成)很容易计算:

起初我认为选择一个随机节点并按顺时针顺序访问邻居的简单算法就足够了,但这可能会导致构建以下“外部”多边形,它不是正确多边形的一部分。

所以我想到了不同的方法。用于计算最小循环的广度优先搜索,但我认为可以轻松修改前面的反例,以便这种方法导致包含孔的“内部”多边形(因此不是正确的多边形)。

我在想也许运行一个拉斯维加斯风格的算法,取随机点,如果所述点在圆的交点中,尝试计算相应的多边形。如果存在这样的多边形,则删除构成该多边形的圆心和交点。重复直到没有圆心或交点。 这将避免最终计算“外部”多边形或“内部”多边形,但会引入新问题(在潜在的高运行时间之外)例如超过 2 个圆在单个交点中相交在计算一个多边形时可以删除所述交点,但对于下一个多边形仍然是必需的。

最后,我的问题是:如何计算这样的多边形?

PS:作为计算多边形后的一个额外问题,如何知道在计算某个圆形切片的面积时要考虑哪个角度,介于 theta 和 2PI - theta 之间?

【问题讨论】:

【参考方案1】:

一旦我们以正确的顺序获得多边形的点,计算面积就是not too difficult。

实现这一目标的方法是利用平面二元性。有关图表,请参阅关于 doubly connected edge list 表示的 Wikipedia 文章,但要点是,给定一个定向边缘,其右面位于多边形内部,该多边形中的下一个定向边是具有相同头部的前一个定向边的相反方向按顺时针顺序。

因此,我们将问题简化为找到多边形联合的定向边并确定每个头部的正确顺序。我们实际上是先解决后一个问题。圆盘的每个交叉点产生一个四边形。我们称中心 C 和 D 以及交点 A 和 B。不失一般性假设以 C 为中心的圆盘不小于以 D 为中心的圆盘。由 A→C←B 形成的内角小于 180 度, 所以该三角形的有符号面积是负的当且仅当 A→C 在 B→C 之前以顺时针顺序围绕 C,反过来当且仅当 B→D 在 A→D 之前以顺时针顺序围绕 D。

现在我们确定哪些边实际上是多边形边界。对于一个特定的磁盘,我们在它的中心周围有一堆从之前的角度间隔(每个从第一个端点到第二个端点顺时针方向扫过)。我们需要的是计算段联合的常见面试问题的更复杂版本。通常的扫描线算法会在扫描开放端点时增加覆盖计数,并在扫描闭合端点时减少覆盖计数,可以在这里进行调整,我们需要将计数初始化为不是 0,而是初始化为起始角度的适当覆盖数。

有一种方法可以在没有三角函数的情况下完成所有这些,只需减法、行列式和比较。

【讨论】:

我很不确定是否理解了您的解释,但简单地说,您是否可能会说我应该在圆心和交点之间交换无向边,以精确确定多边形内的哪边,在计算圆对之间的交点时可以确定哪些?然后合并弧的“内侧”以获得我的多边形?

以上是关于如何从一组重叠的圆中计算出一组多边形?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以选择多个多边形的最大重叠

包含一组点的多边形

给定一条射线和多边形,计算多边形内最大的圆,其中中心位于射线上,端点位于圆上

如何使用 Python 在一组点上绘制多边形(部分向内弯曲)边缘?

如何在顶点缓冲区数组中制作一组多边形的多个副本?

从一组范围计算并发