When doing presentation with Mathematica, I often want a 3D plot to rotate automatically, so the 3D feeling is stronger. I don't want to drag the mouse every time.
So, I want a general function like
autoRotate["3D graphics here"]
The out put is a rotating version, and I can stop/start the rotation by click a control.
Question: How can I implement this function efficiently so the rotation is as smooth as possible?
Here is my first try: Get viewpoint and compute the rotation matrix;
g = Plot3D[Sin[x y], {x, 0, 3}, {y, 0, 3}];
vc = AbsoluteOptions[g, ViewCenter][[1, 2]];
vp = AbsoluteOptions[g, ViewPoint][[1, 2]];
m = RotationMatrix[3 Degree, {0., 0., 1.}];
newvp = m.(vp - vc);
then manipulate:
Manipulate[If[start, newvp = m.newvp];
Show[g, ViewPoint -> Dynamic[newvp + vc],
SphericalRegion -> True ], {start, {False, True }}]
This seems slow and I lose the ability to zoom/rotate the plot manually.
Second try:
DynamicModule[{},
Show[g, ViewPoint ->
Dynamic[newvp = m.newvp; newvp + vc, UpdateInterval -> 1.],
SphericalRegion -> True ]]
This seems faster, but I can't control the refreshrate. UpdateInterval ->1
seems to lose effect and I also can't zoom/rotate the plot manually.
Update: Based on Rojo's idea and Silvia's comment, here is what I currently use:
autoRotate[gr_Graphics3D, rate_: 7] :=
DynamicModule[{vp, va, vv, vc }, {vp, va, vv, vc} =
gr~AbsoluteOptions~#~OptionValue~# &@{ViewPoint, ViewAngle,
ViewVertical, ViewCenter};
Overlay[{Show[Graphics3D[], ViewPoint -> Dynamic[vp],
ViewAngle -> Dynamic[va], SphericalRegion -> True],
Show[gr, SphericalRegion -> True,
ViewPoint -> Dynamic[RotationMatrix[Clock[2 \[Pi], rate], vv].vp],
ViewAngle -> Dynamic[va], Boxed -> False , Axes -> False]}, All,
1]]
Comments
Post a Comment