У меня есть трехмерный массив вокселей, т. Е. Где индексы каждой точки соответствуют ее положению в трехмерном пространстве.
Есть ряд вычислений, которые я хотел бы выполнить, зная, удовлетворяют ли точки удовлетворениюразличные геометрические условия.Это означает преобразование индексов в векторы путем умножения на базис, а затем вычисления точечных и перекрестных произведений, норм и т. Д. Я ищу достаточно быстрый способ сделать это, поскольку мои усилия пока кажутся очень медленными.
Если у меня есть произвольная основа a , b , c :
basis = np.array([[a1, a2, a3],
[b1, b2, b3],
[c1, c2, c3]])
, где a1, a2, a3 - x, компоненты y и z a , а также для b и c .Я могу вычислить декартову координату p = (x, y, z) каждого вокселя следующим образом:
for i in range(vox.shape[0]):
for j in range(vox.shape[1]):
for k in range(vox.shape[2]):
p = np.dot(basis, np.array([i, j, k]))
, где «vox» - трехмерный массив вокселей.Если, например, я хочу вычислить скалярное произведение каждого из этих векторов с одним другим (декартовым) вектором (например, q = np.array([qx, qy, qz])
) и сохранить этот индекс, если результат удовлетворяет заданному условию (здесь больше 0,0), яможет сделать что-то вроде этого (в том же цикле, как указано выше):
if np.dot(p, q) > 0.0:
desired_vox_indices.append([i, j, k])
Проблема в том, что это очень медленно.Могу ли я сделать это более питоническим способом или с помощью более обалденных инструментов?Я понимаю, что на этом этапе я даже не обращаюсь к значениям массива vox.
РЕДАКТИРОВАТЬ: попытка перекрестного произведения на основе ответа Дивакара
# Get q_x (matrix multiplication version of cross product)
q_x = np.array([[0.0, -q[2], q[1]],
[q[2], 0.0, -q[0]],
[-q[1], q[0], 0.0]])
# transpose (as per cross product definition) and matrix multiply with basis
u = np.matmul(q_x.T, basis)
# Get open range arrays
m,n,r = vox.shape
I,J,K = np.ogrid[:m,:n,:r]
# writing everything explicitly, since I am unsure how ogrid objects behave
pxq = np.empty(3)
pxq[0] = u[0,0]*I + u[0,1]*J + u[0,2]*K
pxq[1] = u[1,0]*I + u[1,1]*J + u[1,2]*K
pxq[2] = u[2,0]*I + u[2,1]*J + u[2,2]*K
, который может совпадать спросто:
pxq = np.dot(u, np.array([I, J, K]))
но я не уверен ...