尝试使用元组列表python计算多行相交

2024-09-29 21:26:23 发布

您现在位置:Python中文网/ 问答频道 /正文

编辑示例文件的Git Repohttps://github.com/tpubben/lineIntersect

我试图计算在x,y坐标系下的线的交点,这是基于一组相交的线与一条由多条线段组成的连续直线相交。在

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

lineA = [((x1, y1),(x2,y2)), ((x2,y2),(x3,y3))....]

交叉线以相同的方式表示,但是每条交叉线都是一条离散线(没有共享点):

^{pr2}$

我试图遍历连续线(lineA)并检查哪些交叉线与lineA的哪些线段相交。在

下面是线交点的示例图像: Crossing lines

到目前为止,我尝试了以下方法:

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

Tags: inforiffloatitemdetappend线段
1条回答
网友
1楼 · 发布于 2024-09-29 21:26:23

你的代码看起来像是在处理一组特定的数据(也就是说,我不知道“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]))

这就是总体思路。几何公式来自:

How do you detect where two line segments intersect?

相关问题 更多 >

    热门问题