对同一行的段进行布尔运算

Boolean operations on segments of a same line

我一直在寻找关于几何问题的指导 我有 2 个位于同一条线上的线段,我想根据任何布尔运算剪裁这两个线段

Union, Intersection, Difference, Difference-Rev, Xor

预期结果应该是一个细分列表,因为案例可以 return 0,1 或 2 个细分

在我目前的方法中,我将线段定义为同一行上的一对 2 个数字(坐标)

Segment 1 : (2,13)
Segment 2: (8,16)

我的第一步是制作一个排序点数组

points = [2, 8, 13, 16]

其次是迭代并由其所有者标记点

Segment 1, Segment 2 or Both

最后,我需要根据布尔运算和标签进行选择

但目前我卡在了第二步,我不知道如何找到标签,然后根据布尔运算进行选择,有什么帮助吗?

将三胞胎 [coordinate, begin/end, segment number] 放入列表中。

对列表进行排序。

遍历列表。在每一点更改 code 添加或减去段号。所以code=3表示segement交集,code=1对应第一个segment only range.

根据所需的操作和 code 更改形成结果范围。这里我只是列举了你列表顺序中的操作。

当一段的结尾与另一段的开头重合时,我不确定该怎么办。当前排序将 end 放在 begin 之前,因此 union 将给出两个单独的范围。如果需要,更改 begin/end 字段的符号并使 code -= p[1] * p[2]

Python代码:

def boolops(s1, s2, op):
    pts = [[s1[0], 1, 1], [s1[1], -1, 1],[s2[0], 1, 2],[s2[1], -1, 2]]
    pts.sort()
    #print(pts)
    res = []
    code = 0
    oldcode = 0
    start = -1
    for p in pts:
        code += p[1] * p[2]
        #print(oldcode, code)
        if op == 0:  # union
            if oldcode == 0 and code:
                start = p[0]
            elif oldcode and code == 0:
                res.append([start, p[0]])
        elif op == 1: #intersection
            if code == 3:
                start = p[0]
            elif oldcode == 3:
                res.append([start, p[0]])
        elif op == 2: #diff s1-s2
            if code == 1:
                start = p[0]
            elif oldcode == 1:
                res.append([start, p[0]])
        elif op == 3: #rev diff s2-s1
            if code == 2:
                start = p[0]
            elif oldcode == 2:
                res.append([start, p[0]])
        elif op == 4: #xor
            if code % 3 > 0:
                start = p[0]
            else:
                res.append([start, p[0]])
        oldcode = code
    return res


print(boolops([2,10],[5,12], 0)) 
print(boolops([2,5],[10,12], 0))

print(boolops([2,10],[5,12], 1)) 
print(boolops([2,5],[10,12], 1))

print(boolops([2,10],[5,12], 2))
print(boolops([2,5],[10,12], 2))

print(boolops([2,10],[5,12], 3))
print(boolops([2,5],[10,12], 3))

print(boolops([2,10],[5,12], 4))
print(boolops([2,5],[10,12], 4))

[2, 12]]   #union
[[2, 5], [10, 12]]
[[5, 10]]  #intersection
[]
[[2, 5]]  #diff
[[2, 5]]   
[[10, 12]] #revdiff
[[10, 12]]
[[2, 5], [10, 12]]  #xor
[[2, 5], [10, 12]]

#full coverage tests
print(boolops([2,5],[1,6], 0))
print(boolops([2,5],[1,6], 1))
print(boolops([2,5],[1,6], 2))
print(boolops([2,5],[1,6], 3))
print(boolops([2,5],[1,6], 4)

[[1, 6]]
[[2, 5]]
[]
[[1, 2], [5, 6]]
[[1, 2], [5, 6]]

)