12
$\begingroup$

Is there a possibility in Mathematica to allow for manual rotation of 3D graphics when (auto)playing either using Manipulate or ListAnimate? (When one plays a sequence of 3D graphics using ListAnimate it is not possible to rotate manually the graph as when it is static.)

$\endgroup$
11
  • $\begingroup$ I hope it is not possible to do what you ask. I think any attempt to allow what you ask for would produce nightmarish thread conflict between the thread updating the graphics under animation control and the thread updating the graphics under mouse control. I would expect the 2nd of these two threads to be blocked while animation is running. $\endgroup$
    – m_goldberg
    Commented Oct 23, 2015 at 15:05
  • 1
    $\begingroup$ @m_goldberg Instead of blocking, it might be done with time division multiplex technics? $\endgroup$
    – Silvia
    Commented Oct 23, 2015 at 16:13
  • $\begingroup$ @Silvia. Sound good but do you think Mathematica's front-end supports that? $\endgroup$
    – m_goldberg
    Commented Oct 23, 2015 at 16:20
  • $\begingroup$ @m_goldberg I doubt so. But maybe we can simulate one with nested Dynamics? $\endgroup$
    – Silvia
    Commented Oct 23, 2015 at 16:55
  • 1
    $\begingroup$ @m_goldberg I made one along that way and the performance is indeed bad -- but not unacceptable IMO. Will try a 3D graphics case before shape an answer. $\endgroup$
    – Silvia
    Commented Oct 23, 2015 at 17:00

1 Answer 1

12
$\begingroup$

As there seem no easy way to hack ListAnimate or Manipulate, we'll try to construct a custom "animator", using the method I mentioned in an earlier post with some generalization.

First we generate all frames of the animation:

frameLst =
        Module[{range},
            range = Range[0, 2, .1];
            Plot3D[
                   Im[ArcSin[(.5 Abs[# - 1])^3 (x + I y)^4 Exp[2 # π I]]],
                   {x, -2, 2}, {y, -2, 2},
                   (* quality too high will crash the Dynamic system: *)
                   PlotPoints -> 10, MaxRecursion -> 1,
                   ExclusionsStyle -> {None, Red},
                   PlotRange -> {{-2, 2}, {-2, 2}, 4 {-1, 1}}, 
                   SphericalRegion -> True
            ] & /@ range
        ];

Then we make it move automatically using a Clock:

With[{n = Length@frameLst, opts = glst[[1, 2]]},
    DynamicModule[
        { k,
          frameDataLst = Cases[frameLst, _GraphicsComplex, ∞]
        },
        DynamicWrapper[
           Graphics3D[
              Dynamic[frameDataLst[[k]]],
              opts
           ],
           k = Clock[{1, n, 1}, 3]
        ]
    ]
]

rotatable auto-animation

The key point of the trick is keeping a persistent Graphics3D object across frames. So instead of writing Dynamic[Graphics3D[...]], we should use Graphics3D[{...,Dynamic[...],...}, options] to prevent the Graphics3DBox being destroyed at each frame, which will leave it no time to respond to the dragging operations from mouse.

$\endgroup$
2
  • $\begingroup$ Excellent work! $\endgroup$
    – m_goldberg
    Commented Oct 23, 2015 at 21:56
  • $\begingroup$ @m_goldberg Thanks :) $\endgroup$
    – Silvia
    Commented Oct 24, 2015 at 6:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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