4
$\begingroup$

3D graphics can be easily rotated interactively by clicking and dragging with the mouse.

Is there a simple way to achieve the same for animated 3D graphics? I would like to rotate them interactively (in real time) while the animation is running.


Here's an example animation, mostly taken from the documentation.

L = 4;
sol = NDSolveValue[{D[u[t, x, y], t, t] == 
     D[u[t, x, y], x, x] + D[u[t, x, y], y, y] + Sin[u[t, x, y]], 
    u[t, -L, y] == u[t, L, y], u[t, x, -L] == u[t, x, L], 
    u[0, x, y] == Exp[-(x^2 + y^2)], 
    Derivative[1, 0, 0][u][0, x, y] == 0}, 
   u, {t, 0, L/2}, {x, -L, L}, {y, -L, L}];

Animate[
 Plot3D[sol[t, x, y], {x, -L, L}, {y, -L, L}, PlotRange -> {0, 1}, 
  PlotPoints -> 20, MaxRecursion -> 0],
 {t, 0, L/2}
 ]

When the animation is stopped, I can rotate the graphics. Then if the animation is started again, the rotation is kept.

However, I cannot rotate while the animation is running. Is there a relatively easy way to enable this?

Note: My actual application has an animated plot on the surface of a sphere. The ability to rotate would be very useful.

$\endgroup$
  • $\begingroup$ Do you want to be able to rotate the plot in real time or pre-determine the angle? If the latter you can add the animation parameter in the view point i.e. in your code something like "ViewPoint -> {Cos[π/2 t/L], Sin[π/2 t/L], 1}" $\endgroup$ – gpap Sep 18 '18 at 11:46
  • $\begingroup$ @gpap Rotate in real time by dragging with the mouse. I would like to be able to rotate it interactively the same way as I can rotate a non-animated Graphics3D. $\endgroup$ – Szabolcs Sep 18 '18 at 11:49
  • $\begingroup$ @gpap One idea is to have two copies of the graphics, one animated and one not animated. Connect the two by wrapping their ViewPoint and ViewVertical in Dynamic. Then rotate the non-animated one to control the rotation of the other. Not ideal, but should be usable. $\endgroup$ – Szabolcs Sep 18 '18 at 11:51
  • $\begingroup$ Not sure what machine you are on, Animate allows SynchronousUpdating->True though undocumented. It seems to be doing what you want but it's really slow and unresponsive if plot points are more than 10 on my (decent) macbook. Also, when the refresh rate is changed it seems to not work any more :\ $\endgroup$ – gpap Sep 19 '18 at 8:37
5
$\begingroup$

One possible solution is to make a separate trackball control.

{vp, vv} = {ViewPoint, ViewVertical} /. Options[Graphics3D];

Graphics3D[{Cuboid[]}, Boxed -> False, SphericalRegion -> True, 
 RotationAction -> "Clip", 
 Prolog -> {GrayLevel[.8], Disk[Scaled[{1/2, 1/2}], Scaled[1/2]]}, 
 AspectRatio -> 1, ImageSize -> Small, PlotLabel -> "Trackball",
 ViewPoint -> Dynamic[vp], ViewVertical -> Dynamic[vv]
 ]

Mathematica graphics

Then add

ViewPoint -> Dynamic[vp], ViewVertical -> Dynamic[vv]

to the animated graphics that we want to control.

Rotate the trackball and the other Graphics3D will rotate with it.

This is not nearly as good as direct rotation, and does not easily generalize to multiple rotatable graphics.

$\endgroup$
3
$\begingroup$

Here's another approach. There could be a problem in case plot's options change during animation, PlotRange/Ticks etc, currently only initial ones are preserved. Will try to come up with something more general later.

DynamicModule[{viewPoint, viewVertical, plot}
 ,
 plot[t_] := 
  Plot3D[sol[t, x, y], {x, -L, L}, {y, -L, L}, PlotRange -> {0, 1}, 
   PlotPoints -> 20, MaxRecursion -> 0];
 Module[{opts},

  {viewPoint, viewVertical} = {ViewPoint, ViewVertical} /. 
    Options[Plot3D];
  With[{
    rest = Sequence @@ Last[plot[0]]
    },
   Animate[
    Graphics3D[Dynamic@First@plot[t] 
     , ViewPoint -> Dynamic[viewPoint]
     , ViewVertical -> Dynamic@viewVertical
     , SphericalRegion -> True
     , rest
     ], {t, 0, L/2
     }]
   ]
  ]
 ]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.