Как вычислить точку пересечения двух линий в Python?



У меня есть две линии, которые пересекаются в одной точке. Я знаю конечные точки этих двух линий. Как вычислить точку пересечения в 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]
5261   6  

6 ответов:

В отличие от других предложений, он короткий и не использует внешние библиотеки, такие как numpy. (Не то, чтобы использование других библиотек является bad...it приятно не надо, особенно для такой простой задачи.)

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

И к вашему сведению, я бы использовал кортежи вместо списков для ваших очков. Например,

A = (X, Y)

Не могу стоять в стороне,

Итак, мы имеем линейную систему:

A1 * x + B1 * y = C1
А2 * x + B2 * y = C2

Давайте сделаем это с помощью правила Крамера, чтобы решение можно было найти в детерминантах:

X = D x /D
y = D y/D

Где D - главный детерминант системы:

A1 B1
А2 B2

И D x и D y можно найти из matricies:

C1 B1
С2 B2

И

A1 С1
А2 С2

(обратите внимание, что столбец C соответственно заменяет coef. столбцы x и y )

Итак, теперь python, для ясности для нас, чтобы не испортить вещи, давайте сделаем отображение между math и python. Мы будем использовать массив L для хранения наших coefs A, B, C линейных уравнений и intestead pretty x, y мы будем иметь [0], [1], но все равно. Таким образом, то, что я написал выше, будет иметь следующий вид в дальнейшем в коде:

Для D

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

Для D x

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

Для D y

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

Теперь переходим к кодированию:

line - производит coefs A, B, C линейного уравнения по двум точкам при условии,
intersection - находит точку пересечения (если таковая имеется) двух линий, предоставляемых coefs.

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

Пример использования:

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"

Я не нашел интуитивного объяснения в интернете, поэтому теперь, когда я это понял, вот мое решение. Это для бесконечных линий (то, что мне нужно), а не сегментов.

Некоторые термины, которые вы можете запомнить:

Линия определяется как y = mx + b или y = slope * x + y-intercept

Наклон = подъем = ду / ДХ = высота / расстояние

Y-перехват, где линия пересекает ось Y, где X = 0

Учитывая эти определения, вот некоторые из них: функции:

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

Вот простой тест между двумя (бесконечными) линиями:

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

Вывод:

(2.0, 2.0)

Используя формулу из: 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]

Comments

  1. Sergey
    Sergey 5 лет назад
    <pre>
    <code>необходимо учесть случай деления на ноль
    def slope(P1, P2):
    # dy/dx
    # (y2 - y1) / (x2 - x1)
    # divide zero
    </code></pre>

    <p>    if (P2[0] - P1[0]) == 0:</p>

    <p>        return 0</p>

    <p>    else:</p>

    <p>        return(P2[1] - P1[1]) / (P2[0] - P1[0])<code> </code></p>

    <pre>
    <code>
    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</code></pre>
  2. Sergey
    Sergey 5 лет назад
    <p># для отрезков</p>

    <p># intersection lines</p>

    <p>def slope(P1, P2):</p>

    <p>    # dy/dx</p>

    <p>    # (y2 - y1) / (x2 - x1)</p>

    <p>    if (P2[0] - P1[0]) == 0:</p>

    <p>        return 0</p>

    <p>    else:</p>

    <p>        return(P2[1] - P1[1]) / (P2[0] - P1[0])</p>

    <p> </p>

    <p>def y_intercept(P1, slope):</p>

    <p>    # y = mx + b</p>

    <p>    # b = y - mx</p>

    <p>    # b = P1[1] - slope * P1[0]</p>

    <p>    return P1[1] - slope * P1[0]</p>

    <p> </p>

    <p>def line_intersect(m1, b1, m2, b2):</p>

    <p>    if m1 == m2:</p>

    <p>        print ("These lines are parallel!!!")</p>

    <p>        return None</p>

    <p>    # y = mx + b</p>

    <p>    # Set both lines equal to find the intersection point in the x direction</p>

    <p>    # m1 * x + b1 = m2 * x + b2</p>

    <p>    # m1 * x - m2 * x = b2 - b1</p>

    <p>    # x * (m1 - m2) = b2 - b1</p>

    <p>    # x = (b2 - b1) / (m1 - m2)</p>

    <p>    x = (b2 - b1) / (m1 - m2)</p>

    <p>    # Now solve for y -- use either line, because they are equal here</p>

    <p>    # y = mx + b</p>

    <p>    y = m1 * x + b1</p>

    <p>    return x,y</p>

    <p> </p>

    <p>def otrezok(a,b):</p>

    <p>    if ( ((a[0]&gt;b[0]) and (a[1]&gt;b[1]) ) or ((a[0]&lt;b[0]) and (a[1]&lt;b[1]) )  ):</p>

    <p>        print("Lines short")</p>

    <p>        return None</p>

    <p>A1 = [10,1]</p>

    <p>A2 = [30,30]</p>

    <p>B1 = [21,16]</p>

    <p>B2 = [21,6]</p>

    <p>slope_A = slope(A1, A2)</p>

    <p>slope_B = slope(B1, B2)</p>

    <p>y_int_A = y_intercept(A1, slope_A)</p>

    <p>y_int_B = y_intercept(B1, slope_B)</p>

    <p>d=line_intersect(slope_A, y_int_A, slope_B, y_int_B)</p>

    <p>print(type(d))#line_intersect(slope_A, y_int_A, slope_B, y_int_B))</p>

    <p>print(d)</p>

    <p>print(otrezok(A1,d))</p>