如何在没有循环的情况下对数组或张量的角度索引进行操作
How to operate on angle indexes of an Array or Tensor without loops
是否有一种算法可以分配、获取索引或对数组进行操作,从而提供一批角度、原点和值,而无需任何循环、不可微性或性能繁重的计算。
找到一个对 3 维角度进行运算的函数 space [W,H,D,C] 更受欢迎。
下面基本上就是你想要的。请注意,它确实包含一个循环,但不是应该避免的类型。该循环只有 4 次迭代,因此这不是性能问题。 numpy/pytorch 应该避免的是遍历大型数组中的所有条目。
img = torch.zeros([9,9,3])
points = np.stack(np.indices([9,9])).reshape(2,-1)
blue = (0,0,1)
red = (1,0,0)
orange = (1,1/2,0)
green = (0,1,0)
angles = [0,45,225,280]
origions = np.array([(4,4),(4,4),(4,4),(4,4)])
colors = [blue, red, orange, green]
def angle_from(p):
return np.rad2deg(np.arctan2(*(points-p.reshape(2,1)))) % 360
def set_color(angle, origin, color):
angles = angle_from(np.array(origin))
mask = angles - angle == 0
img.view(-1,3)[np.where(mask),:] = torch.tensor(color, dtype=torch.float)
for angle, origin, color in zip(angles,origions,colors):
set_color(angle, origin, color)
rad = np.deg2rad(angle)
x = (origin[0],origin[1]+10*np.cos(rad))
y = (origin[0],origin[1]+10*np.sin(rad))
plt.plot(x, y, c='white')
angle = 280
rad = np.deg2rad(angle)
plt.scatter(*points)
plt.imshow(img, origin='lower')
除了你在绿色区域作弊外,看起来几乎是完美的。正如您在图片中看到的那样,绿色方块的中心实际上并不在您声称的角度的光线上。我用你选择的原点和角度绘制了中心和光线,这样人们就可以更容易地看到它。我怀疑情况经常如此,并且您想要一种选择绿点的方法。我的方法是选择两条光线而不是一条光线,并显示中心位于光线之间的正方形。
def set_color_between_rays(angles, origins, color):
angles1 = angle_from(np.array(origins[0]))
angles2 = angle_from(np.array(origins[1]))
mask = ((angles1 - angles[0]) >= 0) & ((angles2 - angles[1]) <= 0)
img.view(-1,3)[np.where(mask),:] = torch.tensor(color, dtype=torch.float)
angle = 295
rad = np.deg2rad(angle)
origins = np.array([[3.6,3.6],[4.3,4.3]])
plt.plot((origins[0,0],origins[0,0]+10*np.cos(rad)),(origins[0,1],origins[0,1]+10*np.sin(rad)),c='green')
plt.plot((origins[1,0],origins[1,0]+10*np.cos(rad)),(origins[1,1],origins[1,1]+10*np.sin(rad)),c='green')
set_color_between_rays([angle, angle], origins, green)
plt.scatter(*points)
plt.imshow(img, origin='lower')
找到一个对 3 维角度进行运算的函数 space [W,H,D,C] 更受欢迎。
下面基本上就是你想要的。请注意,它确实包含一个循环,但不是应该避免的类型。该循环只有 4 次迭代,因此这不是性能问题。 numpy/pytorch 应该避免的是遍历大型数组中的所有条目。
img = torch.zeros([9,9,3])
points = np.stack(np.indices([9,9])).reshape(2,-1)
blue = (0,0,1)
red = (1,0,0)
orange = (1,1/2,0)
green = (0,1,0)
angles = [0,45,225,280]
origions = np.array([(4,4),(4,4),(4,4),(4,4)])
colors = [blue, red, orange, green]
def angle_from(p):
return np.rad2deg(np.arctan2(*(points-p.reshape(2,1)))) % 360
def set_color(angle, origin, color):
angles = angle_from(np.array(origin))
mask = angles - angle == 0
img.view(-1,3)[np.where(mask),:] = torch.tensor(color, dtype=torch.float)
for angle, origin, color in zip(angles,origions,colors):
set_color(angle, origin, color)
rad = np.deg2rad(angle)
x = (origin[0],origin[1]+10*np.cos(rad))
y = (origin[0],origin[1]+10*np.sin(rad))
plt.plot(x, y, c='white')
angle = 280
rad = np.deg2rad(angle)
plt.scatter(*points)
plt.imshow(img, origin='lower')
除了你在绿色区域作弊外,看起来几乎是完美的。正如您在图片中看到的那样,绿色方块的中心实际上并不在您声称的角度的光线上。我用你选择的原点和角度绘制了中心和光线,这样人们就可以更容易地看到它。我怀疑情况经常如此,并且您想要一种选择绿点的方法。我的方法是选择两条光线而不是一条光线,并显示中心位于光线之间的正方形。
def set_color_between_rays(angles, origins, color):
angles1 = angle_from(np.array(origins[0]))
angles2 = angle_from(np.array(origins[1]))
mask = ((angles1 - angles[0]) >= 0) & ((angles2 - angles[1]) <= 0)
img.view(-1,3)[np.where(mask),:] = torch.tensor(color, dtype=torch.float)
angle = 295
rad = np.deg2rad(angle)
origins = np.array([[3.6,3.6],[4.3,4.3]])
plt.plot((origins[0,0],origins[0,0]+10*np.cos(rad)),(origins[0,1],origins[0,1]+10*np.sin(rad)),c='green')
plt.plot((origins[1,0],origins[1,0]+10*np.cos(rad)),(origins[1,1],origins[1,1]+10*np.sin(rad)),c='green')
set_color_between_rays([angle, angle], origins, green)
plt.scatter(*points)
plt.imshow(img, origin='lower')