I am trying to make an animation of a rotating cube using the following code:
cube = GraphicsComplex[
{{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1}},
Polygon[{{1, 2, 4, 3}, {5, 6, 8, 7}, {1, 2, 6, 5}, {3, 4, 8, 7}, {1, 3, 7, 5}, {2, 4, 8, 6}}]
]
cubes = Table[
Graphics3D[{Rotate[cube, x, {1, 1, 1}, {0, 0, 0}]},
ViewPoint -> {3, 1/2, -2}, ViewVertical -> {1, 1, 1},
Boxed -> False], {x, 0, 2 Pi/3 - Pi/48, Pi/24}]
However, as the cube rotates, the bounding box (which is not drawn because Boxed->False) causes the image of the cube to be shrunk to fit the larger bounding box in the field of view. Is there a way to keep the scale constant and not vary with the varying size of the bounding box?
I've gone through the list of options for Graphics3D, yet none seem to help.
Edit:
Heike's answer works like a charm! For those interested, here is the finished code, used to create the illustration for this answer on math.SE.
cube =
GraphicsComplex[
{{0, 0, 0}, {0, 0, 1}, {0, 1, 0}, {0, 1, 1}, {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1}},
Polygon[{{1, 2, 4, 3}, {5, 6, 8, 7}, {1, 2, 6, 5}, {3, 4, 8, 7}, {1, 3, 7, 5}, {2, 4, 8, 6}}]
];
envelope[t_] := If[t < 1, t, If[t < 2, Sqrt[(2 t - 3)^2 + 3]/2, 3 - t]]
lozenge =
Rotate[
RevolutionPlot3D[{Sqrt[2/3] envelope[t], t/Sqrt[3]}, {t, 0, 3}, MaxRecursion -> 5][[1]],
{{0, 0, 1}, {1, 1, 1}}];
enveloped =
Table[
Graphics3D[{Rotate[cube, x, {1, 1, 1}, {0, 0, 0}], Opacity[1/2], lozenge},
ViewVector -> {3, 1/2, -2}, ViewAngle -> 30 Degree, ViewCenter -> {1/2, 1/2, 1/2},
ViewVertical -> {1, 1, 1}, Boxed -> False, ImageSize -> 300],
{x, 0, 2 Pi/3 - Pi/48, Pi/24}];
Export["enveloped.gif", enveloped, "GraphicsList", "DisplayDurations" -> {.05}]
Answer
The variation in size is due to variation in camera position and viewing angle. Since ViewPoint uses special coordinates which depend on the bounding box it's better to use ViewVector instead (or even ViewMatrix if you can make it work). To keep the viewing angle fixed you should give an explicit value for ViewAngle. To place the object at the right position in the field of view you could use ViewCentre. For the example above you could do something like
cubes = Table[
Graphics3D[{Rotate[cube, x, {1, 1, 1}, {0, 0, 0}]},
ViewVector -> {3, 1/2, -2},
ViewAngle -> 35 Degree,
ViewCenter -> {.5, .5, .5},
ViewVertical -> {1, 1, 1}, Boxed -> False],
{x, 0, 2 Pi/3 - Pi/48, Pi/24}]
Comments
Post a Comment