Assign value to points in a 3D array that are inside an ellipsoid
mask = x*x + y*y <= r*r
gives you a circle, because that's the equation for a circle.
By the same rationale,
mask = x*x + y*y + z*z <= r*r
should give you a sphere, and
mask = x*x/(a*a) + y*y/(b*b) + z*z/(c*c) <= r*r
should give you an ellipsoid with principal axes of half-length a
, b
, and c
.
Of course, you'll have to create a z
array in a way akin to that in which you create your x
and y
arrays.
For me the easiest way would be to use the coordinate equations for a sphere and work from there.
x = a * cos(u) * cos(v)y = b * cos(u) * sin(v)z = c * sin(u)
You can construct these coordinates with np.meshgrid
and then plot.
a, b, c = 4, 8, 6space = np.linspace(0, 2 * np.pi, 50)u, v = np.meshgrid(space)x = a * np.cos(u) * np.cos(v)y = b * np.cos(u) * np.sin(v)z = c * np.sin(u)fig = plt.figure()ax = fig.add_subplot(111, projection='3d')ax.scatter(x, y, z)fig.show()
UpdateTo get the interior coordinates of the sphere you would use the mask akin to your example, but with the ellipsoid implicit equation. x^2/a^2 + y^2/b^2 + z^2/c^2 = 1
a, b, c = 4, 8, 6xs, ys, zs = np.mgrid[-a + 1:a + 1:15j, -b + 1:b + 1:15j, -c + 1:c + 1:15j]mask = xs**2/(a**2) + ys**2/(b**2) + zs**2/(c**2) <= 1xs[~mask] = 0ys[~mask] = 0zs[~mask] = 0fig = plt.figure()ax = fig.add_subplot(111, projection='3d')ax.scatter(xs, ys, zs)fig.show()
Your first equations hints axis aligned ellipsoid centered at (0,0,0)
for such is the easiest way I know of to use scaling to/from sphere. so let:
[x ,y ,z ] - ellipsoid (rx,ry,rz)[x',y',z'] - sphere (r)
So the transforms are:
// sphere -> ellipsoidx = x' * rx/ry = y' * ry/rz = z' * rz/r// sphere <- ellipsoidx' = x * r/rxy' = y * r/ryz' = z * r/rz
The (rx,ry,rz)
are the radiuses of ellipsoid (in your case rx=ry
) and r
is any nonzero radius of the sphere (for example r=1.0
)
So the test for inside ellipsoid boils down to this:
// scale constantssx = 1/rxsy = 1/rysz = 1/rz// condition for inside ellipsoidx*x*sx*sx + y*y*sy*sy + z*z*sz*sz <= 1.0