合并同一圆上的所有重叠扇区

时间:2014-05-12 20:55:52

标签: algorithm

给定同一个圆(0-2pi)上的一组扇区(startAngle,stopAngle),我想减少该组,以便合并所有重叠/相交的扇区。优选地,在该过程中,我不想分割跨越360deg / 2pi的任何扇区。

使用"check if two segments on the same circle overlap / intersect"的交叉操作,似乎可以直接比较 pre - 排序集中的每个扇区(较小的startAngle优先)并合并任何相对的两个相交的扇区。但是,如果跨越360deg / 2pi的扇区首先分成两部分,那么这种方法似乎才有效。

任何人都可以帮助一个更优雅的解决方案,不涉及拆分任何部门? (最好是伪代码,Java或Ada)

Example: all sectors execpt the purple one, overlaps with another sector and shall be merged

3 个答案:

答案 0 :(得分:0)

我假设您使用(start_angle> end_angle)标记任何段跨越2pi。如果是这种情况,那么以下内容应该有效:

 Add 2pi to  end_angle of segments spanning 2pi. 
 Merge your segments (using your ordered start_angle method) over the range 0-4pi.
 If you only have one segment left, and start_angle > end_angle your segment covers the full circle.  
 Otherwise, subtract 2pi from any angle > 2pi (there will only be one of these at most).

您将得到一个完整的圆圈,或一个或多个独立的部分(其中一个可能跨越2pi)。

答案 1 :(得分:0)

这个解决方案确实涉及拆分扇区,但似乎比下面的那个更简单:

  • 将扇区拆分为起点和终点。

  • 在此{{p>

  • 的每个时间间隔内,在0处添加一个起点,在处添加一个终点。

  • 排序点 - 当两个点相等时,将起点放在第一位(以防止0大小的间隙)。

  • 通过这些点,保持当前重叠间隔的计数。

    • 在起点上:

      • 如果计数为0,则将当前点标记为扇区开始。

      • 增加点数。

    • 关于终点:

      • 减少计数。

      • 如果计数为0,则将扇区开始和当前点输出为扇区。

  • 如果您的某个部门从0开始,一个部门以结尾,请将两者合并。


不涉及拆分任何部门的解决方案:

  • 确定没有重叠间隔的点X

    • 将扇区拆分为起点和终点。

    • 添加到任何超过“开始”(0 / )的任何行程的终点,以使其在结束后结束排序

    • 排序点。

    • 通过积分,保持当前间隔的计数。

      • 在起点上,增加点数。

      • 在结束点,减少计数。

      • 如果计数为0,则停止 - 当前点没有重叠间隔。

  • 按照该点的值移动所有间隔。

    将每个点的值设置为(value + X's value) % 2π

    衡量积分 - 虽然完整的分类并非绝对必要 - 将开始和结束交织在一起并不太难以实现这一转变。

  • 继续按照上述解决方案中的说明进行操作。

  • 移动输出的扇区。

    将每个扇区的点的值设置为(2π + value - X's value) % 2π

答案 2 :(得分:0)

首先,将alfaalfa+2*pi相同的角度合并到列表L中,合并所有扇区。

然后,如果L中最后一个扇区的结束角度大于2*pi,则将其与L头部的扇区合并,直到找到任何不重叠的扇区。

更新:现在,使用一些代码:

#!/usr/bin/python3

from math import pi;
from random import random;
from operator import itemgetter;

def random_sector():
    start = random() * 2 * pi;
    end = start + random() * .5 * pi;
    return (start, end);

sectors = [random_sector() for i in range(10)]

sectors.sort(key=itemgetter(0))

print("all sectors: ", sectors)

out = [];
(start, end) = sectors.pop(0)
for s in sectors:
    if s[0] <= end:
        if s[1] > end:
            end = s[1]
    else:
        out.append((start, end))
        (start, end) = s

if end > 2 * pi:
    while out:
        s = out[0]
        if s[0] + 2 * pi <= end:
            out.pop(0)
            s_end = s[1] + 2 * pi
            if s_end > end:
                end = s_end
                break
        else:
            break

if end >= start + 2 * pi:
    out = [(0, 2*pi)]
else:
    out.append((start, end))

print("merged sectors: ", out)