Conveniently rotate animated 3D graphics

4

2

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.

Szabolcs

Posted 2018-09-18T11:34:50.470

Reputation: 213 047

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}" – gpap – 2018-09-18T11:46:05.257

@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. – Szabolcs – 2018-09-18T11:49:21.523

@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. – Szabolcs – 2018-09-18T11:51:58.720

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 :\ – gpap – 2018-09-19T08:37:46.330

Answers

6

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.

Szabolcs

Posted 2018-09-18T11:34:50.470

Reputation: 213 047

3

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
     }]
   ]
  ]
 ]

Kuba

Posted 2018-09-18T11:34:50.470

Reputation: 129 207