Message Boards Message Boards

0
|
6129 Views
|
6 Replies
|
3 Total Likes
View groups...
Share
Share this post:

Generating multiple graphics objects for animation

Posted 6 years ago

I would like to generate an animation of similar objects whose characteristics are defined by a function (one that is Piecewise defined, it that makes any difference). If I explicitly define the list of objects with their parameters then the animation works as desired. But I expect to have a large number of objects so that I would like to automatically generate the desired list. A simple example of what I am attempting is shown below. The following example works as expected

f1[t_] := 
 Piecewise[{{t, 0 <= t < 3}, {3 - (t - 3)/2, 3 <= t < 6}, {1.5, 
    t >= 6}}]
Animate[Graphics[{Circle[{f1[t], 0}, 1], Circle[{f1[t - 1], 0}, 2]}, 
  PlotRange -> {{-5, 5}, {-4, 4}}], {t, 0, 10}, AnimationRate -> .5]

But if I try to automatically generate the list of objects with either

gList = Circle[{f1[t - #], 0}, 1 + #] & /@ {0, 1}

or

gList1 = Table[Circle[{f1[t - k], 0}, 1 + k], {k, 0, 1}]

then

Animate[Graphics[gList, PlotRange -> {{-5, 5}, {-4, 4}}], {t, 0, 10}, 
 AnimationRate -> .5]

fails. I have tried various combinations of Hold and HoldForm, but have been unsuccessful in generating a list that Animate will accept. Is there any way that I can generate the list automatically that can be used in the animation?

POSTED BY: Mike Luntz
6 Replies

Mike,

I woke up remembering that there was an example in the documentation highlighting the way that Animate interacts with normal evaluation order that is worth studying.

Animate[Plot[
  Evaluate[{Sin[x], Normal[Series[Sin[x], {x, 0, n}]]}], {x, -10, 10},
   PlotRange -> 3], {n, 1, 20, 2}, 
 AnimationDirection -> ForwardBackward, AnimationRunning -> False]

Note that if you remove the Evaluate, it errors because when Animate evaluates its expression, it sets n to be a value and evaluates the Plot, however, Plot will set a value for x everywhere in the term

{Sin[x], Normal[Series[Sin[x], {x, 0, n}]]}

which is a problem because Series needs to have a variable, not a number where 'x' appears. So the evaluation must be controlled so that n is first given a value, then the Series[] is evaluated, and only then can x take on values in the Plot[]. Animate handles the assignment of n but the Evaluate[] causes the Series to be evaluated out of order -- it comes first before Plot[] sets a value for x. You can edit the example and see the errors and see why it breaks.

To be a bit more clear, the Evaluate really only needs to be around the Series[] because this is the part that has evaluation order issues.

Animate[Plot[{Sin[x], 
   Evaluate[Normal[Series[Sin[x], {x, 0, n}]]]}, {x, -10, 10}, 
  PlotRange -> 3], {n, 1, 20, 2}, 
 AnimationDirection -> ForwardBackward, AnimationRunning -> False]

(Also note that even without the Animate, the Evaluate[] is necessary because the error arises because of the Plot[]. The animate makes it conceptually harder because it adds another variable, n, to the evaluation order issue.)

Your original term

Graphics[gList, PlotRange -> {{-5, 5}, {-4, 4}}]

has a similar problem -- if you evaluate that Graphics[] expression, it errors because the variable tis not yet defined.

I hope this helps.

Regards,

Neil

POSTED BY: Neil Singer
Posted 6 years ago

Thanks again Neil. You are truly a master of Mathematica. You have given me a good bit of information to think about. Reading your responses to my plea for help is akin to watching Vladimir Horowitz play the piano or Itzhak Perlman play the fiddle.:-)

Mike

POSTED BY: Mike Luntz

Our posts crossed. I'm glad this helped you!

POSTED BY: Neil Singer

Mike,

Evaluation order and scoping is a difficult area of Mathematica. It takes considerable experimenting to understand it. I do not have a good reference but I believe there are some threads in the forum that talk about references. Generally the tutorials in the documentation are good. This scoping is especially hard when you use Manipulate, Animate, and Dynamic.

The problem with your formulation is that you used functions to create a list of expressions and then wanted to use that list as a function inside a dynamic construct. This gets complicated. For example,

In[46]:= aa = Expand[(x + 5)^3]

Out[46]= 125 + 75 x + 15 x^2 + x^3

In[47]:= bb[x_] := aa

In[48]:= bb[g]

Out[48]= 125 + 75 x + 15 x^2 + x^3

Note that bb failed to have the proper definition. This is analogous to what you are doing. One way to fix it is to force aa to evaluate immediately.

In[49]:= bb[x_] := Evaluate[aa]

In[50]:= bb[g]

Out[50]= 125 + 75 g + 15 g^2 + g^3

You have a similar problem with gList -- it is an expression in t but you want to substitute in values for t as if it were a function (similar to what I did above). My suggestion would be change your approach and construct circle piecewise functions so that they are functions of t and then they will behave as you expect.

circ[y_, r_][t_] := Circle[{f1[t], y}, r]

gList = Table[circ[0, i], {i, 1, 2}]

{circ[0, 1], circ[0, 2]}

I made a function circ that returns a function of time. Now gList is a list of functions -- not expressions. I can apply each of these to a time and they will produce a circle at that instant in time.

Animate[Graphics[Through[gList[tp]], 
  PlotRange -> {{-5, 5}, {-4, 4}}], {tp, 0, 10}, AnimationRate -> .5]

The function Through just applies each function in my list, gList, to the argument [tp]. Essentially giving you {c1[tp], c2[tp], ... cn[tp]} where c1, c2, ... are circle functions of only time. Now this behaves as you expect. Its a list of functions that animate without having to worry about scoping of variables.

You could also do this with Map instead of Through if it is more clear:

Animate[Graphics[Map[#[tp] &, gList], 
  PlotRange -> {{-5, 5}, {-4, 4}}], {tp, 0, 10}, AnimationRate -> .5]

I hope this helps (and did not make things worse!)).

Regards,

Neil

POSTED BY: Neil Singer
Posted 6 years ago

Thanks Neil. That did the trick. From this question, and others I have had over time, it should be obvious that I have a serious lack of understanding of the fundamentals of Mathematica such as the detailed information in your response. Can you recommend a reference that will provide this kind of information? The Mathematica documentation is great if you know what you are looking for, but information such as you provided is hard to extract from the documentation.

POSTED BY: Mike Luntz

Mike,

The problem is twofold. First gList needs to be evaluated because Animate is HoldAll. Secondly, gList has a variable t that is locally scoped and has no value when it is evaluated -- you need it to be filled in by the animate. These situations can be addressed with the function "With[]". Do the following:

Animate[Graphics[With[{t = tp}, Evaluate[gList]], 
  PlotRange -> {{-5, 5}, {-4, 4}}], {tp, 0, 10}, AnimationRate -> .5]

Regards,

Neil

POSTED BY: Neil Singer
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract