With Graphics3D[Sphere[{0, 0, 0}, 1]], I can render a uniform 3D sphere, but how can I render an ellipsoid? I would need to specify the rotation of the ellipsoid and the length of the main axes. The method should be reasonably fast to display around 100 of them at once.
- 124,525
- 11
- 401
- 574
- 1,505
- 1
- 10
- 17
5 Answers
You can modify this if you need to specify the rotation in different ways, etc. As Simon Woods has suggested, probably the best way is to use GeometricTransformation.
ellipsoid[a_, b_, center_?VectorQ, rotation_, around_?VectorQ] := Fold[
GeometricTransformation,
Sphere[],
{ScalingTransform[{a, b, b}],
RotationTransform[rotation, around],
TranslationTransform[center]}]
ellipsoid @@@ Table[{x, x, 10 {x, x, x}, x, {x, x, x}} /. x :> RandomReal[]
, {111}] // Graphics3D // AbsoluteTiming
{0.347020,
- 124,525
- 11
- 401
- 574
- 136,707
- 13
- 279
- 740
-
2I had a slight wtf moment at all the x's - nice way to generate the data. – Simon Woods Oct 29 '13 at 21:15
-
-
1You can compose the transforms with
Dotinstead ofFold:TranslationTransform[center].RotationTransform[rotation, around].ScalingTransform[{a, b, b}]. Very nice, +1! – Michael E2 Oct 30 '13 at 00:15 -
@MichaelE2 Thanks ;) and yes
Dotlooks clear and is about 3% faster thanFoldon my pc. – Kuba Oct 30 '13 at 03:17 -
Dot[]works, butComposition[]is the documented way to compose geometric transforms:GeometricTransformation[Sphere[], Composition[TranslationTransform[center], RotationTransform[rotation, around], ScalingTransform[{a, b, b}]]]– J. M.'s missing motivation Jul 21 '16 at 01:37
Using Sphere with Scale and Rotate works too:
Graphics3D[Rotate[Scale[Sphere[], {5, 4, 2}, {0, 0, 0}], 60 Degree, {1, 2, 1}]]

The first triple is the scaling in the x,y,and z coordinates, the second triple is the translation, and the third triple is the axis about which to rotate. To generate a number of random ellipses:
x := RandomReal[];
Show[Table[Graphics3D[Rotate[Scale[Sphere[], {x, x, x}, {x i/6, x i/6, x i/6}],
x, {x, x, x}], Boxed -> False], {i, 25}]]

- 68,936
- 4
- 101
- 191
An alternative approach that generates explicit primitives instead of transformed ones uses the NURBS representation of a sphere, with all the appropriate transformations done to its control points to generate the ellipsoid:
myEllipsoid[dims : {_?Positive, _?Positive, _?Positive} : {1, 1, 1},
center : (_?VectorQ) : {0, 0, 0},
rot : {_, _?VectorQ} : {0, {1, 0, 0}}] := Block[{ctrlpts},
ctrlpts = Composition[TranslationTransform[center],
RotationTransform[Sequence @@ rot],
ScalingTransform[dims]] /@
Outer[Append[#2 #1[[1]], #1[[2]]] &,
{{0, -1}, {1, -1}, {1, 1}, {0, 1}},
{{1, 0}, {1, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {1, -1}, {1, 0}}, 1];
BSplineSurface[ctrlpts, SplineClosed -> True, SplineDegree -> 2,
SplineKnots -> {{0, 0, 0, 1/2, 1, 1, 1},
{0, 0, 0, 1/4, 1/2, 1/2, 3/4, 1, 1, 1}},
SplineWeights -> Outer[Times, {1, 1/2, 1/2, 1},
{1, 1/2, 1/2, 1, 1/2, 1/2, 1}]]]
Here's an example:
randomEllipsoid := myEllipsoid[RandomReal[1, 3], RandomReal[{-2, 2}, 3],
{RandomReal[{-π, π}],
Normalize[RandomVariate[NormalDistribution[], 3]]}]
BlockRandom[SeedRandom[42, Method -> "Legacy"];
Graphics3D[Table[{ColorData[61, RandomInteger[{1, 9}]], randomEllipsoid},
{50}], Boxed -> False, Lighting -> "Neutral"]]

- 124,525
- 11
- 401
- 574
Starting from version 10 there is documented Ellipsoid which is reasonably fast
Graphics3D[Ellipsoid @@@ RandomReal[1, {100, 2, 3}]]
For an arbitrary orientation you specify the weight matrix Σ as a second argument
randomEllipsoid[] := Module[{ℛ, \[ScriptCapitalS], p},
ℛ = First@QRDecomposition@RandomReal[NormalDistribution[], {3, 3}];
\[ScriptCapitalS] = DiagonalMatrix@RandomReal[1, 3];
p = RandomReal[10, 3];
Ellipsoid[p, ℛ\[Transpose].\[ScriptCapitalS].ℛ]]
Graphics3D[Table[randomEllipsoid[], {100}]]
Here ℛ and \[ScriptCapitalS] are random rotation matrix and random scale matrix respectively.
- 43,673
- 5
- 108
- 212
-
Its only limitation is that it can only generate axis-aligned ellipsoids;
Rotate[]is still needed for the arbitrary orientation. – J. M.'s missing motivation Nov 17 '15 at 14:51 -
@J.M. What about
Graphics3D[Ellipsoid[{0, 0, 0}, {{5, 2, 3}, {2, 3, 2}, {3, 2, 5}}]]? :) – ybeltukov Nov 17 '15 at 14:54 -
Ah, missed that. :D One still has to recognize the SVD for this. Anyway:
First @ QRDecomposition @ RandomReal[NormalDistribution[], {3, 3}]is more compactly done asOrthogonalize[RandomReal[NormalDistribution[], {3, 3}]]. – J. M.'s missing motivation Nov 17 '15 at 15:09 -
@J.M. Sure, it is just a habit because it is faster for big matrices. – ybeltukov Nov 17 '15 at 15:31
-
-
@J.M. I just find that the timings are the same with
Method -> "Householder"inOrthogonalize. – ybeltukov Nov 17 '15 at 15:38 -
Ah, I think I see now;
Orthogonalize[]is probably not using LAPACK (that is, its implementation of QR decomposition) by default for numerical matrices. (Gram-Schmidt?) – J. M.'s missing motivation Nov 17 '15 at 15:50
Thought I would add after looking at this quite a bit later. The numbers you use to generate the random ellipsoid orientation are not truly random. You are missing a factor of $\pi/2$ in the 4th argument in the table.
When generating the table, use this instead to get truly random ellipsoids:
ellipsoid @@@ Table[{x, x, 10 {x, x, x}, pi/2*x, {x, x, x}} /. x :> RandomReal[]
, {111}] // Graphics3D // AbsoluteTiming
All I added was a factor of $\pi$ in the 4th argument of ellipsoid in the table being generated. This will give you random radian values from $0$ to $\pi/2$.
- 124,525
- 11
- 401
- 574
- 43
- 4



GeometricTransformation– Simon Woods Oct 29 '13 at 16:36Ellipsoidfunction in theMultivariateStatisticspackage that I used here, but it acts cranky at times... – rm -rf Oct 29 '13 at 23:12