简体   繁体   English

八分圆分区同样是 3D 中的点云

[英]Octant partition equally a cloud of points in 3D

Is there a better way to do this?有一个更好的方法吗? Not necessarily prettier, although it would be nice.不一定更漂亮,虽然它会很好。

P = [N,3] ‘Cloud of points’

P -= np.sum(P, axis=0) / P.shape[0]

Map = [i for i in range(P.shape[0])]

p_0 = Map[P[:,0] <= 0] 
p_1 = Map[P[:,0] > 0]

p_0_0 = p_0[P[p_0,1] <= 0]
p_0_1 = p_0[P[p_0,1] > 0]
p_1_0 = p_1[P[p_1,1] <= 0]
p_1_1 = p_1[P[p_1,1] > 0]

p_0_0_0 = p_0_0[P[p_0_0,2] <= 0]
p_0_0_1 = p_0_0[P[p_0_0,2] > 0]
p_0_1_0 = p_0_1[P[p_0_1,2] <= 0]
p_0_1_1 = p_0_1[P[p_0_1,2] > 0]
p_1_0_0 = p_1_0[P[p_1_0,2] <= 0]
p_1_0_1 = p_1_0[P[p_1_0,2] > 0]
p_1_1_0 = p_1_1[P[p_1_1,2] <= 0]
p_1_1_1 = p_1_1[P[p_1_1,2] > 0]

Or in other words, is there a way to compound conditions like,或者换句话说,有没有办法复合条件,例如,

Oct_0_0_0 = Map[P[:,0] <= 0 and P[:,1] <= 0 and P[:,2] <= 0]

I'm assuming a loop won't be better than this… not sure.我假设循环不会比这更好……不确定。

Thanks in advance.提前致谢。

Instead of repeatedly slicing and keeping lists of the indices, I'd instead recommend creating a single that maps the index of the point to the octant it belongs to.我建议不要重复切片和保留索引列表,而是建议创建一个将点的索引映射到它所属的八分圆的单个。 I'd argue that this is a more natural way of doing it in numpy.我认为这是在 numpy 中更自然的方式。 So for instance with因此,例如

octants = (P>0) @ 2**np.arange(P.shape[2])

the n -th entry of octants is the index (here in the range 0,1,2,...,7 ) of the octant that P belongs to.八分圆的第n个条目是P所属的octants的索引(此处在0,1,2,...,7范围内)。 This works by checking each coordinate whether it is positive or not.这通过检查每个坐标是否为正来工作。 This gives three boolean values per point which we can interpret as the binary expansion of that index.这为每个点提供了三个 boolean 值,我们可以将其解释为该索引的二进制扩展。 (In fact, the line above works for indexing the 2^d -ants in any number of dimensions d .) (事实上,上面的行适用于在任意数量的维度d中索引2^d蚂蚁。)

To demonstrate this solution, following snippet makes a point cloud and colours them according to their quadrant:为了演示这个解决方案,下面的代码片段制作了一个点云并根据它们的象限为它们着色:

import numpy as np
P = np.random.rand(10000, 3)*2-1
quadrants = (P > 0) @ 2**np.arange(3)
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.scatter(*P.T, c=quadrants, cmap='jet')
plt.show()

If you still need to extract an array of the indices of a specific quadrant, say quadrant 0, 1, 1 this corresponds to finding the corresponding decimal number, which is 0*2^0 + 1*2^1 + 1*2^2 = 6 , which you can do with eg如果您仍然需要提取特定象限的索引数组,例如象限 0、1、1 0, 1, 1这对应于找到相应的十进制数,即0*2^0 + 1*2^1 + 1*2^2 = 6 ,您可以使用例如

p_0_1_1 = np.where(quadrants == np.array([0,1,1]) @ 2**np.arange(3))

按象限着色的点

All in all, I'm going with an even messier version,总而言之,我会选择一个更混乱的版本,

p_x = P[:,0] < 0

p_0 = np.nonzero(p_x)[0]
p_1 = np.nonzero(~p_x)[0]

p_0_y = P[p_0,1] < 0
p_1_y = P[p_1,1] < 0

p_0_0 = p_0[p_0_y]
p_0_1 = p_0[~p_0_y]
p_1_0 = p_1[p_1_y]
p_1_1 = p_1[~p_1_y]

p_0_0_z = P[p_0_0,2] < 0
p_0_1_z = P[p_0_1,2] < 0
p_1_0_z = P[p_1_0,2] < 0
p_1_1_z = P[p_1_1,2] < 0

p_0_0_0 = p_0_0[p_0_0_z]
p_0_0_1 = p_0_0[~p_0_0_z]
p_0_1_0 = p_0_1[p_0_1_z]
p_0_1_1 = p_0_1[~p_0_1_z]
p_1_0_0 = p_1_0[p_1_0_z]
p_1_0_1 = p_1_0[~p_1_0_z]
p_1_1_0 = p_1_1[p_1_1_z]
p_1_1_1 = p_1_1[~p_1_1_z]

I have a religious belief (I mean based on thin air) that a comparison is fundamentally cheaper than an arithmetic operation.我有一个宗教信仰(我的意思是凭空而来),比较基本上比算术运算便宜。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM