我不知道如何全面地解释我的问题。所以我会告诉你一个例子......
我有这个数组指示每个四边形或三角形的顶点索引:
>>> faces
array([[0, 1, 2, 3],
[4, 7, 6, 5],
[0, 4, 1, 0],
[1, 5, 6, 2],
[2, 6, 7, 3],
[4, 0, 3, 7],
[1, 4, 5, 0]])
三角形是以0
我想进行这样的转换:
>>> faces
array([[0, 1, 2, 3], #->[[0, 1, 2], [0, 2, 3],
[4, 7, 6, 5], #-> [4, 7, 6], [4, 6, 5],
[0, 4, 1, 0], #-> [0, 4, 1],
[1, 5, 6, 2], #-> [1, 5, 6], [1, 6, 2],
[2, 6, 7, 3], #-> [2, 6, 7], [2, 7, 3],
[4, 0, 3, 7], #-> [4, 0, 3], [4, 3, 7],
[1, 4, 5, 0]]) #-> [1, 4, 5]]
那么我怎样才能有效地进行这种转变?
我做了一个以不同方式解决它的功能。将四边形获得的tirangles放在数组的末尾。
def v_raw_to_tris(tessfaces):
len_tessfaces = len(tessfaces)
quad_indices = tessfaces[:, 3].nonzero()[0]
t3 = np.empty(((len_tessfaces + len(quad_indices)), 3), 'i4')
t3[:len_tessfaces] = tessfaces[:, :3]
t3[len_tessfaces:] = tessfaces[quad_indices][:, (0, 2, 3)]
return t3
但我不希望生成的三角形位于数组的末尾。并且在原始四边形前面是的
答案 0 :(得分:1)
我们可以复制每一行,每行一次性移动为两行,并在末尾掩盖三角形。实现看起来像这样 -
def transform1(a):
idx = np.flatnonzero(a[:,-1] == 0)
out0 = np.empty((a.shape[0],2,3),dtype=a.dtype)
out0[:,0,1:] = a[:,1:-1]
out0[:,1,1:] = a[:,2:]
out0[...,0] = a[:,0,None]
out0.shape = (-1,3)
mask = np.ones(out0.shape[0],dtype=bool)
mask[idx*2+1] = 0
return out0[mask]
示例运行 -
In [94]: a
Out[94]:
array([[0, 1, 2, 3],
[4, 7, 6, 5],
[0, 4, 1, 0],
[1, 5, 6, 2],
[2, 6, 7, 3],
[4, 0, 3, 7],
[1, 4, 5, 0]])
In [95]: transform1(a)
Out[95]:
array([[0, 1, 2],
[0, 2, 3],
[4, 7, 6],
[4, 6, 5],
[0, 4, 1],
[1, 5, 6],
[1, 6, 2],
[2, 6, 7],
[2, 7, 3],
[4, 0, 3],
[4, 3, 7],
[1, 4, 5]])
可能的改进
我们可以引入np.lib.stride_tricks.as_strided
来将out0[:,0,1:]
和out0[:,1,1:]
的两个步骤分配替换为一个,并希望能够改进它,就像这样 -
from numpy.lib.stride_tricks import as_strided
def strided_axis1(a, L):
s0,s1 = a.strides
m,n = a.shape
nL = n-L+1
return as_strided(a, (m,nL,L),(s0,s1,s1))
def transform2(a):
idx = np.flatnonzero(a[:,-1] == 0)
out0 = np.empty((a.shape[0],2,3),dtype=a.dtype)
out0[...,1:] = strided_axis1(a[:,1:], 2)
out0[...,0] = a[:,0,None]
out0.shape = (-1,3)
mask = np.ones(out0.shape[0],dtype=bool)
mask[idx*2+1] = 0
return out0[mask]
答案 1 :(得分:0)
这适用于相当紧凑的代码。首先,我们将所有四边形分成三角形,然后,我们从那些已经是三角形的四边形中删除所有第二个元素。拆分后删除可使算法简单。
import numpy as np
a = np.array([[0, 1, 2, 3],
[4, 7, 6, 5],
[0, 4, 1, 0],
[1, 5, 6, 2],
[2, 6, 7, 3],
[4, 0, 3, 7],
[1, 4, 5, 0]])
b = np.empty((a.shape[0], 2, 3))
b[:,0,:] = a[:,(0,1,2)]
b[:,1,:] = a[:,(0,2,3)]
b.shape = (-1, 3)
idx_to_delete = 2*np.flatnonzero(a[:,-1] == 0)+1
b = np.delete(b, idx_to_delete, axis=0)
输出结果为:
In [4]: print(b)
[[ 0. 1. 2.]
[ 0. 2. 3.]
[ 4. 7. 6.]
[ 4. 6. 5.]
[ 0. 4. 1.]
[ 1. 5. 6.]
[ 1. 6. 2.]
[ 2. 6. 7.]
[ 2. 7. 3.]
[ 4. 0. 3.]
[ 4. 3. 7.]
[ 1. 4. 5.]]