【问题标题】:How to find line intersections with single line equation array in a pythonic way如何以pythonic方式查找与单线方程数组的线交点
【发布时间】:2023-04-02 04:44:01
【问题描述】:

在不使用 for 循环的情况下,在由 m,c 值组成的数组中查找线交点的最 Pythonic 方式是什么?

lines=np.array([m0,c0],
               [m1,c1],
               [m2,c2],
               ....)

使用 for 循环实现所需的结果将包括以下内容:

for i in lines:
 for n in lines:
   np.linalg.solve(i, n)

【问题讨论】:

标签: python performance python-3.x numpy


【解决方案1】:

y1 = a1*x + b1y2 = a2*x + b2 两条线相交的方程式是x = (b2 - b1) / (a1 - a2)

通过使用broadcasting,可以很容易地计算任意数量的线之间的所有交点:

import numpy as np    

# lines of the form y = a * x + b
# with lines = [[a0, b0], ..., [aN, bN]]
lines = np.array([[1, 0], [0.5, 0], [-1, 3], [1, 2]])

slopes = lines[:, 0]  # array with slopes (shape [N])
slopes = slopes[:, np.newaxis]  # column vector (shape [N, 1])

offsets = lines[:, 1]  # array with offsets (shape [N])
offsets = offsets[:, np.newaxis]  # column vector (shape [N, 1])

# x-coordinates of intersections
xi = (offsets - offsets.T) / (slopes.T - slopes) 

# y-coordinates of intersections
yi = xi * slopes + offsets

这是通过将逐元素 - 运算符应用于形状 [N, 1] 的列向量并且它是形状 [1, N] 的转置来实现的。向量被广播到一个形状为 [N, N] 的矩阵。

最终结果是两个对称矩阵xiyi。每个条目xi[m, n] 是行mn 的交点。 nan 表示这些线是相同的(它们在每个点上相交)。 inf 表示线不相交。

让我们炫耀一下结果:

#visualize the result
import matplotlib.pyplot as plt
for l in lines:
    x = np.array([-5, 5])
    plt.plot(x, x * l[0] + l[1], label='{}x + {}'.format(l[0], l[1]))
for x, y in zip(xi, yi)    :
    plt.plot(x, y, 'ko')
plt.legend()
plt.show()

【讨论】:

  • 可能需要强调的是,当您执行slopes = lines[:, [0]](而不是lines[:, 0])时,您正在创建一个二维切片,而不是更常见的一维切片。这使您可以使用.T 而不是更冗长(但也更常见)的[None, :] 进行广播。不是每个人都能像这样在脑海中解析花哨的索引:)
  • @DanielF 好点 :) 你确定像 lines[:, 0][:, np.newaxis]lines[:, np.newaxis, 0] 这样的东西更具可读性吗?
  • 它在 2D 中当然不是更易读,但它更明确,因此当你超过 2 维时更具可读性(在我看来)。对于 2D,您的方法更具可读性,但用于设置它的精美索引可能会让初学者感到困惑。
  • 不要混淆 - 通常我不会将 linesoffsets 数组构造为 2D,但会做 xi = (offsets - offsets[none, :]) / (slopes[none, :] - slopes) - 在广播步骤期间显式制作 xi 2d。这比您的方法可读性差,但随着维度的变大变得更具可读性(imo)。
  • 我同意。我什至会写(offsets[:, None] - offsets[None, :]) 让它超级明确。
猜你喜欢
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 2017-12-13
  • 2012-08-15
  • 1970-01-01
  • 2020-04-01
  • 2018-01-27
  • 1970-01-01
相关资源
最近更新 更多