Python 尝试使用元组列表计算多条直线交点

Python 尝试使用元组列表计算多条直线交点,python,line-intersection,Python,Line Intersection,编辑:样本文件的Git Repo 我试图计算x,y坐标系中的线交点,基于一组相交线,这些相交线穿过由多个线段组成的一条连续线 连续线由元组列表表示,如下所示,其中每个段从上一段端点的x/y坐标开始: lineA = [((x1, y1),(x2,y2)), ((x2,y2),(x3,y3))....] 交叉线以相同的方式表示,但每一条都是一条离散线(无共享点): 我试图通过连续线(lineA)进行迭代,并检查哪些交叉线与lineA的哪些线段相交 直线交点的示例图像如下所示: 到目前为止,我尝

编辑:样本文件的Git Repo

我试图计算x,y坐标系中的线交点,基于一组相交线,这些相交线穿过由多个线段组成的一条连续线

连续线由元组列表表示,如下所示,其中每个段从上一段端点的x/y坐标开始:

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]))