Python 如何计算两条直线的交点?

Python 如何计算两条直线的交点?,python,geometry,line,intersect,Python,Geometry,Line,Intersect,我有两条在一点相交的线。我知道这两条线的端点。在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] 与其他建议不同,它很短,并且不使用像numpy这样的外部库。(并不是说使用其他库不好……不用这样做很好,特别是对于这样一个简单的问题。) 仅供参考,我会使用

我有两条在一点相交的线。我知道这两条线的端点。在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]

与其他建议不同,它很短,并且不使用像
numpy
这样的外部库。(并不是说使用其他库不好……不用这样做很好,特别是对于这样一个简单的问题。)

仅供参考,我会使用元组而不是列表来表示你的观点。例如

A = (X, Y)

编辑:最初有一个打字错误。那是2014年9月,多亏了@zidik

这只是以下公式的Python音译,其中行是(a1a2)和(b1b2),交点是p。(如果分母为零,则线没有唯一的交点。)

不能袖手旁观

我们有线性系统:

A1*x+B1*y=C1
A2*x+B2*y=C2

让我们用克拉默法则来做,这样就可以在行列式中找到解:

x=Dx/D
y=Dy/D

其中D是系统的主要决定因素:

A1 B1
A2 B2

Dx和Dy可从矩阵中找到:

C1 B1
C2 B2

A1 C1
A2 C2

(注意,C列因此取代了x和y的系数列)

现在,为了让我们更清楚,为了不把事情搞砸,让我们在数学和python之间进行映射。我们将使用数组
L
存储直线方程的系数A、B、C,而不是漂亮的
x
y
,我们将有
[0]
[1]
,但无论如何。因此,我在上面所写的内容将在代码中进一步采用以下形式:

对于D

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

对于Dx

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

对于Dy

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

现在开始编码:

line
-通过提供的两点生成直线方程的系数A、B、C,
交点
-查找coefs提供的两条直线的交点(如果有)

来自未来进口部的

def管路(p1、p2):
A=(p1[1]-p2[1])
B=(p2[0]-p1[0])
C=(p1[0]*p2[1]-p2[0]*p1[1])
返回A,B,-C
def交叉口(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]
如果D!=0:
x=Dx/D
y=Dy/D
返回x,y
其他:
返回错误
用法示例:

L1=行([0,1],[2,3])
L2=直线([2,3],[0,4])
R=交叉口(L1、L2)
如果R:
打印“检测到交叉点:”,R
其他:
打印“未检测到单个交点”

我在网上找不到直观的解释,所以现在我已经解决了,下面是我的解决方案。这是为无限的线(我需要的),而不是段

您可能还记得一些术语:

直线定义为y=mx+b或y=slope*x+y-截距

坡度=上升超过行程=dy/dx=高度/距离

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
下面是两条(无限)线之间的一个简单测试:

输出:

(2.0, 2.0)
使用以下公式:


如果线是多个点,则可以使用

将numpy导入为np
将matplotlib.pyplot作为plt导入
"""
苏克宾德
2017年4月5日
基于:
"""
定义直接内部(x1,x2):
n1=x1.形状[0]-1
n2=x2.形状[0]-1
X1=np.c_X1[:-1],X1[1:]
X2=np.c_X2[:-1],X2[1:]
S1=np.tile(X1.min(轴=1),(n2,1)).T
S2=np.瓷砖(X2.最大值(轴=1),(n1,1))
S3=np.瓦片(X1.最大值(轴=1),(n2,1)).T
S4=np.瓦片(X2.最小(轴=1),(n1,1))
返回S1、S2、S3、S4
定义矩形交叉点(x1,y1,x2,y2):
S1、S2、S3、S4=内部(x1、x2)
S5、S6、S7、S8=内部(y1、y2)
C1=np.小于等于(S1,S2)
C2=np.大于等于(S3,S4)
C3=np.小于等于(S5,S6)
C4=np.大于等于(S7,S8)
ii,jj=np.非零(C1&C2&C3&C4)
返回ii,jj
def交叉点(x1、y1、x2、y2):
"""
曲线的交点。
计算两条曲线相交的(x,y)位置。曲线
可以使用NAN断开或具有垂直段。
用法:
x、 y=交点(x1,y1,x2,y2)
例子:
a、 b=1,2
phi=np.linspace(3,10100)
x1=a*phi-b*np.sin(phi)
y1=a-b*np.cos(φ)
x2=φ
y2=np.sin(φ)+2
x、 y=交点(x1,y1,x2,y2)
plt.图(x1,y1,c='r')
平面图(x2,y2,c='g')
plt.绘图(x,y,'*k')
plt.show()
"""
ii,jj=_矩形_交点_uux1,y1,x2,y2)
n=len(ii)
dxy1=np.diff(np.c_x1,y1],轴=0)
dxy2=np.diff(np.c_x2,y2],轴=0)
T=np.零((4,n))
AA=np.零((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.零((4,n))
BB[0,:]=-x1[ii].ravel()
BB[1,:]=-x2[jj].ravel()
BB[2,:]=-y1[ii].拉威尔()
BB[3,:]=-y2[jj].ravel()
对于范围(n)中的i:
尝试:
T[:,i]=np.linalg.solve(AA[:,:,i],BB[:,i])
除:
T[:,i]=np.NaN

在_range=(T[0,:]>=0)和(T[1,:]>=0)和(T[0,:]中,这里有一个使用该库的解决方案。Shapely通常用于GIS工作,但其构建对于计算几何非常有用。我将您的输入从列表更改为元组

问题
#给定这些端点
#第1行
A=(X,Y)
B=(X,Y)
#第2行
C=(X,Y)
D=(X,Y)
#计算如下:
交点的点=(X,Y)
解决方案 你可以用这个柯德

class Nokta:
def __init__(self,x,y):
    self.x=x
    self.y=y             
class Dogru:
def __init__(self,a,b):
    self.a=a
    self.b=b        

def Kesisim(self,Dogru_b):
    x1= self.a.x
    x2=self.b.x
    x3=Dogru_b.a.x
    x4=Dogru_b.b.x
    y1= self.a.y
    y2=self.b.y
    y3=Dogru_b.a.y
    y4=Dogru_b.b.y                          
    #Notlardaki denklemleri kullandım
    pay1=((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3))      
    pay2=((x2-x1) * (y1 - y3) - (y2 - y1) * (x1 - x3))
    payda=((y4 - y3) *(x2-x1)-(x4 - x3)*(y2 - y1))        

    if pay1==0 and pay2==0 and payda==0:
        print("DOĞRULAR BİRBİRİNE ÇAKIŞIKTIR")

    elif payda==0:               
        print("DOĞRULAR BİRBİRNE PARALELDİR")        
    else:                               
        ua=pay1/payda if payda else 0                   
        ub=pay2/payda  if payda else 0  
        #x ve y buldum 
        x=x1+ua*(x2-x1) 
        y=y1+ua*(y2-y1)
        print("DOĞRULAR {},{} NOKTASINDA KESİŞTİ".format(x,y))

我发现的最简洁的解决方案使用Sympy:


这些是线段还是直线?这个问题主要归结为“做数学运算”。你可以使用代数运算找到交点坐标的表达式,然后将该表达式插入到你的程序中。不过,记住要先检查平行线。在询问问题之前先搜索stackoverflow
(2.0, 2.0)
 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]
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 __name__ == '__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()
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)
class Nokta:
def __init__(self,x,y):
    self.x=x
    self.y=y             
class Dogru:
def __init__(self,a,b):
    self.a=a
    self.b=b        

def Kesisim(self,Dogru_b):
    x1= self.a.x
    x2=self.b.x
    x3=Dogru_b.a.x
    x4=Dogru_b.b.x
    y1= self.a.y
    y2=self.b.y
    y3=Dogru_b.a.y
    y4=Dogru_b.b.y                          
    #Notlardaki denklemleri kullandım
    pay1=((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3))      
    pay2=((x2-x1) * (y1 - y3) - (y2 - y1) * (x1 - x3))
    payda=((y4 - y3) *(x2-x1)-(x4 - x3)*(y2 - y1))        

    if pay1==0 and pay2==0 and payda==0:
        print("DOĞRULAR BİRBİRİNE ÇAKIŞIKTIR")

    elif payda==0:               
        print("DOĞRULAR BİRBİRNE PARALELDİR")        
    else:                               
        ua=pay1/payda if payda else 0                   
        ub=pay2/payda  if payda else 0  
        #x ve y buldum 
        x=x1+ua*(x2-x1) 
        y=y1+ua*(y2-y1)
        print("DOĞRULAR {},{} NOKTASINDA KESİŞTİ".format(x,y))
# import sympy and Point, Line 
from sympy import Point, Line 
  
p1, p2, p3 = Point(0, 0), Point(1, 1), Point(7, 7) 
l1 = Line(p1, p2) 
  
# using intersection() method 
showIntersection = l1.intersection(p3) 
  
print(showIntersection)