Python 尝试使用元组列表计算多条直线交点
编辑:样本文件的Git Repo 我试图计算x,y坐标系中的线交点,基于一组相交线,这些相交线穿过由多个线段组成的一条连续线 连续线由元组列表表示,如下所示,其中每个段从上一段端点的x/y坐标开始:Python 尝试使用元组列表计算多条直线交点,python,line-intersection,Python,Line Intersection,编辑:样本文件的Git Repo 我试图计算x,y坐标系中的线交点,基于一组相交线,这些相交线穿过由多个线段组成的一条连续线 连续线由元组列表表示,如下所示,其中每个段从上一段端点的x/y坐标开始: lineA = [((x1, y1),(x2,y2)), ((x2,y2),(x3,y3))....] 交叉线以相同的方式表示,但每一条都是一条离散线(无共享点): 我试图通过连续线(lineA)进行迭代,并检查哪些交叉线与lineA的哪些线段相交 直线交点的示例图像如下所示: 到目前为止,我尝
lineA = [((x1, y1),(x2,y2)), ((x2,y2),(x3,y3))....]
交叉线以相同的方式表示,但每一条都是一条离散线(无共享点):
我试图通过连续线(lineA)进行迭代,并检查哪些交叉线与lineA的哪些线段相交
直线交点的示例图像如下所示:
到目前为止,我尝试了以下方法:
from __future__ import print_function
def newSurveys(nintyin, injectorin):
# pull data out of pre-prepared CSV files
fh = open(nintyin)
fho = open(injectorin)
rlines = fho.readlines()
rlines90 = fh.readlines()
segA = []
segB = []
segA90 = []
segB90 = []
for item in rlines:
if not item.startswith('M'):
item = item.split(',')
segA.append((float(item[4]),float(item[5])))#easting northing
segB.append((float(item[4]),float(item[5])))#easting northing
segB.pop(0)
z = len(segA)-1
segA.pop(z)
for item in rlines90:
if not item.startswith('N'):
item = item.split(',')
segA90.append((float(item[1]),float(item[0])))#easting northing
segB90.append((float(item[3]),float(item[2])))#easting northing
activeWellSegs = []
injector90Segs = []
for a, b in zip(segA, segB):
activeWellSegs.append((a,b))
for c, d in zip(segA90, segB90):
injector90Segs.append((c,d))
if len(activeWellSegs) >= len(injector90Segs):
lineA = activeWellSegs
lineB = injector90Segs
else:
lineA = injector90Segs
lineB = activeWellSegs
for l1 in lineA:
for l2 in lineB:
##### Use differential equation to calculate line intersections,
##### taken from another user's post
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])
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(l1, l2), file=lprint)
newSurveys('producer90.csv', 'injector.csv')
您的代码看起来像是在处理一组特定的数据(也就是说,我不知道“startsWith('N')”等等是指什么),所以我只能抽象地回答这个问题 尝试将代码拆分为多个函数来完成一项特定任务,而不是一个大函数来完成所有任务。您会发现使用和排除故障要容易得多
def getScalar(lineSegment):
return (lineSegment[1][0] - lineSegment[0][0],
lineSegment[1][1] - lineSegment[0][1])
def doTheyIntersect(lineA, lineB):
scalarA = getScalar(lineA)
scalarB = getScalar(lineB)
s = (-1.0 * scalarA[1] * (lineA[0][0] - lineB[0][0]) + scalarA[0] * (lineA[0][1] - lineB[0][1])) / (-1.0 * scalarB[0] * scalarA[1] + scalarA[0] * scalarB[1])
t = (scalarB[0] * (lineA[0][1] - lineB[0][1]) - scalarB[1] * (lineA[0][0] - lineB[0][0])) / (-1.0 * scalarB[0] * scalarA[1] + scalarA[0] * scalarB[1])
if 0.0 <= s <= 1.0 and 0.0 <= t <= 1.0:
return True
else:
return False
lineA = [(x, y), (x1, y1), ...]
lineB = [(x, y), (x1, y1), ...]
for index, segment in enumerate(lineA):
if index + 1 < len(lineA):
for index2 in range(0, len(lineB), 2):
if doTheyIntersect((lineA[index], lineA[index + 1]), (lineB[index2], lineB[index2+1])):
print("lineB ({0}, {1}) intersects lineA at ({2}, {3})".format(str(lineB[index2]),str(lineB[index2+1]), str(lineA[index]), str(lineA[index + 1]))
def getScalar(线段):
返回(线段[1][0]-线段[0][0],
线段[1][1]-线段[0][1])
def doTheyIntersect(直线A、直线B):
scalarA=getScalar(线性)
scalarB=getScalar(lineB)
s=(-1.0*scalarA[1]*(lineA[0][0]-lineB[0][0])+scalarA[0]*(lineA[0][1]-lineB[0][1])/(-1.0*scalarB[0]*scalarA[1]+scalarA[0]*scalarB[1])
t=(scalarB[0]*(lineA[0][1]-lineB[0][1])-scalarB[1]*(lineA[0][0]-lineB[0][0])/(-1.0*scalarB[0]*scalarA[1]+scalarA[0]*scalarB[1])
如果你尝试过0.0,那么?真正的问题是什么?我几乎没有动力生成测试数据,运行代码,然后猜猜你的问题是什么。你的代码有什么问题?一些具有预期输出的实际测试数据会很好。另外,你真的希望直线交叉点的定义像这样在循环中吗?我对这一点很陌生……可以说,我的雇主把我扔进了火中,因为我有一些HTML和CSS(显然是标记语言==编程)方面的经验。我不知道我是否希望在嵌套循环中实现这一点,就性能而言,它可能是次优的,但原始性能可能并不重要。如何为您附加可接受的测试数据文件?A
列表中的段数是否等于B
列表中的段数,如果是,则A
中的第一段是否与B
中的第一段相交。?如果是这样,您应该能够用单个循环替换嵌套循环。就发布数据而言——发布列表的示例更为合理lineA
和lineB
。代码中的文件输入输出部分会让人分心。将从文件中提取数据的逻辑与查找交点的逻辑分开(分成不同的功能)。不幸的是,数据类型的线段数永远不会相等,有时交叉线比连续线段多,而其他情况则相反。我在顶部添加了一个git repo链接,供任何对数据样本(以及列表)感兴趣的人使用。谢谢您回复我。我正在仔细研究你发布的内容,我遇到了一个路障。在修复了(非常少的)语法错误之后,我得到了一个回溯,它告诉我getScalar函数不能处理元组。仅供参考,感谢您提醒我将其分解为更易于阅读的函数。对于getScalar函数,它需要传入一个元组(例如((1,2),(2,3)),每个元组表示线段的一个点。我还注意到了一些其他错误:忘记在s和t的分子周围放括号,t公式中的第一个值应该是scalarB[0],if语句使用“>=”而不是
def getScalar(lineSegment):
return (lineSegment[1][0] - lineSegment[0][0],
lineSegment[1][1] - lineSegment[0][1])
def doTheyIntersect(lineA, lineB):
scalarA = getScalar(lineA)
scalarB = getScalar(lineB)
s = (-1.0 * scalarA[1] * (lineA[0][0] - lineB[0][0]) + scalarA[0] * (lineA[0][1] - lineB[0][1])) / (-1.0 * scalarB[0] * scalarA[1] + scalarA[0] * scalarB[1])
t = (scalarB[0] * (lineA[0][1] - lineB[0][1]) - scalarB[1] * (lineA[0][0] - lineB[0][0])) / (-1.0 * scalarB[0] * scalarA[1] + scalarA[0] * scalarB[1])
if 0.0 <= s <= 1.0 and 0.0 <= t <= 1.0:
return True
else:
return False
lineA = [(x, y), (x1, y1), ...]
lineB = [(x, y), (x1, y1), ...]
for index, segment in enumerate(lineA):
if index + 1 < len(lineA):
for index2 in range(0, len(lineB), 2):
if doTheyIntersect((lineA[index], lineA[index + 1]), (lineB[index2], lineB[index2+1])):
print("lineB ({0}, {1}) intersects lineA at ({2}, {3})".format(str(lineB[index2]),str(lineB[index2+1]), str(lineA[index]), str(lineA[index + 1]))