1

I need to make an ellipsoid out of voxels in python, but I still do not completely understand how to define the boundaries of this figure. I have seen some examples where they use boolean operations to define the voxels but I have not been able to make it work the way I want it to. Any help would be greatly appreciated.

This is what I have been trying out:

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# the angles and radius
u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
radius = 4

# equations for the shell of the ellipsoid
X = 3*radius*np.sin(v)*np.cos(u)
Y = 2*radius*np.sin(v)*np.sin(u)
Z = radius*np.cos(v)


x, y, z = np.indices((10, 10, 10))
voxels = (x <= X) | (y <= Y) | (z <= Z)
ax.voxels(voxels)

plt.show()

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-12-f0d9033151c5> in <module>
     14 
     15 x, y, z = np.indices((10, 10, 10))
---> 16 voxels = (x <= X) | (y <= Y) | (z <= Z)
     17 ax.voxels(voxels)
     18 

ValueError: operands could not be broadcast together with shapes (10,10,10) (100,)

1 Answers1

1

You can filter to points within an ellipsoid on an evenly spaced grid using meshgrid and then applying a boolean mask to the points:

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# grid points in spherical coord:
N = 40
R = 1
x,y,z = np.meshgrid(np.linspace(-R, R, N), np.linspace(-R, R, N),np.linspace(-R, R, N))

# filter points outside ellipsoid interior:
mask = (2*x)**2 + (3*y)**2 + z**2 <= R**2
x = x[mask]
y = y[mask]
z = z[mask]


# convert to cartesian for plotting:

ax.scatter3D(x,y,z)
ax.set_xlim(-1.2,1.2)
ax.set_ylim(-1.2,1.2)
ax.set_zlim(-1.2,1.2)
plt.show()

enter image description here

anon01
  • 10,618
  • 8
  • 35
  • 58
  • If you must plot many points (more than ~500), I would recommend checking out `plotly` as it will be much faster. You can see example code here: https://stackoverflow.com/questions/43187484/matplotlib-slow-3d-scatter-rotation/46457858#46457858 – anon01 Oct 15 '20 at 06:13
  • That is not exactly what I need, I need to make the ellipsoid out of voxels, with voxels on the inside as well. – An Hernández Oct 15 '20 at 14:20
  • do you need this plotted, or just want to define those points? – anon01 Oct 15 '20 at 17:40