需要找到迭代多个线段的两条线段的交点
Need to find the intersection point of two line segments iterated over multiple segments
好的,问题来了。我试图通过比较从一系列 csv 文件中读出的多条线段来计算两条线的交点。我已经将每个线段的 x、y 坐标对放入元组中的元组列表中,如下所示:
continuousLine = [((x1,y1),(x2,y2)), ...]
crossingLines = [((x1,y1),(x2,y2)), ...]
我想弄清楚如何沿着连续线和交叉线进行迭代,以找出每条交叉线沿着连续线相交的位置。
基本上我想要的(下面列出的伪代码):
for segment in continuousLine:
if segment in crossingLines intersect == True:
return intersection
else:
move on to next crossing line segment and repeat test
我讨厌在这方面寻求帮助,因为我对编码太陌生,无法帮助其他人,但希望有人能和我一起解决这个问题。
我确实有一个方法,我认为一旦我弄清楚迭代器就可以计算交集:
line1 = ()
line2 = ()
def line_intersection(line1, line2):
xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1]) #Typo was here
def det(a, b):
return a[0] * b[1] - a[1] * b[0]
div = det(xdiff, ydiff)
if div == 0:
raise Exception('lines do not intersect')
d = (det(*line1), det(*line2))
x = det(d, xdiff) / div
y = det(d, ydiff) / div
return x, y
print line_intersection((A, B), (C, D))
假设函数 line_intersection
会在 div == 0
上 return False 而不是引发异常。
简单的方法:
filter(None, [intersection(a, b) for a in continuousLine for b in crossingLines])
但是,使用嵌套循环,当crossingLines中有很多段时速度很慢。
更高效的方法:
要提高性能,请尝试 intervaltree,这将为您提供用于测试的相交候选项。在你的情况下,首先在 crossingLines 上构建一个间隔树,然后循环遍历 continuousLine 以找到该树中的相交候选者,并进行测试以获得最终结果。
由于您没有提供任何示例输入和预期输出,我将使用如下所示的 line_intersection()
函数的虚拟版本。它所做的只是打印其输入和 returns 一个硬编码结果 — 但它会向您展示如何遍历输入数据并将其传递给实际函数。
从输出中应该清楚它在做什么。
def line_intersection(line1, line2):
print('intersecting:')
print(' ({}. {}), ({}, {})'.format(line1[0][0], line1[0][1],
line1[1][0], line1[1][1]))
print(' ({}. {}), ({}, {})'.format(line2[0][0], line2[0][1],
line2[1][0], line2[1][1]))
print('')
return 100, 200
所有循环都放在一个名为 find_intersections()
的生成器函数中,它找到 returns 个连续的交叉点,跳过任何没有找到的组合。
def find_intersections(continuous_line, crossing_lines):
for cl_segment in continuous_line:
for xl_segment in crossing_lines:
try:
x, y = line_intersection(cl_segment, xl_segment)
except Exception:
pass
else:
yield x, y
这是一个使用虚构输入数据的用法示例:
continuous_line = [((1,2),(3,4)), ((5,6),(7,8)), ((9,10),(11,12))]
crossing_lines = [((21,22),(23,24)), ((25,26),(27,28)), ((29,30),(31,32))]
intersections = [(x, y) for x, y in
find_intersections(continuous_line, crossing_lines)]
print('intersections found:')
print(intersections)
输出:
intersecting:
(1. 2), (3, 4)
(21. 22), (23, 24)
intersecting:
(1. 2), (3, 4)
(25. 26), (27, 28)
intersecting:
(1. 2), (3, 4)
(29. 30), (31, 32)
intersecting:
(5. 6), (7, 8)
(21. 22), (23, 24)
intersecting:
(5. 6), (7, 8)
(25. 26), (27, 28)
intersecting:
(5. 6), (7, 8)
(29. 30), (31, 32)
intersecting:
(9. 10), (11, 12)
(21. 22), (23, 24)
intersecting:
(9. 10), (11, 12)
(25. 26), (27, 28)
intersecting:
(9. 10), (11, 12)
(29. 30), (31, 32)
intersections found:
[(100, 200), (100, 200), (100, 200), (100, 200), (100, 200), (100, 200), (100,
200), (100, 200), (100, 200)]
好的,问题来了。我试图通过比较从一系列 csv 文件中读出的多条线段来计算两条线的交点。我已经将每个线段的 x、y 坐标对放入元组中的元组列表中,如下所示:
continuousLine = [((x1,y1),(x2,y2)), ...]
crossingLines = [((x1,y1),(x2,y2)), ...]
我想弄清楚如何沿着连续线和交叉线进行迭代,以找出每条交叉线沿着连续线相交的位置。
基本上我想要的(下面列出的伪代码):
for segment in continuousLine:
if segment in crossingLines intersect == True:
return intersection
else:
move on to next crossing line segment and repeat test
我讨厌在这方面寻求帮助,因为我对编码太陌生,无法帮助其他人,但希望有人能和我一起解决这个问题。
我确实有一个方法,我认为一旦我弄清楚迭代器就可以计算交集:
line1 = ()
line2 = ()
def line_intersection(line1, line2):
xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1]) #Typo was here
def det(a, b):
return a[0] * b[1] - a[1] * b[0]
div = det(xdiff, ydiff)
if div == 0:
raise Exception('lines do not intersect')
d = (det(*line1), det(*line2))
x = det(d, xdiff) / div
y = det(d, ydiff) / div
return x, y
print line_intersection((A, B), (C, D))
假设函数 line_intersection
会在 div == 0
上 return False 而不是引发异常。
简单的方法:
filter(None, [intersection(a, b) for a in continuousLine for b in crossingLines])
但是,使用嵌套循环,当crossingLines中有很多段时速度很慢。
更高效的方法:
要提高性能,请尝试 intervaltree,这将为您提供用于测试的相交候选项。在你的情况下,首先在 crossingLines 上构建一个间隔树,然后循环遍历 continuousLine 以找到该树中的相交候选者,并进行测试以获得最终结果。
由于您没有提供任何示例输入和预期输出,我将使用如下所示的 line_intersection()
函数的虚拟版本。它所做的只是打印其输入和 returns 一个硬编码结果 — 但它会向您展示如何遍历输入数据并将其传递给实际函数。
从输出中应该清楚它在做什么。
def line_intersection(line1, line2):
print('intersecting:')
print(' ({}. {}), ({}, {})'.format(line1[0][0], line1[0][1],
line1[1][0], line1[1][1]))
print(' ({}. {}), ({}, {})'.format(line2[0][0], line2[0][1],
line2[1][0], line2[1][1]))
print('')
return 100, 200
所有循环都放在一个名为 find_intersections()
的生成器函数中,它找到 returns 个连续的交叉点,跳过任何没有找到的组合。
def find_intersections(continuous_line, crossing_lines):
for cl_segment in continuous_line:
for xl_segment in crossing_lines:
try:
x, y = line_intersection(cl_segment, xl_segment)
except Exception:
pass
else:
yield x, y
这是一个使用虚构输入数据的用法示例:
continuous_line = [((1,2),(3,4)), ((5,6),(7,8)), ((9,10),(11,12))]
crossing_lines = [((21,22),(23,24)), ((25,26),(27,28)), ((29,30),(31,32))]
intersections = [(x, y) for x, y in
find_intersections(continuous_line, crossing_lines)]
print('intersections found:')
print(intersections)
输出:
intersecting:
(1. 2), (3, 4)
(21. 22), (23, 24)
intersecting:
(1. 2), (3, 4)
(25. 26), (27, 28)
intersecting:
(1. 2), (3, 4)
(29. 30), (31, 32)
intersecting:
(5. 6), (7, 8)
(21. 22), (23, 24)
intersecting:
(5. 6), (7, 8)
(25. 26), (27, 28)
intersecting:
(5. 6), (7, 8)
(29. 30), (31, 32)
intersecting:
(9. 10), (11, 12)
(21. 22), (23, 24)
intersecting:
(9. 10), (11, 12)
(25. 26), (27, 28)
intersecting:
(9. 10), (11, 12)
(29. 30), (31, 32)
intersections found:
[(100, 200), (100, 200), (100, 200), (100, 200), (100, 200), (100, 200), (100,
200), (100, 200), (100, 200)]