webentwicklung-frage-antwort-db.com.de

Wie berechne ich den Schnittpunkt zweier Linien in Python?

Ich habe zwei Linien, die sich an einem Punkt schneiden. Ich kenne die Endpunkte der beiden Linien. Wie berechne ich den Schnittpunkt in Python?

# Given these endpoints
#line 1
A = [X, Y]
B = [X, Y]

#line 2
C = [X, Y]
D = [X, Y]

# Compute this:
point_of_intersection = [X, Y]
34
bolt19

Im Gegensatz zu anderen Vorschlägen ist dies kurz und verwendet keine externen Bibliotheken wie numpy. (Nicht dass die Verwendung anderer Bibliotheken schlecht ist ... es ist Nizza nicht nötig, besonders für so ein einfaches Problem.)

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

Und zu Ihrer Information würde ich Tupel anstelle von Listen für Ihre Punkte verwenden. Z.B.

A = (X, Y)
35
Paul Draper

Kann nicht beiseite stehen,

Wir haben also ein lineares System:

EIN1 * x + B1 * y = C1
EIN2 * x + B2 * y = C2

lass es uns mit der Cramer-Regel tun, also kann die Lösung in Determinanten gefunden werden:

x = Dx/ D
y = Dy/ D

wobei D die Hauptbestimmung des Systems ist:

EIN1 B1
EIN2 B2

und Dx und Dy kann aus Matrizen gefunden werden:

C1 B1
C2 B2

und

EIN1 C1
EIN2 C2

(Beachten Sie, da die Spalte C die Koef-Spalten von x und y ersetzt).

Also jetzt der Python, aus Gründen der Klarheit, um die Dinge nicht durcheinander zu bringen, machen wir ein Mapping zwischen Mathe und Python. Wir verwenden das Array L zum Speichern unserer Coefs A, B, C der Zeilengleichungen und des Intestead von ziemlich x, y wir haben [0], [1] , aber wie auch immer. Also, was ich oben geschrieben habe, wird das folgende Formular weiter im Code haben:

für D

L1 [0] L1 [1]
L2 [0] L2 [1]

für Dx

L1 [2] L1 [1]
L2 [2] L2 [1]

für Dy

L1 [0] L1 [2]
L2 [0] L2 [2]

Nun zum Codieren:

line - erzeugt Koefs A, B, C der Liniengleichung durch zwei bereitgestellte Punkte,
intersection - sucht den Schnittpunkt (falls vorhanden) zweier Linien, die von coefs bereitgestellt werden.

from __future__ import division 

def line(p1, p2):
    A = (p1[1] - p2[1])
    B = (p2[0] - p1[0])
    C = (p1[0]*p2[1] - p2[0]*p1[1])
    return A, B, -C

def intersection(L1, L2):
    D  = L1[0] * L2[1] - L1[1] * L2[0]
    Dx = L1[2] * L2[1] - L1[1] * L2[2]
    Dy = L1[0] * L2[2] - L1[2] * L2[0]
    if D != 0:
        x = Dx / D
        y = Dy / D
        return x,y
    else:
        return False

Anwendungsbeispiel:

L1 = line([0,1], [2,3])
L2 = line([2,3], [0,4])

R = intersection(L1, L2)
if R:
    print "Intersection detected:", R
else:
    print "No single intersection point detected"
47
rook

Verwendung der Formel aus: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection

 def findIntersection(x1,y1,x2,y2,x3,y3,x4,y4):
        px= ( (x1*y2-y1*x2)*(x3-x4)-(x1-x2)*(x3*y4-y3*x4) ) / ( (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4) ) 
        py= ( (x1*y2-y1*x2)*(y3-y4)-(y1-y2)*(x3*y4-y3*x4) ) / ( (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4) )
        return [px, py]
2
Gabriel Eng

Ich habe keine intuitive Erklärung im Web gefunden, und jetzt, da ich es herausgefunden habe, hier meine Lösung. Dies ist für unendliche Zeilen (was ich brauchte), keine Segmente.

Einige Begriffe, an die Sie sich vielleicht erinnern:

Eine Linie ist definiert als y = mx + b OR y = Steigung * x + y-Achsenabschnitt

Steigung = Anstieg über der Strecke = dy/dx = Höhe/Entfernung 

Der Y-Achsenabschnitt ist der Punkt, an dem die Linie die Y-Achse kreuzt, wobei X = 0 ist

In Anbetracht dieser Definitionen sind hier einige Funktionen:

def slope(P1, P2):
    # dy/dx
    # (y2 - y1) / (x2 - x1)
    return(P2[1] - P1[1]) / (P2[0] - P1[0])

def y_intercept(P1, slope):
    # y = mx + b
    # b = y - mx
    # b = P1[1] - slope * P1[0]
    return P1[1] - slope * P1[0]

def line_intersect(m1, b1, m2, b2):
    if m1 == m2:
        print ("These lines are parallel!!!")
        return None
    # y = mx + b
    # Set both lines equal to find the intersection point in the x direction
    # m1 * x + b1 = m2 * x + b2
    # m1 * x - m2 * x = b2 - b1
    # x * (m1 - m2) = b2 - b1
    # x = (b2 - b1) / (m1 - m2)
    x = (b2 - b1) / (m1 - m2)
    # Now solve for y -- use either line, because they are equal here
    # y = mx + b
    y = m1 * x + b1
    return x,y

Hier ist ein einfacher Test zwischen zwei (unendlichen) Zeilen:

A1 = [1,1]
A2 = [3,3]
B1 = [1,3]
B2 = [3,1]
slope_A = slope(A1, A2)
slope_B = slope(B1, B2)
y_int_A = y_intercept(A1, slope_A)
y_int_B = y_intercept(B1, slope_B)
print(line_intersect(slope_A, y_int_A, slope_B, y_int_B))

Ausgabe:

(2.0, 2.0)
1
Kiki Jewell

Hier ist eine Lösung mit der Shapely Bibliothek. Formschön wird häufig für GIS-Arbeiten verwendet, ist jedoch für die rechnergestützte Geometrie geeignet. Ich habe Ihre Eingaben von Listen in Tupel geändert.

Problem

# Given these endpoints
#line 1
A = (X, Y)
B = (X, Y)

#line 2
C = (X, Y)
D = (X, Y)

# Compute this:
point_of_intersection = (X, Y)

Lösung

import shapely
from shapely.geometry import LineString, Point

line1 = LineString([A, B])
line2 = LineString([C, D])

int_pt = line1.intersection(line2)
point_of_intersection = int_pt.x, int_pt.y

print(point_of_intersection)
1
user11708734

Wenn Ihre Linien stattdessen aus mehreren Punkten bestehen, können Sie diese Version verwenden.

enter image description here

import numpy as np
import matplotlib.pyplot as plt
"""
Sukhbinder
5 April 2017
Based on:    
"""

def _rect_inter_inner(x1,x2):
    n1=x1.shape[0]-1
    n2=x2.shape[0]-1
    X1=np.c_[x1[:-1],x1[1:]]
    X2=np.c_[x2[:-1],x2[1:]]    
    S1=np.tile(X1.min(axis=1),(n2,1)).T
    S2=np.tile(X2.max(axis=1),(n1,1))
    S3=np.tile(X1.max(axis=1),(n2,1)).T
    S4=np.tile(X2.min(axis=1),(n1,1))
    return S1,S2,S3,S4

def _rectangle_intersection_(x1,y1,x2,y2):
    S1,S2,S3,S4=_rect_inter_inner(x1,x2)
    S5,S6,S7,S8=_rect_inter_inner(y1,y2)

    C1=np.less_equal(S1,S2)
    C2=np.greater_equal(S3,S4)
    C3=np.less_equal(S5,S6)
    C4=np.greater_equal(S7,S8)

    ii,jj=np.nonzero(C1 & C2 & C3 & C4)
    return ii,jj

def intersection(x1,y1,x2,y2):
    """
INTERSECTIONS Intersections of curves.
   Computes the (x,y) locations where two curves intersect.  The curves
   can be broken with NaNs or have vertical segments.
usage:
x,y=intersection(x1,y1,x2,y2)
    Example:
    a, b = 1, 2
    phi = np.linspace(3, 10, 100)
    x1 = a*phi - b*np.sin(phi)
    y1 = a - b*np.cos(phi)
    x2=phi    
    y2=np.sin(phi)+2
    x,y=intersection(x1,y1,x2,y2)
    plt.plot(x1,y1,c='r')
    plt.plot(x2,y2,c='g')
    plt.plot(x,y,'*k')
    plt.show()
    """
    ii,jj=_rectangle_intersection_(x1,y1,x2,y2)
    n=len(ii)

    dxy1=np.diff(np.c_[x1,y1],axis=0)
    dxy2=np.diff(np.c_[x2,y2],axis=0)

    T=np.zeros((4,n))
    AA=np.zeros((4,4,n))
    AA[0:2,2,:]=-1
    AA[2:4,3,:]=-1
    AA[0::2,0,:]=dxy1[ii,:].T
    AA[1::2,1,:]=dxy2[jj,:].T

    BB=np.zeros((4,n))
    BB[0,:]=-x1[ii].ravel()
    BB[1,:]=-x2[jj].ravel()
    BB[2,:]=-y1[ii].ravel()
    BB[3,:]=-y2[jj].ravel()

    for i in range(n):
        try:
            T[:,i]=np.linalg.solve(AA[:,:,i],BB[:,i])
        except:
            T[:,i]=np.NaN


    in_range= (T[0,:] >=0) & (T[1,:] >=0) & (T[0,:] <=1) & (T[1,:] <=1)

    xy0=T[2:,in_range]
    xy0=xy0.T
    return xy0[:,0],xy0[:,1]


if __== '__main__':

    # a piece of a prolate cycloid, and am going to find
    a, b = 1, 2
    phi = np.linspace(3, 10, 100)
    x1 = a*phi - b*np.sin(phi)
    y1 = a - b*np.cos(phi)

    x2=phi
    y2=np.sin(phi)+2
    x,y=intersection(x1,y1,x2,y2)
    plt.plot(x1,y1,c='r')
    plt.plot(x2,y2,c='g')
    plt.plot(x,y,'*k')
    plt.show()
0
Paul Chen