manim: t values issue that causes the animations to not be finished entirely.

y values are generated with those lines : (progress_through_animations, l883, scene.py).

        for t in self.get_animation_time_progression(animations):
            dt = t - last_t
            last_t = t
            for animation in animations:
                animation.update_mobjects(dt)
                alpha = t / animation.run_time
                animation.interpolate(alpha)
            self.update_mobjects(dt)
            self.update_frame(moving_mobjects, static_image)
            self.add_frames(self.get_frame())

get_animation_time_progression returns a ProgressBarDisplay object, from the library tdqm that we use to display the progress bar.

When doing -s, skip_animations is enabled to t value is set to 1.0 (no intermediary values as we just need the last frame).

When running normally, eg with 15 fps, there are logically 15 t values, that are :

0.0
0.06666666666666667
0.13333333333333333
0.2
0.26666666666666666
0.3333333333333333
0.4
0.4666666666666667
0.5333333333333333
0.6
0.6666666666666666
0.7333333333333333
0.8
0.8666666666666667
0.9333333333333333

As you may see, 1 is never reached. In other terms, the animations is stopped at 93%). Not that 1.0 change depending on the rn_time : if the run_time was let’s say 3, last t value would be 2.93.

We can see this issue with a single pixel that should be here : image

To give an idea of a fix, I will use the words of @leotrs :

I’ve never used tqdm myself so my question is: is it orthodox/expected/good practice to determine the course of a program by querying the progress bar itself? I’m not sure how this works at all.

It’d be much more reasonable I think for manim to determine its own course of action and then tell the progress bar to reflect that, instead of the other way around

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Comments: 35 (34 by maintainers)

Most upvoted comments

Leo you are correct on this. That is why some video standards have fractions in their fps counts. In the US for example the standard for TV is 59.94 FPS or exactly 1% slower than the 60Hz electricity there.

On Mon, Sep 7, 2020, 3:38 PM Leo Torres notifications@github.com wrote:

I don’t think it’s correct to say that if you add a frame at the end, then the video automatically becomes 2fps.

1fps means that a frame lasts for 1s. If you have a video that is 1s long and it shows one frame for 99.99% of the time, and then at the last instant changes to another frame, then that video is still 1fps because the first frame was shown for (almost exactly) 1s. The second frame would have been shown for 1s as well, if the video had lasted for 2s.

So it seems to me fps really refers to the duration of each frame on screen, not the number of frames you show in the span of of a 1s window. The difference is that the first and/or last frames may be on screen for a different amount of time.

Also, I’m not sure I understand when you say “this issue isn’t really important (it is purely graphical)”. I think we should care if there are graphical issues, since manim is designed to generate video, no?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ManimCommunity/manim/issues/183#issuecomment-688332528, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEDJKY6OU2DY3T45OAXCQFTSETO65ANCNFSM4OUNQ4UA .

Only the time between frames is counted toward the animation, so there is no additional 1/15 seconds added by the last frame. For example if you wanted to show an animation at 1 fps for 1 second you’d have to generate a start and end frame, otherwise you wouldn’t have any video at all.

@huguesdevimeux could you please update us here? I thought this was fixed.

Well, it is not fixed. I’m working on it !

Keep in mind that if we do this then the last frame of animation n and the first frame of animation n+1 will always be the same, which would cause an unavoidable pause between animations which would be especially noticeable at low frame rates. It wouldn’t be possible to create the effect where animation 1 runs from 0s to 1s and animation 2 runs from 1s to 2s. This isn’t technically possible now, since playing an animation for 1s at a given frame rate generates <frame_rate> frames, which is only (frame_rate-1)/frame_rate seconds of video.

If you did want to do this, you’d probably want to increase the number of samples to 1 more than the frame rate so that each animation played for 1s rather than (frame_rate-1)/(frame_rate) seconds as it does now. Consecutive calls to play() would then generate video lengths of 1s, (2 + 1/frame_rate)s, (3 + 2/frame_rate)s, etc.

However, I think the proper solution is just to add a terminating frame at the end of the last animation, so that consecutive calls to play() would generate video with frame counts of 16, 31, 46, etc., which corresponds to video lengths of 1s, 2s, 3s, etc. at 15fps.