I have a 3D numpy array of float values in Python. I need to retrieve all the elements in a sphere of radius r starting from a center point P(x, y, z). Then, I want to apply to the sphere points a function that updates their values and needs the distance to the center point to do this. I do these steps a lot of times and for large radius values, so I would like to have a solution that is as efficient as possible.
My current solution checks only the points in the bounding box of the sphere, as indicated here: Using a QuadTree to get all points within a bounding circle. A sketch of the code looks like this:
# P(x, y, z): center of the sphere
for k1 in range(x - r, x + r + 1):
for k2 in range(y - r, y + r + 1):
for k3 in range(z - r, z + r + 1):
# Sphere center - current point distance
dist = np.sum((np.array([k1, k2, k3]) - np.array([x, y, z])) ** 2)
if (dist <= r * r):
# computeUpdatedValue(distance, radius): function that computes the new value of the matrix in the current point
newValue = computeUpdatedValue(dist, r)
# Update the matrix
mat[k1, k2, k3] = newValue
However, I thought that applying a mask to retrive the points and, then, update them based on distance in a vectorized manner is more efficient. I have seen how to apply a circular kernel (How to apply a disc shaped mask to a numpy array?), but I do no know how to efficiently apply the function (depending on the indices) on each of the mask's elements.