首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Numpy和线的交叉点

Numpy和线的交叉点
EN

Stack Overflow用户
提问于 2010-07-15 11:03:26
回答 10查看 72.1K关注 0票数 35

我如何使用numpy来计算两个线段之间的交点?

在代码中,我有segment1 = ((x1,y1),(x2,y2))segment2 = ((x1,y1),(x2,y2))。注意:segment1不等于segment2。所以在我的代码中,我也一直在计算斜率和y截距,如果可以避免,那就好了,但我不知道如何避免。

我在用Python编写的函数中使用了Cramer规则,但我想找到一种更快的方法来实现这一点。

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2010-07-15 11:13:47

直接从https://web.archive.org/web/20111108065352/https://www.cs.mun.ca/~rod/2500/notes/numpy-arrays/numpy-arrays.html盗取

代码语言:javascript
复制
#
# line segment intersection using vectors
# see Computer Graphics by F.S. Hill
#
from numpy import *
def perp( a ) :
    b = empty_like(a)
    b[0] = -a[1]
    b[1] = a[0]
    return b

# line segment a given by endpoints a1, a2
# line segment b given by endpoints b1, b2
# return 
def seg_intersect(a1,a2, b1,b2) :
    da = a2-a1
    db = b2-b1
    dp = a1-b1
    dap = perp(da)
    denom = dot( dap, db)
    num = dot( dap, dp )
    return (num / denom.astype(float))*db + b1

p1 = array( [0.0, 0.0] )
p2 = array( [1.0, 0.0] )

p3 = array( [4.0, -5.0] )
p4 = array( [4.0, 2.0] )

print seg_intersect( p1,p2, p3,p4)

p1 = array( [2.0, 2.0] )
p2 = array( [4.0, 3.0] )

p3 = array( [6.0, 0.0] )
p4 = array( [6.0, 3.0] )

print seg_intersect( p1,p2, p3,p4)
票数 45
EN

Stack Overflow用户

发布于 2017-03-11 04:56:18

代码语言:javascript
复制
import numpy as np

def get_intersect(a1, a2, b1, b2):
    """ 
    Returns the point of intersection of the lines passing through a2,a1 and b2,b1.
    a1: [x, y] a point on the first line
    a2: [x, y] another point on the first line
    b1: [x, y] a point on the second line
    b2: [x, y] another point on the second line
    """
    s = np.vstack([a1,a2,b1,b2])        # s for stacked
    h = np.hstack((s, np.ones((4, 1)))) # h for homogeneous
    l1 = np.cross(h[0], h[1])           # get first line
    l2 = np.cross(h[2], h[3])           # get second line
    x, y, z = np.cross(l1, l2)          # point of intersection
    if z == 0:                          # lines are parallel
        return (float('inf'), float('inf'))
    return (x/z, y/z)

if __name__ == "__main__":
    print get_intersect((0, 1), (0, 2), (1, 10), (1, 9))  # parallel  lines
    print get_intersect((0, 1), (0, 2), (1, 10), (2, 10)) # vertical and horizontal lines
    print get_intersect((0, 1), (1, 2), (0, 10), (1, 9))  # another line for fun

解释

请注意,直线的方程式是ax+by+c=0。因此,如果一个点在这条线上,那么它就是(a,b,c).(x,y,1)=0的解决方案(.是点积)

l1=(a1,b1,c1)l2=(a2,b2,c2)是两条线,p1=(x1,y1,1)p2=(x2,y2,1)是两个点。

查找通过两点的直线:

t=p1xp2 (两点的叉积)是表示一条直线的向量。

我们知道p1在线上t是因为t.p1 = (p1xp2).p1=0。我们也知道p2t上是因为t.p2 = (p1xp2).p2=0。所以t必须是通过p1p2的那条线。

这意味着我们可以通过取直线上两个点的叉积来获得该直线的向量表示。

查找交点:

现在,假设r=l1xl2 (两条线的叉积)是表示一个点的向量

我们知道rl1上撒谎是因为r.l1=(l1xl2).l1=0。我们也知道rl2上撒谎是因为r.l2=(l1xl2).l2=0。因此,r必须是线l1l2的交点。

有趣的是,我们可以通过取两条直线的叉积来找到交点。

票数 28
EN

Stack Overflow用户

发布于 2012-02-02 18:44:42

这可能是一个很晚的回复,但当我在谷歌上搜索“numpy line intersections”时,它是第一次点击。在我的例子中,我在一个平面上有两条线,我想快速得到它们之间的任何交点,而Hamish的解决方案会很慢--需要在所有线段上嵌套一个for循环。

下面是如何在不使用for循环的情况下做到这一点(它非常快):

代码语言:javascript
复制
from numpy import where, dstack, diff, meshgrid

def find_intersections(A, B):

    # min, max and all for arrays
    amin = lambda x1, x2: where(x1<x2, x1, x2)
    amax = lambda x1, x2: where(x1>x2, x1, x2)
    aall = lambda abools: dstack(abools).all(axis=2)
    slope = lambda line: (lambda d: d[:,1]/d[:,0])(diff(line, axis=0))

    x11, x21 = meshgrid(A[:-1, 0], B[:-1, 0])
    x12, x22 = meshgrid(A[1:, 0], B[1:, 0])
    y11, y21 = meshgrid(A[:-1, 1], B[:-1, 1])
    y12, y22 = meshgrid(A[1:, 1], B[1:, 1])

    m1, m2 = meshgrid(slope(A), slope(B))
    m1inv, m2inv = 1/m1, 1/m2

    yi = (m1*(x21-x11-m2inv*y21) + y11)/(1 - m1*m2inv)
    xi = (yi - y21)*m2inv + x21

    xconds = (amin(x11, x12) < xi, xi <= amax(x11, x12), 
              amin(x21, x22) < xi, xi <= amax(x21, x22) )
    yconds = (amin(y11, y12) < yi, yi <= amax(y11, y12),
              amin(y21, y22) < yi, yi <= amax(y21, y22) )

    return xi[aall(xconds)], yi[aall(yconds)]

然后使用它,提供两行作为参数,其中is arg是一个2列矩阵,每行对应一个(x,y)点:

代码语言:javascript
复制
# example from matplotlib contour plots
Acs = contour(...)
Bsc = contour(...)

# A and B are the two lines, each is a 
# two column matrix
A = Acs.collections[0].get_paths()[0].vertices
B = Bcs.collections[0].get_paths()[0].vertices

# do it
x, y = find_intersections(A, B)

玩得开心

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3252194

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档