Python 在2D numpy数组中查找给定角度的最近项
给定numpy 2D数组,从给定角度的指定坐标(其中“X”位于)获取最近项(例如“1”)的最佳方法是什么 例如,假设在如下所示的二维数组中,X位于(1,25)处。假设角度为225度,假设0度垂直向右,90度垂直向上。如何获得朝向该矢量方向的“1”的最近坐标Python 在2D numpy数组中查找给定角度的最近项,python,numpy,matrix,angle,Python,Numpy,Matrix,Angle,给定numpy 2D数组,从给定角度的指定坐标(其中“X”位于)获取最近项(例如“1”)的最佳方法是什么 例如,假设在如下所示的二维数组中,X位于(1,25)处。假设角度为225度,假设0度垂直向右,90度垂直向上。如何获得朝向该矢量方向的“1”的最近坐标 [ 0000000000000000000000000000 0000000000000000000000000X00 0000000000000000000000000000 1110000000000000000000000000 111
[
0000000000000000000000000000
0000000000000000000000000X00
0000000000000000000000000000
1110000000000000000000000000
1111100000000000000000000000
1111110000000000000000000000
1111111000000000000000000000
1111111110000000000000000000
1111111111100000000000000000
]
我假设朝那个方向,你指的是那种光线。在这种情况下,255°没有解决方案,因此我冒昧地将其更改为195° 然后你可以用蛮力来强迫它:
import numpy as np
a = """
0000000000000000000000000000
0000000000000000000000000X00
0000000000000000000000000000
1110000000000000000000000000
1111100000000000000000000000
1111110000000000000000000000
1111111000000000000000000000
1111111110000000000000000000
1111111111100000000000000000
"""
a = np.array([[int(i) for i in row] for row in a.strip().replace('X', '2').split()], dtype=np.uint8)
x = np.argwhere(a==2)[0]
y = np.argwhere(a==1)
d = y-x
phi = 195 # 255 has no solutions
on_ray = np.abs(d@(np.sin(np.radians(-phi-90)), np.cos(np.radians(-phi-90))))<np.sqrt(0.5)
show_ray = np.zeros_like(a)
show_ray[tuple(y[on_ray].T)] = 1
print(show_ray)
ymin=y[on_ray][np.argmin(np.einsum('ij,ij->i', d[on_ray], d[on_ray]))]
print(ymin)
是的,我只是选择了一个任意的角度,以为会击中那些。试图理解你的解决方案。我知道“d”是什么,但我想了解它是如何决定on_射线的。我猜这是用来确定每个1的角度的?还有,"d"做什么??谢谢
@
是矩阵乘法。这里,它用于对标量积进行大量求值。正如你们所看到的,我们并没有和射线方向相乘,而是把射线方向i旋转了90°。这就是所谓的法向量。法向量的美妙之处在于,标量prdouct提供了与光线的距离(上面或下面有符号)。因此,我们选择光线sqrt(1/2)范围内的所有1
s。我不得不承认,sqrt(1/2)有点马虎。我明白了。谢谢你的信息。从你的回答中,我可以使用单位向量,单位向量=np.cos(np.radians(-phi-90)),-np.sin(np.radians(-phi-90)),然后从x坐标(起点)开始,用单位向量不断增加起始坐标(和舍入/int),并检查该坐标中的矩阵值是否为“1”。直到找到“1”或超出范围为止。基本上一直沿着单位向量的直线向下移动,直到你碰到一个“1”或它的边界。你觉得那样会更快吗?由于您的解决方案计算所有1,并且如果阵列相当大,那么它可能会比较慢。我想这取决于你的电网有多大。问题是Python循环比矢量化操作慢得多,因此需要节省大量工作才能更快地使用循环。您必须尝试使用timeit.timeit
进行比较。最有希望的策略可能是以矢量化的方式计算射线上或射线附近网格点的坐标,可能使用np.linspace
和dtype=int
,然后检查这些坐标处的坐标。确实,python循环要慢得多。再次感谢你提供的信息。
# [[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# [1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]]
# [6 6]