对同一行的段进行布尔运算
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]]
)
我一直在寻找关于几何问题的指导 我有 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]]
)