5
$\begingroup$

I'm trying to make an animation of a rotating wheel to show the effect of aliasing in sampled systems. Here is my code, where I use Manipulate to adjust independently both AnimationRate and RefreshRate:

wheel = GraphicsGroup[{{Red, Thickness[0.01], 
     Line[{{0, 0}, {1, 0}}]}, {Thickness[0.01], 
     Circle[{0, 0}, 1], {Red, Disk[{0, 0}, 0.05]}}}];
Manipulate[
 Animate[Graphics[Rotate[wheel, angle]], {angle, 0, 2 Pi}, 
  AnimationRate -> f, RefreshRate -> fs, 
  AnimationRunning -> False], {f, 0.1, 100}, {{fs, 10}, 0.01, 10}] 

The issue is that the two frequencies are out of sync, even at very low refresh and animation frequencies, and where I expect, e.g., a fixed wheel because I set f=fs, I get instead a slowly rotating wheel.

Probably and understandably, the real refresh rate is internally quantized to a certain set of values which rarely coincide with the arbitrary settings obtained through Manipulate.

My question is therefore the following: Are there any preferred values for RefreshRate that I can use to obtain a nice animation? Or is there any other workaround?


Update

I've thought a bit more about the issue and if I understand correctly the operation of Animate, the image should be ideally stationary whenever I set f=fs, even if they're different from 1.

I've done a few tests with two different computers, and it appears that the issue is computer dependent even at very low animation and refresh rates, below 1. The original test was carried out on a laptop with an i3 processor (4 cores, Windows OS); then, I've done another test with an i7 processor (8 cores, Linux OS) and it gives better results.

I wouldn't have expected such large differences between the two computers at such low refresh rates as a few frame per second or less, but that's it. I suspect that there's no solution.

$\endgroup$

2 Answers 2

4
$\begingroup$

AnimationRate sets the fraction of the animation variables range to move through in one second. 0.5 says move through half the range in one second. 2 says move through the entire range twice in one second. RefreshRate sets how many times per second the display is updated.

You will only get a stationary image when both f and fs equal 1. The animation will run in one second and the display is updated once per second. In practice there is a little jitter about the start of the wheel but it doesn't rotate.

The higher you set AnimationRate then the higher you need to set RefreshRate in order to capture the animation at all points. In general for smooth animations you need about 60 frames per second. Your fs tops out at 10 frames per second. However, when you are saying move through the animation range 50 times per second then you would need to increase the frames per second to not get a jittery animation. I would say 120 frames per second.

Hope this helps.

$\endgroup$
3
  • $\begingroup$ Rethinking about what you wrote in the second paragraph, it's not clear to me why you say "You will only get a stationary image when both f and fs equal 1". I think it should be stationary whenever f=fs, regardless of the value, and from a few experiments with the parameters it seems really like this, apart from the difference described in the question which appears to be computer dependent. $\endgroup$ Commented May 9, 2016 at 12:48
  • $\begingroup$ Yes, moving through the animation variables at x times per second and painting the screen at x times per second should get it reasonable stationery. I do find it is extra jittery for higher values. The main point of the above is that your f and fs ranges are out of sync from the outset. $\endgroup$
    – Edmund
    Commented May 9, 2016 at 17:50
  • 1
    $\begingroup$ Thank you, the problem is that I don't want to have a smooth movement, because I want to show the phenomenon of aliasing, but for this I need exact timing: e.g., I'd like to show that with f=0.5 and fs=1 one gets exactly two points per period, the same two, and that for f=0.98 and fs=1 you get a backward motion with a period of exactly 50 s (it gets nowhere near this). But probably Animate has not enough control on the timing for such kind of animations (I'd like to show live these changes). $\endgroup$ Commented May 9, 2016 at 18:15
0
$\begingroup$

I finally had the time to play again with the code in the question and I've eventually found a satisfactory solution... cheating a bit, though.

First, I have to admit that I misinterpreted the parameter AnimationRate. As the documentation says,

AnimationRate->r specifies that the animation variables should be changed by r over the course of one second.

Since the animation variable is the rotation angle, the above means that AnimationRate should be set to the needed angular frequency:

AnimationRate->2Pi f

Then, to avoid the synchronization problem between animation and refresh, I set the animation step equal to the angle by which the wheel rotates between two samples: 2 Pi f/fs. And finally I ask Mathematica to show all the steps with DisplayAllSteps -> True.

The resulting code is the following, where I've added some stuff to manage also negative rotating frequencies and to remove some controls:

ClearAll[wheel];

wheel = GraphicsGroup[{{Red, Thickness[0.01], 
     Line[{{0, 0}, {1, 0}}]}, {Thickness[0.01], 
     Circle[{0, 0}, 1], {Red, Disk[{0, 0}, 0.05]}}}];
Manipulate[
 Animate[Graphics[Rotate[wheel, angle]], {{angle, 0, ""}, -Infinity, 
   Infinity, 2 Pi Abs[f]/fs, AppearanceElements -> "PlayPauseButton"},
   AnimationRate -> 2 Pi Abs[f], 
  AnimationDirection -> If[Sign[f] >= 0, Forward, Backward], 
  DisplayAllSteps -> True, AnimationRunning -> False], {{f, 1}, -10, 
  10}, {{fs, 10}, 0.1, 10}]

Of course, any suggestion for improvements would be still welcomed.

$\endgroup$

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.