2016-08-22 1 views
0

EDIT: Git repo pour des exemples de fichiershttps://github.com/tpubben/lineIntersectessayer de calculer plusieurs intersections de lignes en utilisant des listes de tuples python

Je suis en train de calculer les points d'intersection de ligne en coordonnées x, y basées sur un ensemble de lignes qui se croisent en traversant une ligne continue composée de plusieurs segments.

La ligne continue est représentée par une liste de tuples de la manière suivante, où chaque segment commence par la coordonnées x/y du point d'extrémité du segment précédent:

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

Les lignes de passage sont représentés de la même manière cependant chacun est une ligne discrète (pas de points communs):

lineB = [((x1, y1),(x2,y2))...] 

Je suis en train de parcourir la ligne continue (linea) et vérifier pour voir quelles lignes traversant se croisent avec les segments de linea.

Une image par exemple de ce que les intersections de la ligne ressembleraient est ici: Crossing lines

jusqu'à présent, je l'ai essayé ce qui suit:

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

Vous avez essayé et ...? Quelle est la question réelle? J'ai peu de motivation pour générer des données de test, exécuter votre code, puis * deviner * quelle est votre question. Quel est le problème avec votre code? Certaines données de test réelles avec une sortie attendue seraient bien. –

+0

Aussi, voulez-vous vraiment que la définition de 'line_intersection' soit dans la boucle comme ça? –

+0

Je suis assez nouveau à ce sujet ... mon employeur m'a jeté dans le feu pour ainsi dire parce que j'ai une certaine expérience avec HTML et CSS (apparemment langages de balisage == programmation). Je ne sais pas si je veux que dans une boucle imbriquée, les performances sont probablement sous-optimales mais les performances brutes n'a probablement pas trop d'importance. Comment puis-je joindre pour vous les fichiers de données de test acceptables? – haplessgeo

Répondre

-1

Votre code ressemble à cela face à un ensemble spécifique de données (c'est-à-dire que je n'ai aucune idée de ce à quoi se réfère le "startsWith ('N')" et ainsi de suite) je ne peux donc répondre à cette question que dans l'abstrait. Essayez de diviser le code en plusieurs fonctions qui effectuent une tâche spécifique, plutôt qu'une grande fonction qui essaie de tout faire. Vous trouverez beaucoup plus facile de travailler avec et dépanner.

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

Ceci est l'idée générale. Je suis les formules de géométrie de:

How do you detect where two line segments intersect?

+0

Merci de me répondre. Je travaille ma tête à travers ce que vous avez posté et je cours dans un barrage routier. Après avoir corrigé les erreurs de syntaxe (remarquablement peu nombreuses), j'obtiens une traceback qui m'indique que votre fonction getScalar ne fonctionne pas avec les tuples. FYI, merci de me rappeler de le décomposer en fonctions, beaucoup plus facile à lire. – haplessgeo

+0

Pour la fonction getScalar, un couple de tuples doit être passé (par exemple ((1,2), (2,3))) avec chaque tuple représentant un point du segment de ligne. J'ai aussi remarqué quelques autres erreurs: j'ai oublié de mettre des parenthèses autour du numérateur pour s et t, la première valeur dans la formule de t devrait être scalaireB [0], l'instruction if utilise "> =" au lieu de "<=" , et la déclaration d'impression à la fin utilise la syntaxe de formage incorrecte. Je vais corriger ceux-ci dans l'exemple original. – TripleD