From 8f2a8f032ee8eab647cfe08ac2618436fa76127a Mon Sep 17 00:00:00 2001 From: Grant Sanderson Date: Fri, 25 Sep 2015 19:43:53 -0700 Subject: [PATCH] More music_and_measure, animate->play, making NumberLine better --- animation/animation.py | 2 +- animation/simple_animations.py | 1 - animation/transform.py | 28 +- mobject/creatures.py | 6 +- mobject/function_graphs.py | 83 ++++-- mobject/mobject.py | 35 ++- mobject/simple_mobjects.py | 6 +- scene/arithmetic_scenes.py | 2 +- scene/counting_scene.py | 2 +- scene/graphs.py | 12 +- scene/number_line.py | 15 + scene/scene.py | 4 +- scripts/counting_in_binary.py | 20 +- scripts/ecf_graph_scenes.py | 112 ++++---- scripts/generate_logo.py | 2 +- scripts/inventing_math.py | 214 +++++++------- scripts/moser_main.py | 164 +++++------ scripts/music_and_measure.py | 508 +++++++++++++++++++++++++++++++-- scripts/tau_poem.py | 72 ++--- 19 files changed, 908 insertions(+), 380 deletions(-) create mode 100644 scene/number_line.py diff --git a/animation/animation.py b/animation/animation.py index 591c6538..8ca76f6c 100644 --- a/animation/animation.py +++ b/animation/animation.py @@ -27,7 +27,6 @@ class Animation(object): raise Exception("Invalid mobject parameter, must be \ subclass or instance of Mobject") self.starting_mobject = copy.deepcopy(self.mobject) - self.reference_mobjects = [self.starting_mobject] self.alpha_func = alpha_func or (lambda x : x) self.run_time = run_time #TODO, Adress the idea of filtering the animation @@ -36,6 +35,7 @@ class Animation(object): self.restricted_width = SPACE_WIDTH self.spacial_center = np.zeros(3) self.name = name or self.__class__.__name__ + str(self.mobject) + self.update(0) def __str__(self): return self.name diff --git a/animation/simple_animations.py b/animation/simple_animations.py index dacffdb1..c70498ab 100644 --- a/animation/simple_animations.py +++ b/animation/simple_animations.py @@ -187,7 +187,6 @@ class Succession(Animation): for index in range(len(self.anims)): self.anims[index].update(scaled_alpha - index) - ####### Pi Creature Stuff ############# class WalkPiCreature(Animation): diff --git a/animation/transform.py b/animation/transform.py index 79198445..dcedc6b6 100644 --- a/animation/transform.py +++ b/animation/transform.py @@ -39,25 +39,27 @@ class Transform(Animation): self.interpolation_function = interpolation_function count1, count2 = mobject1.get_num_points(), mobject2.get_num_points() if count2 == 0: - mobject2.add_points([(SPACE_WIDTH, SPACE_HEIGHT, 0)]) + mobject2.add_points([SPACE_WIDTH*RIGHT+SPACE_HEIGHT*UP]) count2 = mobject2.get_num_points() Mobject.align_data(mobject1, mobject2) - Animation.__init__(self, mobject1, run_time = run_time, *args, **kwargs) self.ending_mobject = mobject2 + if black_out_extra_points and count2 < count1: + self.black_out_extra_points(count1, count2) + + Animation.__init__(self, mobject1, run_time = run_time, *args, **kwargs) + self.name += "To" + str(mobject2) self.mobject.SHOULD_BUFF_POINTS = \ mobject1.SHOULD_BUFF_POINTS and mobject2.SHOULD_BUFF_POINTS - self.reference_mobjects.append(mobject2) - self.name += "To" + str(mobject2) - if black_out_extra_points and count2 < count1: - #Ensure redundant pixels fade to black - indices = np.arange( - 0, count1-1, float(count1) / count2 - ).astype('int') - temp = np.zeros(mobject2.points.shape) - temp[indices] = mobject2.rgbs[indices] - mobject2.rgbs = temp - self.non_redundant_m2_indices = indices + def black_out_extra_points(self, count1, count2): + #Ensure redundant pixels fade to black + indices = np.arange( + 0, count1-1, float(count1) / count2 + ).astype('int') + temp = np.zeros(self.ending_mobject.points.shape) + temp[indices] = self.ending_mobject.rgbs[indices] + self.ending_mobject.rgbs = temp + self.non_redundant_m2_indices = indices def update_mobject(self, alpha): self.mobject.points = self.interpolation_function( diff --git a/mobject/creatures.py b/mobject/creatures.py index c0ac3a68..283afdb9 100644 --- a/mobject/creatures.py +++ b/mobject/creatures.py @@ -55,9 +55,9 @@ class PiCreature(CompoundMobject): CompoundMobject.__init__(self, *self.get_parts()) return self - def TODO_what_should_I_do_with_this(self): - for part_name, mob in zip(self.part_names, self.split()): - setattr(self, part_name, mob) + # def TODO_what_should_I_do_with_this(self): + # for part_name, mob in zip(self.part_names, self.split()): + # setattr(self, part_name, mob) def get_parts(self): diff --git a/mobject/function_graphs.py b/mobject/function_graphs.py index 40095efd..c12ebe8f 100644 --- a/mobject/function_graphs.py +++ b/mobject/function_graphs.py @@ -92,27 +92,48 @@ class Grid(Mobject1D): class NumberLine(Mobject1D): def __init__(self, - radius = SPACE_WIDTH+1, - interval_size = 0.5, tick_size = 0.1, - *args, **kwargs): - self.radius = int(radius) - self.interval_size = interval_size + radius = SPACE_WIDTH, + unit_length_to_spacial_width = 1, + tick_size = 0.1, + tick_frequency = 0.5, + number_at_center = 0, + numbers_with_elongated_ticks = [0], + longer_tick_multiple = 2, + **kwargs): + #TODO, There must be better (but still safe) way to add all + #these config arguments as attributes. + self.radius = radius + self.unit_length_to_spacial_width = unit_length_to_spacial_width self.tick_size = tick_size - Mobject1D.__init__(self, *args, **kwargs) + self.tick_frequency = tick_frequency + self.numbers_with_elongated_ticks = numbers_with_elongated_ticks + self.number_at_center = number_at_center + self.longer_tick_multiple = longer_tick_multiple + numerical_radius = float(radius) / unit_length_to_spacial_width + self.left_num = number_at_center - numerical_radius + self.right_num = number_at_center + numerical_radius + Mobject1D.__init__(self, **kwargs) def generate_points(self): self.add_points([ - (x, 0, 0) - for x in np.arange(-self.radius, self.radius, self.epsilon) + (b*x, 0, 0) + for x in np.arange(0, self.radius, self.epsilon) + for b in [-1, 1] ]) + self.index_of_left = np.argmin(self.points[:,0]) + self.index_of_right = np.argmax(self.points[:,0]) + spacial_tick_frequency = self.tick_frequency*self.unit_length_to_spacial_width self.add_points([ - (x, y, 0) - for x in np.arange(-self.radius, self.radius, self.interval_size) + (b*x, y, 0) + for x in np.arange(0, self.radius, spacial_tick_frequency) for y in np.arange(-self.tick_size, self.tick_size, self.epsilon) + for b in ([1, -1] if x > 0 else [1]) ]) - self.elongate_tick_at(0) + for number in self.numbers_with_elongated_ticks: + self.elongate_tick_at(number, self.longer_tick_multiple) - def elongate_tick_at(self, x, multiple = 2): + def elongate_tick_at(self, number, multiple = 2): + x = self.number_to_point(number)[0] self.add_points([ [x, y, 0] for y in np.arange( @@ -123,17 +144,37 @@ class NumberLine(Mobject1D): ]) return self - def add_numbers(self, intervals_per_number = 2): - max_val = int(self.radius/self.interval_size/intervals_per_number) - for x in range(-max_val, max_val+1): - num = tex_mobject(str(x)).scale(0.5) - num.shift( - DOWN*4*self.tick_size + \ - RIGHT*x*self.interval_size*intervals_per_number - ) - self.add(num) + def number_to_point(self, number): + return interpolate( + self.points[self.index_of_left], + self.points[self.index_of_right], + float(number-self.left_num)/(self.right_num - self.left_num) + ) + + def add_numbers(self, *numbers): + if len(numbers) == 0: + numbers = range(int(self.left_num), int(self.right_num+1)) + for number in numbers: + mob = tex_mobject(str(number)).scale(0.5) + mob.shift(self.number_to_point(number)) + mob.shift(DOWN*4*self.tick_size) + self.add(mob) return self +class UnitInterval(NumberLine): + DEFAULT_CONFIG = { + "radius" : SPACE_WIDTH-1, + "unit_length_to_spacial_width" : 2*(SPACE_WIDTH-1), + "tick_frequency" : 0.1, + "number_at_center" : 0.5, + "numbers_with_elongated_ticks" : [0, 1], + } + def __init__(self, **kwargs): + config = self.DEFAULT_CONFIG + config.update(kwargs) + NumberLine.__init__(self, **config) + + class Axes(CompoundMobject): def __init__(self, *args, **kwargs): x_axis = NumberLine(*args, **kwargs) diff --git a/mobject/mobject.py b/mobject/mobject.py index b0fccccc..79f3b80f 100644 --- a/mobject/mobject.py +++ b/mobject/mobject.py @@ -21,6 +21,7 @@ class Mobject(object): DEFAULT_COLOR = Color("skyblue") SHOULD_BUFF_POINTS = GENERALLY_BUFF_POINTS EDGE_BUFFER = 0.5 + NEXT_TO_BUFFER = 0.2 def __init__(self, color = None, @@ -152,12 +153,17 @@ class Mobject(object): self.shift(shift_val) return self - def next_to(self, mobject, direction = RIGHT, buff = EDGE_BUFFER): - self.shift( - mobject.get_edge_center(direction) - \ - self.get_edge_center(-direction) + \ - buff * direction - ) + def next_to(self, mobject, + direction = RIGHT, + buff = NEXT_TO_BUFFER, + aligned_edge = None): + if aligned_edge is not None: + anchor_point = self.get_corner(aligned_edge-direction) + target_point = mobject.get_corner(aligned_edge+direction) + else: + anchor_point = self.get_edge_center(-direction) + target_point = mobject.get_edge_center(direction) + self.shift(target_point - anchor_point + buff*direction) return self def scale(self, scale_factor): @@ -225,8 +231,16 @@ class Mobject(object): self.rgbs[:,:] = rgb return self + def to_original_color(self): + self.highlight(self.color) + return self + + def fade_to(self, color, alpha): + self.rgbs = interpolate(self.rgbs, Color(color).rgb, alpha) + return self + def fade(self, brightness = 0.5): - self.rgbs *= brightness + self.fade_to("black", brightness) return self def filter_out(self, condition): @@ -268,6 +282,13 @@ class Mobject(object): result[dim] = max_or_min_func(self.points[:,dim]) return result + def get_corner(self, direction): + return sum([ + self.get_edge_center(RIGHT*direction[0]), + self.get_edge_center(UP*direction[1]), + -self.get_center() + ]) + def get_top(self): return self.get_edge_center(UP) diff --git a/mobject/simple_mobjects.py b/mobject/simple_mobjects.py index 9ff18f4a..b3baf05a 100644 --- a/mobject/simple_mobjects.py +++ b/mobject/simple_mobjects.py @@ -102,7 +102,7 @@ class Arrow(Line): def add_tip(self, tip_length): vect = self.start-self.end - vect *= tip_length/np.linalg.norm(vect) + vect = vect*tip_length/np.linalg.norm(vect) self.add_points([ interpolate(self.end, self.end+v, t) for t in np.arange(0, 1, tip_length*self.epsilon) @@ -217,8 +217,8 @@ class Bubble(Mobject): return self class SpeechBubble(Bubble): - INITIAL_WIDTH = 6 - INITIAL_HEIGHT = 4 + INITIAL_WIDTH = 4 + INITIAL_HEIGHT = 2 def __init__(self, *args, **kwargs): Mobject.__init__(self, *args, **kwargs) complex_power = 0.9 diff --git a/scene/arithmetic_scenes.py b/scene/arithmetic_scenes.py index ca16acc6..84c32d19 100644 --- a/scene/arithmetic_scenes.py +++ b/scene/arithmetic_scenes.py @@ -56,7 +56,7 @@ class RearrangeEquation(Scene): if leave_start_terms: self.add(CompoundMobject(*start_mobs)) self.dither() - self.animate(*[ + self.play(*[ Transform(*pair, **transform_kwargs) for pair in mobject_pairs ]) diff --git a/scene/counting_scene.py b/scene/counting_scene.py index 24c8647b..536967ad 100644 --- a/scene/counting_scene.py +++ b/scene/counting_scene.py @@ -52,7 +52,7 @@ class CountingScene(Scene): self.dither(frame_time) mob.highlight(original_color) if mode == "show_creation": - self.animate(ShowCreation(mob, run_time = frame_time)) + self.play(ShowCreation(mob, run_time = frame_time)) if mode == "show": self.add(mob) self.dither(frame_time) diff --git a/scene/graphs.py b/scene/graphs.py index 348e65ad..f4e45a31 100644 --- a/scene/graphs.py +++ b/scene/graphs.py @@ -220,10 +220,10 @@ class GraphScene(Scene): def draw_vertices(self, **kwargs): self.clear() - self.animate(ShowCreation(CompoundMobject(*self.vertices), **kwargs)) + self.play(ShowCreation(CompoundMobject(*self.vertices), **kwargs)) def draw_edges(self): - self.animate(*[ + self.play(*[ ShowCreation(edge, run_time = 1.0) for edge in self.edges ]) @@ -235,7 +235,7 @@ class GraphScene(Scene): Dot(point, radius = 3*Dot.DEFAULT_RADIUS, color = "lightgreen") for point in self.points ]) - self.animate(Transform( + self.play(Transform( start, end, alpha_func = there_and_back, **kwargs )) @@ -246,7 +246,7 @@ class GraphScene(Scene): def replace_vertices_with(self, mobject): mobject.center() diameter = max(mobject.get_height(), mobject.get_width()) - self.animate(*[ + self.play(*[ CounterclockwiseTransform( vertex, deepcopy(mobject).shift(vertex.get_center()) @@ -267,7 +267,7 @@ class GraphScene(Scene): for angle, edge in zip(angles, self.edges) ] if fade_in: - self.animate(*[ + self.play(*[ FadeIn(ann, **kwargs) for ann in self.edge_annotations ]) @@ -282,7 +282,7 @@ class GraphScene(Scene): Line(self.points[i], self.points[j]).highlight(color) for i, j in zip(cycle, next_in_cycle) ]) - self.animate( + self.play( ShowCreation(self.traced_cycle), run_time = run_time ) diff --git a/scene/number_line.py b/scene/number_line.py new file mode 100644 index 00000000..6423c72f --- /dev/null +++ b/scene/number_line.py @@ -0,0 +1,15 @@ +import numpy as np +import itertools as it + +from scene import Scene + +from mobject import * +from animation import * +from region import * +from constants import * +from helpers import * + + +class NumberLineScene(Scene): + def construct(self): + pass \ No newline at end of file diff --git a/scene/scene.py b/scene/scene.py index 18ff6388..a4fe48fb 100644 --- a/scene/scene.py +++ b/scene/scene.py @@ -98,7 +98,7 @@ class Scene(object): self.background = self.original_background return self - def animate(self, *animations, **kwargs): + def play(self, *animations, **kwargs): if "run_time" in kwargs: run_time = kwargs["run_time"] else: @@ -127,7 +127,7 @@ class Scene(object): progress_bar.finish() return self - def animate_over_time_range(self, t0, t1, *animations): + def play_over_time_range(self, t0, t1, *animations): needed_scene_time = max(abs(t0), abs(t1)) existing_scene_time = len(self.frames)*self.frame_duration if existing_scene_time < needed_scene_time: diff --git a/scripts/counting_in_binary.py b/scripts/counting_in_binary.py index 58c82396..30b3fc8f 100644 --- a/scripts/counting_in_binary.py +++ b/scripts/counting_in_binary.py @@ -235,7 +235,7 @@ class Introduction(Scene): self.add(words) self.dither() - self.animate(DelayByOrder(Transform(words, hand))) + self.play(DelayByOrder(Transform(words, hand))) self.dither() @@ -261,9 +261,9 @@ class ShowReadingRule(Scene): self.add(answer[0]) counts = map(finger_tip_power_of_2, range(5)) for count in counts: - self.animate(SpinInFromNothing(count, run_time = 0.3)) + self.play(SpinInFromNothing(count, run_time = 0.3)) self.dither() - self.animate(ShimmerIn(answer[1])) + self.play(ShimmerIn(answer[1])) for count in sample_counts: self.clear() self.add(*answer) @@ -283,7 +283,7 @@ class ShowReadingRule(Scene): ).to_corner(UP+RIGHT).split() self.add(hand, *count_mobs) self.dither() - self.animate(*[ + self.play(*[ Transform(count_mobs[n/2], sum_mobs[n]) if n%2 == 0 and n/2 < len(counts) else FadeIn(sum_mobs[n]) @@ -325,7 +325,7 @@ class ShowIncrementRule(Scene): if pause: self.background = oh.frames[COUNT_TO_FRAME_NUM[start]] self.add(phrase) - self.animate(ShimmerIn(self.get_arrow_set(start))) + self.play(ShimmerIn(self.get_arrow_set(start))) self.dither() self.clear() self.reset_background() @@ -391,7 +391,7 @@ class MindFindsShortcuts(Scene): seven ) self.dither() - self.animate( + self.play( Transform(compound, Arrow(hand, seven).highlight("yellow")), ShimmerIn(text_mobject("Directly recognize").shift(1.5*DOWN+2*RIGHT)) ) @@ -413,7 +413,7 @@ class MindFindsShortcuts(Scene): self.add(words2, hands[23]) self.dither() - self.animate( + self.play( Transform( deepcopy(hands[16]).highlight("black").center().shift(hands[23].get_center()), hands[16] @@ -427,7 +427,7 @@ class MindFindsShortcuts(Scene): FadeIn(plus) ) self.dither() - self.animate(ShimmerIn(equals23)) + self.play(ShimmerIn(equals23)) self.dither() @@ -452,7 +452,7 @@ class FinishCountingExampleSentence(Scene): comp = CompoundMobject(sixteen, two) self.add(hand, comp, words) self.dither() - self.animate(Transform(comp, eightteen)) + self.play(Transform(comp, eightteen)) self.dither() class Question(Scene): @@ -474,7 +474,7 @@ class WithToes(Scene): ]).split() self.add(words[0]) self.dither() - self.animate(ShimmerIn(words[1])) + self.play(ShimmerIn(words[1])) self.dither() diff --git a/scripts/ecf_graph_scenes.py b/scripts/ecf_graph_scenes.py index e37fe066..4bfd9c55 100644 --- a/scripts/ecf_graph_scenes.py +++ b/scripts/ecf_graph_scenes.py @@ -48,7 +48,7 @@ class PreferOtherProofDialogue(Scene): self.add(student, teacher, teacher_bubble, teacher_bubble.text) self.dither(2) - self.animate(Transform( + self.play(Transform( Dot(student_bubble.tip).highlight("black"), CompoundMobject(student_bubble, student_bubble.text) )) @@ -76,7 +76,7 @@ class IllustrateDuality(GraphScene): "run_time" : 5.0, "alpha_func" : special_alpha } - self.animate(*[ + self.play(*[ Transform(*edge_pair, **kwargs) for edge_pair in zip(self.edges, self.dual_edges) ] + [ @@ -129,7 +129,7 @@ class IntroduceGraph(GraphScene): "run_time" : 5.0 } self.add(not_okay) - self.animate(*[ + self.play(*[ Transform(*pair, **kwargs) for pair in zip( self.edges + self.vertices, @@ -142,7 +142,7 @@ class IntroduceGraph(GraphScene): self.remove(planar_explanation) self.add(not_okay) self.remove(*edges_to_remove) - self.animate(ShowCreation( + self.play(ShowCreation( CompoundMobject(*edges_to_remove), alpha_func = lambda t : 1 - t, run_time = 1.0 @@ -164,7 +164,7 @@ class OldIntroduceGraphs(GraphScene): self.replace_vertices_with(Face().scale(0.4)) friends = text_mobject("Friends").scale(EDGE_ANNOTATION_SCALE_VAL) self.annotate_edges(friends.shift((0, friends.get_height()/2, 0))) - self.animate(*[ + self.play(*[ CounterclockwiseTransform(vertex, Dot(point)) for vertex, point in zip(self.vertices, self.points) ]+[ @@ -195,7 +195,7 @@ class PlanarGraphDefinition(Scene): self.add(quote, planar, end_quote) self.dither() - self.animate( + self.play( FadeOut(quote), FadeOut(end_quote), ApplyMethod(planar.shift, shift_val), @@ -238,26 +238,26 @@ class TerminologyFromPolyhedra(GraphScene): regions_to_faces = text_mobject("Regions $\\to$ Faces").to_corner() self.clear() - # self.animate(TransformAnimations( + # self.play(TransformAnimations( # Rotating(Dodecahedron(), **rot_kwargs), # Rotating(cube, **rot_kwargs) # )) - self.animate(Rotating(cube, **rot_kwargs)) + self.play(Rotating(cube, **rot_kwargs)) self.clear() - self.animate(*[ + self.play(*[ Transform(l1, l2) for l1, l2 in zip(cube.split(), self.edges) ]) self.dither() self.add(dots_to_vertices) - self.animate(*[ + self.play(*[ ShowCreation(dot, run_time = 1.0) for dot in self.vertices ]) self.dither(2) self.remove(dots_to_vertices, *self.vertices) self.add(lines_to_edges) - self.animate(ApplyMethod( + self.play(ApplyMethod( CompoundMobject(*self.edges).highlight, "yellow" )) self.dither(2) @@ -295,7 +295,7 @@ class ThreePiecesOfTerminology(GraphScene): self.remove(self.traced_cycle) self.add(accent(spanning_trees)) - self.animate(ShowCreation(self.spanning_tree), run_time = 1.0) + self.play(ShowCreation(self.spanning_tree), run_time = 1.0) self.dither() tone_down(spanning_trees) self.remove(self.spanning_tree) @@ -304,14 +304,14 @@ class ThreePiecesOfTerminology(GraphScene): self.generate_dual_graph() for mob in self.mobjects: mob.fade - self.animate(*[ + self.play(*[ ShowCreation(mob, run_time = 1.0) for mob in self.dual_vertices + self.dual_edges ]) self.dither() self.clear() - self.animate(ApplyMethod( + self.play(ApplyMethod( CompoundMobject(*terms).center )) self.dither() @@ -335,7 +335,7 @@ class WalkingRandolph(GraphScene): randy.scale(RANDOLPH_SCALE_VAL) randy.move_to(point_path[0]) for next, last in zip(point_path[1:], point_path): - self.animate( + self.play( WalkPiCreature(randy, next), ShowCreation(Line(last, next).highlight("yellow")), run_time = 2.0 @@ -378,13 +378,13 @@ class PathExamples(GraphScene): self.remove(not_a_path) self.add(valid_path) - self.animate(ShowCreation(path_lines, **kwargs)) + self.play(ShowCreation(path_lines, **kwargs)) self.dither(2) self.remove(path_lines) self.remove(valid_path) self.add(not_a_path) - self.animate(ShowCreation(non_path_lines, **kwargs)) + self.play(ShowCreation(non_path_lines, **kwargs)) self.dither(2) self.remove(non_path_lines) @@ -414,7 +414,7 @@ class IntroduceRandolph(GraphScene): GraphScene.construct(self) randy = Randolph().move_to((-3, 0, 0)) name = text_mobject("Randolph") - self.animate(Transform( + self.play(Transform( randy, deepcopy(randy).scale(RANDOLPH_SCALE_VAL).move_to(self.points[0]), )) @@ -454,19 +454,19 @@ class DefineSpanningTree(GraphScene): self.dither(2) self.remove(dollar_signs) run_time_per_branch = 0.5 - self.animate( + self.play( ShowCreation(green_dot_at_index(0)), run_time = run_time_per_branch ) for pair in self.spanning_tree_index_pairs: - self.animate(ShowCreation( + self.play(ShowCreation( Line( self.points[pair[0]], self.points[pair[1]] ).highlight("yellow"), run_time = run_time_per_branch )) - self.animate(ShowCreation( + self.play(ShowCreation( green_dot_at_index(pair[1]), run_time = run_time_per_branch )) @@ -476,7 +476,7 @@ class DefineSpanningTree(GraphScene): for edge, limit in zip(unneeded_edges, range(5)): line = Line(self.points[edge[0]], self.points[edge[1]]) line.highlight("red") - self.animate(ShowCreation(line, run_time = 1.0)) + self.play(ShowCreation(line, run_time = 1.0)) self.add(unneeded.center().shift(line.get_center() + 0.2*UP)) self.dither() self.remove(line, unneeded) @@ -493,19 +493,19 @@ class NamingTree(GraphScene): spanning_tree = text_mobject("``Spanning Tree''").to_edge(UP) self.add(*branches) - self.animate( + self.play( FadeOut(CompoundMobject(*self.edges + self.vertices)), Animation(CompoundMobject(*branches)), ) self.clear() self.add(tree, *branches) self.dither() - self.animate(*[ + self.play(*[ Transform(b1, b2, run_time = 2) for b1, b2 in zip(branches, treeified_branches) ]) self.dither() - self.animate(*[ + self.play(*[ FadeIn(mob) for mob in self.edges + self.vertices ] + [ @@ -522,7 +522,7 @@ class DualGraph(GraphScene): GraphScene.construct(self) self.generate_dual_graph() self.add(text_mobject("Dual Graph").to_edge(UP).shift(2*LEFT)) - self.animate(*[ + self.play(*[ ShowCreation(mob) for mob in self.dual_edges + self.dual_vertices ]) @@ -557,12 +557,12 @@ class FacebookGraph(GraphScene): self.dither() self.annotate_edges(friends) self.dither() - self.animate(*[ + self.play(*[ CounterclockwiseTransform(account, vertex) for account, vertex in zip(accounts, self.vertices) ]) self.dither() - self.animate(*[ + self.play(*[ Transform(ann, edge) for ann, edge in zip(self.edge_annotations, self.edges) ]) @@ -607,7 +607,7 @@ class FacebookGraphAsAbstractSet(Scene): self.add(accounts, friendships, lines) self.dither() for mob in names_mob, friends_mob: - self.animate(ShowCreation( + self.play(ShowCreation( mob, run_time = 1.0 )) self.dither() @@ -690,10 +690,10 @@ class ExamplesOfGraphs(GraphScene): comp_words = CompoundMobject(*words) comp_lines = CompoundMobject(*lines) self.add(words1) - self.animate(ShowCreation(comp_words, run_time = 1.0)) + self.play(ShowCreation(comp_words, run_time = 1.0)) self.dither() self.add(words2) - self.animate(ShowCreation(comp_lines, run_time = 1.0)) + self.play(ShowCreation(comp_lines, run_time = 1.0)) self.dither() self.remove(comp_words, comp_lines) @@ -708,7 +708,7 @@ class ExamplesOfGraphs(GraphScene): for mob in connected, not_connected: mob.shift(self.points[3] + UP) - self.animate(*[ + self.play(*[ ShowCreation(mob, run_time = 1.0) for mob in self.edges + self.vertices ]) @@ -745,7 +745,7 @@ class ExamplesOfGraphs(GraphScene): tup = tuple(reversed(tup)) edge = deepcopy(self.edges[self.graph.edges.index(tup)]) edge.highlight("red") - self.animate(ShowCreation(edge), run_time = 1.0) + self.play(ShowCreation(edge), run_time = 1.0) self.dither() self.remove(edge) else: @@ -787,19 +787,19 @@ class DrawDualGraph(GraphScene): self.dither() self.reset_background() self.highlight_region(outer_region, outer_region_mob.get_color()) - self.animate(*[ + self.play(*[ Transform(reg_mob, dot) for reg_mob, dot in zip(region_mobs, self.dual_vertices) ]) self.dither() self.reset_background() - self.animate(ApplyFunction( + self.play(ApplyFunction( lambda p : (SPACE_WIDTH + SPACE_HEIGHT)*p/np.linalg.norm(p), outer_region_mob )) self.dither() for edges in internal_edges, external_edges: - self.animate(*[ + self.play(*[ ShowCreation(edge, run_time = 2.0) for edge in edges ]) @@ -812,7 +812,7 @@ class EdgesAreTheSame(GraphScene): self.remove(*self.vertices) self.add(*self.dual_edges) self.dither() - self.animate(*[ + self.play(*[ Transform(*pair, run_time = 2.0) for pair in zip(self.dual_edges, self.edges) ]) @@ -880,7 +880,7 @@ class CyclesCorrespondWithConnectedComponents(GraphScene): for last, next in zip(cycle, cycle[1:]): line = Line(self.points[last], self.points[next]) line.highlight("yellow") - self.animate( + self.play( ShowCreation(line), WalkPiCreature(randy, self.points[next]), run_time = 1.0 @@ -896,8 +896,8 @@ class CyclesCorrespondWithConnectedComponents(GraphScene): Line(self.dual_points[last], self.dual_points[next]) for last, next in zip(dual_cycle, dual_cycle[1:]) ]).highlight("red") - self.animate(ShowCreation(lines)) - self.animate(*[ + self.play(ShowCreation(lines)) + self.play(*[ Transform(v, Dot( v.get_center(), radius = 3*Dot.DEFAULT_RADIUS @@ -937,7 +937,7 @@ class IntroduceMortimer(GraphScene): small_morty = deepcopy(morty).scale(RANDOLPH_SCALE_VAL) small_randy.move_to(self.points[randy_path[0]]) small_morty.move_to(self.dual_points[morty_path[0]]) - self.animate(*[ + self.play(*[ FadeIn(mob) for mob in self.vertices + self.edges ] + [ @@ -949,19 +949,19 @@ class IntroduceMortimer(GraphScene): self.highlight_region(self.regions[morty_path[0]]) for last, next in zip(morty_path, morty_path[1:]): - self.animate(WalkPiCreature(morty, self.dual_points[next]),**kwargs) + self.play(WalkPiCreature(morty, self.dual_points[next]),**kwargs) self.highlight_region(self.regions[next]) self.dither() for last, next in zip(randy_path, randy_path[1:]): line = Line(self.points[last], self.points[next]) line.highlight("yellow") - self.animate( + self.play( WalkPiCreature(randy, self.points[next]), ShowCreation(line), **kwargs ) self.dither() - self.animate(*[ + self.play(*[ ApplyMethod( line.rotate_in_place, np.pi/10, @@ -988,9 +988,9 @@ class RandolphMortimerSpanningTreeGame(GraphScene): time_per_dual_edge = 0.5 self.add(randy, morty) - self.animate(ShowCreation(self.spanning_tree)) + self.play(ShowCreation(self.spanning_tree)) self.dither() - self.animate(WalkPiCreature( + self.play(WalkPiCreature( morty, self.dual_points[attempted_dual_point_index], alpha_func = lambda t : 0.3 * there_and_back(t), run_time = 2.0, @@ -1000,7 +1000,7 @@ class RandolphMortimerSpanningTreeGame(GraphScene): # if index > 0: # edge = self.edges[dual_edges[index-1]] # midpoint = edge.get_center() - # self.animate(*[ + # self.play(*[ # ShowCreation(Line( # midpoint, # tip @@ -1015,7 +1015,7 @@ class RandolphMortimerSpanningTreeGame(GraphScene): cycle_index = region_ordering[-1] cycle = self.graph.region_cycles[cycle_index] self.highlight_region(self.regions[cycle_index], "black") - self.animate(ShowCreation(CompoundMobject(*[ + self.play(ShowCreation(CompoundMobject(*[ Line(self.points[last], self.points[next]).highlight("green") for last, next in zip(cycle, list(cycle)[1:] + [cycle[0]]) ]))) @@ -1043,7 +1043,7 @@ class MortimerCannotTraverseCycle(GraphScene): for last, next in zip(dual_cycle, dual_cycle[1:]): line = Line(self.dual_points[last], self.dual_points[next]) line.highlight("red") - self.animate( + self.play( WalkPiCreature(morty, self.dual_points[next], **kwargs), ShowCreation(line, **kwargs), ) @@ -1056,7 +1056,7 @@ class MortimerCannotTraverseCycle(GraphScene): matching_edges.append( self.edges[distances.index(min(distances))] ) - self.animate(*[ + self.play(*[ Transform(v, Dot( v.get_center(), radius = 3*Dot.DEFAULT_RADIUS, @@ -1065,7 +1065,7 @@ class MortimerCannotTraverseCycle(GraphScene): for v in np.array(self.vertices)[trapped_points] ]) self.add(text) - self.animate(*[ + self.play(*[ Transform(line, deepcopy(edge).highlight(line.get_color())) for line, edge in zip(all_lines, matching_edges) ]) @@ -1095,7 +1095,7 @@ class TwoPropertiesOfSpanningTree(Scene): explanation.get_center() + vect, tail = word.get_center() - vect, )) - self.animate(ApplyMethod(word.highlight, "yellow")) + self.play(ApplyMethod(word.highlight, "yellow")) self.dither() @@ -1116,7 +1116,7 @@ class DualSpanningTree(GraphScene): """).to_edge(UP) self.add(self.spanning_tree, randy, morty) - self.animate(ShowCreation(CompoundMobject( + self.play(ShowCreation(CompoundMobject( *np.array(self.edges)[dual_edges] ).highlight("red"))) self.add(words) @@ -1136,7 +1136,7 @@ class TreeCountFormula(Scene): all_dots = [Dot(branches[0].points[0])] self.add(text, all_dots[0]) for branch in branches: - self.animate( + self.play( ShowCreation(branch), run_time = time_per_branch ) @@ -1145,7 +1145,7 @@ class TreeCountFormula(Scene): all_dots.append(dot) self.dither() self.remove(*all_dots) - self.animate( + self.play( FadeOut(text), FadeIn(CompoundMobject(*gs.edges + gs.vertices)), *[ @@ -1178,7 +1178,7 @@ class FinalSum(Scene): copy.scale_in_place(lines[index].get_width()/mob.get_width()) anims.append(CounterclockwiseTransform(copy, mob)) self.clear() - self.animate(*anims, run_time = 2.0) + self.play(*anims, run_time = 2.0) self.dither() diff --git a/scripts/generate_logo.py b/scripts/generate_logo.py index e364f87f..863c92fc 100644 --- a/scripts/generate_logo.py +++ b/scripts/generate_logo.py @@ -52,7 +52,7 @@ class LogoGeneration(Scene): name.highlight("grey") name.shift(2*DOWN) - self.animate(Transform( + self.play(Transform( circle, iris, run_time = DEFAULT_ANIMATION_RUN_TIME )) diff --git a/scripts/inventing_math.py b/scripts/inventing_math.py index 2d1e327f..edf945ca 100644 --- a/scripts/inventing_math.py +++ b/scripts/inventing_math.py @@ -15,7 +15,7 @@ from region import * from scene import Scene, RearrangeEquation from script_wrapper import command_line_create_scene -from inventing_math_images import * +# from inventing_math_images import * MOVIE_PREFIX = "inventing_math/" DIVERGENT_SUM_TEXT = [ @@ -191,7 +191,7 @@ class IntroduceDivergentSum(Scene): **kwargs ) self.add(ellipses) - self.animate( + self.play( Transform(brace, end_brace, **kwargs), flip_through, ) @@ -220,17 +220,17 @@ class ClearlyNonsense(Scene): this_way.highlight("yellow") right_arrow.highlight("yellow") - self.animate(Transform( + self.play(Transform( div_sum, deepcopy(div_sum).scale(0.5).shift(3*UP) )) - self.animate(ShowCreation(number_line)) + self.play(ShowCreation(number_line)) self.dither() self.add(how_here) - self.animate(ShowCreation(neg_1_arrow)) + self.play(ShowCreation(neg_1_arrow)) self.dither() self.add(this_way) - self.animate(ShowCreation(right_arrow)) + self.play(ShowCreation(right_arrow)) self.dither() class OutlineOfVideo(Scene): @@ -280,7 +280,7 @@ class OutlineOfVideo(Scene): [texts[3]] ] for group in groups: - self.animate(*[ + self.play(*[ DelayByOrder(FadeIn(element)) for element in group ]) @@ -309,7 +309,7 @@ class OutlineOfVideo(Scene): # # div_sum = divergent_sum().scale(0.5).shift(3*UP) # # self.add(div_sum) -# # self.animate( +# # self.play( # # ApplyMethod(div_sum.replace, equation), # # FadeIn(line_one_first), # # FadeIn(line_one_last) @@ -333,9 +333,9 @@ class OutlineOfVideo(Scene): # define_parts[1].highlight("skyblue") # self.add(sum_mob) -# self.animate(FadeIn(discover)) +# self.play(FadeIn(discover)) # self.dither() -# self.animate(FadeIn(CompoundMobject(*define_parts))) +# self.play(FadeIn(CompoundMobject(*define_parts))) # self.dither() class YouAsMathematician(Scene): @@ -359,16 +359,16 @@ class YouAsMathematician(Scene): for x in LEFT, RIGHT ] self.add(you, explanation) - self.animate( + self.play( ShowCreation(arrow), BlinkPiCreature(you) ) self.dither() - self.animate(ShowCreation(bubble)) + self.play(ShowCreation(bubble)) for part in equation_parts: - self.animate(DelayByOrder(FadeIn(part)), run_time = 0.5) + self.play(DelayByOrder(FadeIn(part)), run_time = 0.5) self.dither() - self.animate( + self.play( BlinkPiCreature(you), FadeOut(explanation), FadeOut(arrow) @@ -376,19 +376,19 @@ class YouAsMathematician(Scene): self.remove(bubble, *equation_parts) self.disapproving_friend() self.add(bubble, equation) - self.animate(Transform(equation, CompoundMobject(*dot_pair))) + self.play(Transform(equation, CompoundMobject(*dot_pair))) self.remove(equation) self.add(*dot_pair) two_arrows = [ Arrow(x, direction = x).shift(UP).nudge() for x in LEFT, RIGHT ] - self.animate(*[ShowCreation(a) for a in two_arrows]) - self.animate(BlinkPiCreature(you)) + self.play(*[ShowCreation(a) for a in two_arrows]) + self.play(BlinkPiCreature(you)) self.remove(*dot_pair+two_arrows) everything = CompoundMobject(*self.mobjects) self.clear() - self.animate( + self.play( ApplyPointwiseFunction( lambda p : 3*SPACE_WIDTH*p/np.linalg.norm(p), everything @@ -408,7 +408,7 @@ class YouAsMathematician(Scene): bubble.content.sort_points(lambda p : np.dot(p, DOWN+RIGHT)) self.add(friend, bubble) - self.animate(DelayByOrder(FadeIn(bubble.content))) + self.play(DelayByOrder(FadeIn(bubble.content))) self.dither() self.remove(friend, bubble, bubble.content) @@ -423,7 +423,7 @@ class DotsGettingCloser(Scene): self.dither() for x in range(10): distance = min(dots[1].points[:,0])-max(dots[0].points[:,0]) - self.animate(ApplyMethod(dots[0].shift, 0.5*distance*RIGHT)) + self.play(ApplyMethod(dots[0].shift, 0.5*distance*RIGHT)) class ZoomInOnInterval(Scene): @@ -441,10 +441,10 @@ class ZoomInOnInterval(Scene): self.add(number_line) self.dither() - self.animate(Transform(number_line, new_line)) + self.play(Transform(number_line, new_line)) self.clear() squish = lambda p : (p[0], 0, 0) - self.animate( + self.play( ApplyMethod(new_line.apply_function, squish), ApplyMethod( interval[0].apply_function, squish, @@ -476,7 +476,7 @@ class DanceDotOnInterval(Scene): conv_sum = tex_mobject(sum_terms, size = "\\large").split() self.add(interval) - self.animate(*[ + self.play(*[ ApplyMethod(dot.shift, DOWN) for dot in dots ]) @@ -486,7 +486,7 @@ class DanceDotOnInterval(Scene): start = dots[0].get_center() line = Line(start, start + shift_val*RIGHT) line.highlight(color_range.next()) - self.animate( + self.play( ApplyMethod(dots[0].shift, shift_val), ShowCreation(line) ) @@ -500,7 +500,7 @@ class DanceDotOnInterval(Scene): line.get_center()+2*DOWN, tail = num.get_center()+0.5*num.get_height()*UP ) - self.animate( + self.play( ApplyMethod(line.shift, 2*DOWN), FadeIn(num), FadeIn(arrow), @@ -517,7 +517,7 @@ class DanceDotOnInterval(Scene): for x in range(0, len(partial_sum_parts), 4): partial_sum_parts[x+2].highlight("yellow") - self.animate(*[ + self.play(*[ FadeIn(partial_sum_parts[y]) for y in range(x, x+4) ]) @@ -541,7 +541,7 @@ class OrganizePartialSums(Scene): self.add(*partial_sum_parts) self.dither() - self.animate(*[ + self.play(*[ ClockwiseTransform(*pair) for pair in zip(pure_sums, new_pure_sums) ]+[ @@ -557,9 +557,9 @@ class OrganizePartialSums(Scene): infinite_sum.scale(1.5/1.25) infinite_sum.to_corner(DOWN+LEFT).shift(2*RIGHT) - self.animate(ShowCreation(dots)) + self.play(ShowCreation(dots)) self.dither() - self.animate(FadeIn(CompoundMobject(down_arrow, infinite_sum))) + self.play(FadeIn(CompoundMobject(down_arrow, infinite_sum))) self.dither() class SeeNumbersApproachOne(Scene): @@ -580,7 +580,7 @@ class SeeNumbersApproachOne(Scene): ]) self.add(interval) - self.animate( + self.play( ShowCreation(arrow), ShowCreation(dots), run_time = 2.0 @@ -598,7 +598,7 @@ class OneAndInfiniteSumAreTheSameThing(Scene): self.dither() self.add(inf_sum.shift(RIGHT)) self.dither() - self.animate( + self.play( ApplyMethod(one.shift, RIGHT), ApplyMethod(inf_sum.shift, LEFT), CounterclockwiseTransform(point, equals) @@ -623,7 +623,7 @@ class HowDoYouDefineInfiniteSums(Scene): for mob in text[:-1]: self.add(mob) self.dither(0.1) - self.animate(BlinkPiCreature(you)) + self.play(BlinkPiCreature(you)) self.dither() self.add(text[-1]) self.dither() @@ -650,8 +650,8 @@ class LessAboutNewThoughts(Scene): kwargs = {"run_time" : 0.25} self.add(*words) self.dither() - self.animate(ShowCreation(gen_cross, **kwargs)) - self.animate(ShowCreation(new_cross, **kwargs)) + self.play(ShowCreation(gen_cross, **kwargs)) + self.play(ShowCreation(new_cross, **kwargs)) self.dither() self.add(disecting) self.dither(0.5) @@ -679,9 +679,9 @@ class ListOfPartialSums(Scene): display_numbers = False, run_time = 1.0 ) - self.animate(ShowCreation(dots)) + self.play(ShowCreation(dots)) self.dither() - self.animate( + self.play( FadeIn(CompoundMobject(*equals)), *[ Transform(deepcopy(number), finite_sum) @@ -689,7 +689,7 @@ class ListOfPartialSums(Scene): ] ) self.dither() - self.animate(*[ + self.play(*[ ApplyMethod(s.highlight, "yellow", alpha_func = there_and_back) for s in sums ]) @@ -720,7 +720,7 @@ class ShowDecreasingDistance(Scene): self.add(dots.split()[0]) self.add(number_line, *lines) self.dither() - self.animate( + self.play( ApplyMethod(vert_line0.shift, RIGHT), Transform( horiz_line, @@ -753,19 +753,19 @@ class CircleZoomInOnOne(Scene): arrow = Arrow(2*RIGHT, direction = 1.5*(DOWN+RIGHT)).nudge() self.add(number_line, dots) - self.animate( + self.play( Transform(circle, Point(2*RIGHT).highlight("white")), run_time = 5.0 ) - self.animate(*[ + self.play(*[ DelayByOrder(FadeIn(mob)) for mob in arrow, curr_num ]) self.dither() for num in numbers[1:] + [text]: curr_num.points = np.array(list(reversed(curr_num.points))) - self.animate( + self.play( ShowCreation( curr_num, alpha_func = lambda t : smooth(1-t) @@ -782,12 +782,12 @@ class ZoomInOnOne(Scene): number_line = NumberLine(interval_size = 1, radius = SPACE_WIDTH+2) number_line.filter_out(lambda (x, y, z):abs(y)>0.1) nl_with_nums = deepcopy(number_line).add_numbers() - self.animate(ApplyMethod(nl_with_nums.shift, 2*LEFT)) + self.play(ApplyMethod(nl_with_nums.shift, 2*LEFT)) zero, one, two = [ tex_mobject(str(n)).scale(0.5).shift(0.4*DOWN+2*(-1+n)*RIGHT) for n in 0, 1, 2 ] - self.animate( + self.play( FadeOut(nl_with_nums), *[Animation(mob) for mob in zero, one, two, number_line] ) @@ -817,7 +817,7 @@ class ZoomInOnOne(Scene): for x in range(num_levels) ] kwargs = {"alpha_func" : None} - self.animate(*[ + self.play(*[ ApplyMethod(number_lines[x].scale, scale_val, **kwargs) for x in range(1, num_levels) ]+[ @@ -853,7 +853,7 @@ class DefineInfiniteSum(Scene): self.add(expression) self.dither() - self.animate(ApplyFunction( + self.play(ApplyFunction( lambda mob : mob.scale(0.5).to_corner(UP+LEFT, buff = buff), expression )) @@ -863,7 +863,7 @@ class DefineInfiniteSum(Scene): Line(SPACE_WIDTH*LEFT+bottom, side+bottom), Line(SPACE_HEIGHT*UP+side, side+bottom) ] - self.animate(*[ + self.play(*[ ShowCreation(line.highlight("white")) for line in lines ]) @@ -893,7 +893,7 @@ class DefineInfiniteSum(Scene): self.dither() esses = np.array(terms)[range(0, len(terms), 3)] other_terms = filter(lambda m : m not in esses, terms) - self.animate(*[ + self.play(*[ ApplyMethod(ess.highlight, "yellow") for ess in esses ]) @@ -903,7 +903,7 @@ class DefineInfiniteSum(Scene): s.scale(1.0/(n+1)) s.shift(ex_point-RIGHT*2.0/2**n) return s - self.animate(*[ + self.play(*[ FadeOut(term) for term in other_terms ]+[ @@ -920,7 +920,7 @@ class DefineInfiniteSum(Scene): for y in [-1, -0.01, 1, 0.01] for x in [ex_point+y*RIGHT] ] - self.animate(*[ + self.play(*[ Transform(lines[x], lines[x+1], run_time = 3.0) for x in 0, 2 ]) @@ -944,8 +944,8 @@ class YouJustInventedSomeMath(Scene): for mob in text: self.add(mob) self.dither(0.2) - self.animate(WaveArm(you)) - self.animate(BlinkPiCreature(you)) + self.play(WaveArm(you)) + self.play(BlinkPiCreature(you)) @@ -968,7 +968,7 @@ class SeekMoreGeneralTruths(Scene): for qsum in sums.split(): qsum.sort_points(lambda p : np.dot(p, DOWN+RIGHT)) - self.animate(DelayByOrder(FadeIn(qsum))) + self.play(DelayByOrder(FadeIn(qsum))) self.dither(0.5) self.dither() @@ -1036,7 +1036,7 @@ class ChopIntervalInProportions(Scene): new_term_to_replace = deepcopy(term_to_replace) new_term_to_replace.center().shift(last+UP+0.3*LEFT) left_paren.center().shift(last+1.1*UP) - self.animate( + self.play( FadeIn(lt[1]), FadeIn(rt[0]), Transform( @@ -1049,7 +1049,7 @@ class ChopIntervalInProportions(Scene): *additional_anims ) self.dither() - self.animate( + self.play( Transform( term_to_replace, CompoundMobject(lt[0], rt[1]) @@ -1059,7 +1059,7 @@ class ChopIntervalInProportions(Scene): ) self.remove(left_paren, right_paren) else: - self.animate( + self.play( FadeIn(lt[1]), FadeIn(rt[0]), Transform( @@ -1076,7 +1076,7 @@ class ChopIntervalInProportions(Scene): lt, rt = CompoundMobject(*lt), CompoundMobject(*rt) self.add(lt, rt) else: - self.animate( + self.play( Transform( brace_to_replace.repeat(2), CompoundMobject(*braces) @@ -1090,7 +1090,7 @@ class ChopIntervalInProportions(Scene): self.remove(brace_to_replace, term_to_replace) self.add(lt, rt, *braces) else: - self.animate(*[ + self.play(*[ FadeIn(mob) for mob in braces + [lt, rt] ] + additional_anims) @@ -1104,7 +1104,7 @@ class ChopIntervalInProportions(Scene): split_100.to_edge(RIGHT) split_100.sort_points() right_terms[-1].sort_points() - self.animate(Transform( + self.play(Transform( right_terms[-1], split_100 )) self.dither() @@ -1225,13 +1225,13 @@ class PlugNumbersIntoRightside(Scene): self.add(lhs, *rhs) self.dither() - self.animate(FadeIn(right_words)) + self.play(FadeIn(right_words)) curr = rhs[1] for num, count in zip(nums, it.count()): - self.animate(CounterclockwiseTransform(curr, num)) + self.play(CounterclockwiseTransform(curr, num)) self.dither() if count == 2: - self.animate(FadeIn(left_words)) + self.play(FadeIn(left_words)) class PlugInNegativeOne(RearrangeEquation): @@ -1327,10 +1327,10 @@ class ListPartialDivergentSums(Scene): arrow = Arrow(3*DOWN+2*LEFT, direction = DOWN, length = 6) for x in range(0, len(terms), 2): - self.animate(FadeIn(terms[x]), FadeIn(terms[x+1])) - self.animate(FadeIn(words), ShowCreation(arrow)) + self.play(FadeIn(terms[x]), FadeIn(terms[x+1])) + self.play(FadeIn(words), ShowCreation(arrow)) for x in range(0, len(terms), 2): - self.animate( + self.play( ApplyMethod(terms[x].highlight, "green"), run_time = 0.1 ) @@ -1345,8 +1345,8 @@ class NotARobot(Scene): low_words.shift(1.5*DOWN) self.add(you) - self.animate(ShimmerIn(top_words)) - self.animate(ShimmerIn(low_words)) + self.play(ShimmerIn(top_words)) + self.play(ShimmerIn(low_words)) class SumPowersOfTwoAnimation(Scene): @@ -1412,7 +1412,7 @@ class SumPowersOfTwoAnimation(Scene): new_top_sum_end = new_top_sum[-1] self.dither() - self.animate(*[ + self.play(*[ FadeIn(mob) for mob in [ new_dots, @@ -1423,7 +1423,7 @@ class SumPowersOfTwoAnimation(Scene): ] ]) self.dither() - self.animate( + self.play( Transform(topbrace, new_topbrace), Transform(alt_topbrace, new_topbrace), Transform(bottombrace, new_bottombrace), @@ -1463,11 +1463,11 @@ class PretendTheyDoApproachNegativeOne(RearrangeEquation): for column in columns: column.shift(shift_val) shift_val = shift_val + (column.get_width()+0.2)*RIGHT - self.animate(ShimmerIn(columns[0])) + self.play(ShimmerIn(columns[0])) self.dither() self.add(columns[1]) self.dither() - self.animate( + self.play( DelayByOrder(Transform(deepcopy(columns[0]), columns[-1])), FadeIn(columns[2]) ) @@ -1488,16 +1488,16 @@ class DistanceBetweenRationalNumbers(Scene): text = text_mobject("How we define distance between rational numbers") text.to_edge(UP) self.add(text, *nums) - self.animate(*[ShowCreation(arrow) for arrow in arrows]) - self.animate(ShimmerIn(dist)) + self.play(*[ShowCreation(arrow) for arrow in arrows]) + self.play(ShimmerIn(dist)) self.dither() class NotTheOnlyWayToOrganize(Scene): def construct(self): - self.animate(ShowCreation(NumberLine().add_numbers())) + self.play(ShowCreation(NumberLine().add_numbers())) self.dither() words = "Is there any other reasonable way to organize numbers?" - self.animate(FadeIn(text_mobject(words).shift(2*UP))) + self.play(FadeIn(text_mobject(words).shift(2*UP))) self.dither() class DistanceIsAFunction(Scene): @@ -1563,11 +1563,11 @@ class DistanceIsAFunction(Scene): kwargs = {"run_time" : 0.5} for mobs in example_mobs: if previous: - self.animate(*[ + self.play(*[ DelayByOrder(Transform(prev, mob, **kwargs)) for prev, mob in zip(previous, mobs)[:-1] ]) - self.animate(DelayByOrder(Transform( + self.play(DelayByOrder(Transform( previous[-1], mobs[-1], **kwargs ))) self.remove(*previous) @@ -1595,7 +1595,7 @@ class ShiftInvarianceNumberLine(Scene): self.add(number_line, topbrace, dist0, footnote) self.dither() self.remove(dist0) - self.animate( + self.play( ApplyMethod(topbrace.shift, 2*RIGHT), *[ Transform(*pair) @@ -1624,9 +1624,9 @@ class NameShiftInvarianceProperty(Scene): mob.highlight("yellow") self.add(prop) - self.animate(ShimmerIn(label), ShimmerIn(u_brace)) + self.play(ShimmerIn(label), ShimmerIn(u_brace)) self.dither() - self.animate(ShimmerIn(name)) + self.play(ShimmerIn(name)) self.dither() @@ -1657,15 +1657,15 @@ class TriangleInequality(Scene): ] for symbol, loc in zip(symbols, locations): self.add(tex_mobject(symbol).shift(loc)) - self.animate(ShowCreation(ac_line), FadeIn(ac_copy)) + self.play(ShowCreation(ac_line), FadeIn(ac_copy)) self.dither() - self.animate(*[ + self.play(*[ ShowCreation(line) for line in ab_line, bc_line ]+[ FadeIn(dist) for dist in ab_copy, bc_copy ]) self.dither() - self.animate(*[ + self.play(*[ Transform(*pair) for pair in zip(all_copies, all_dists) ]+[ @@ -1696,7 +1696,7 @@ class StruggleToFindFrameOfMind(Scene): bubble.add_content(mob) for first, second in [(curr, questions), (questions, mob)]: copy = deepcopy(first) - self.animate(DelayByOrder(Transform( + self.play(DelayByOrder(Transform( copy, second, **kwargs ))) self.remove(copy) @@ -1732,7 +1732,7 @@ class RoomsAndSubrooms(Scene): for group in rectangle_groups: mob = CompoundMobject(*group) mob.sort_points(np.linalg.norm) - self.animate(ShowCreation(mob)) + self.play(ShowCreation(mob)) self.dither() @@ -1771,7 +1771,7 @@ class RoomsAndSubroomsWithNumbers(Scene): LEFT*0.05*n+\ (0.4*RIGHT if n == 0 else ORIGIN) #Stupid ) - self.animate(FadeIn(num, run_time = 0.5)) + self.play(FadeIn(num, run_time = 0.5)) nums.append(num) return zero, nums @@ -1790,7 +1790,7 @@ class RoomsAndSubroomsWithNumbers(Scene): rect.highlight(colors[n]) rectangles.append(rect) for rect in rectangles: - self.animate(ShowCreation(rect)) + self.play(ShowCreation(rect)) self.dither() return rectangles @@ -1810,7 +1810,7 @@ class RoomsAndSubroomsWithNumbers(Scene): ) clusters.append(cluster) for rect in cluster[1:]: - self.animate(FadeIn(rect, run_time = 0.6**(count-1))) + self.play(FadeIn(rect, run_time = 0.6**(count-1))) return clusters def adjust_power_mobs(self, zero, power_mobs, small_rects): @@ -1822,7 +1822,7 @@ class RoomsAndSubroomsWithNumbers(Scene): new_power_mobs[-1].shift(DOWN) dots = tex_mobject("\\vdots") dots.scale(0.5).shift(new_zero.get_center()+0.5*DOWN) - self.animate( + self.play( Transform(zero, new_zero), FadeIn(dots), *[ @@ -1847,7 +1847,7 @@ class RoomsAndSubroomsWithNumbers(Scene): self.center_in_closest_rect(mob, small_rects) mob.shift(UP) return mob - self.animate(*[ + self.play(*[ ApplyFunction(transform, mob) for mob in zero_copy, power_mob_copy ]) @@ -1855,7 +1855,7 @@ class RoomsAndSubroomsWithNumbers(Scene): for n in range(power+1, 2*power): left_mob = num_mobs[n-power] shift_val = left_mob.get_center()-last_left_mob.get_center() - self.animate(*[ + self.play(*[ ApplyMethod(mob.shift, shift_val) for mob in zero_copy, power_mob_copy ]) @@ -1867,7 +1867,7 @@ class RoomsAndSubroomsWithNumbers(Scene): num_mobs[n].shift(power_mob_copy.get_center()+DOWN) self.center_in_closest_rect(num_mobs[n], small_rects) point = Point(power_mob_copy.get_center()) - self.animate(Transform(point, num_mobs[n])) + self.play(Transform(point, num_mobs[n])) self.remove(point) self.add(num_mobs[n]) last_left_mob = left_mob @@ -1885,7 +1885,7 @@ class RoomsAndSubroomsWithNumbers(Scene): neg_one = tex_mobject("-1").scale(0.5) shift_val = num_mobs[15].get_center()-neg_one.get_center() neg_one.shift(UP) - self.animate(ApplyMethod(neg_one.shift, shift_val)) + self.play(ApplyMethod(neg_one.shift, shift_val)) def show_distances(self, num_mobs, rect_clusters): self.remove(*[r for c in rect_clusters for r in c]) @@ -1912,7 +1912,7 @@ class RoomsAndSubroomsWithNumbers(Scene): for pair in sample(pairs, min(10, len(pairs))): for index in pair: num_mobs[index].highlight("green") - self.animate(*[ + self.play(*[ ApplyMethod( num_mobs[index].rotate_in_place, np.pi/10, alpha_func = wiggle @@ -1967,7 +1967,7 @@ class DeduceWhereNegativeOneFalls(Scene): for new_arg, old_arg in zip(new_args, last_args): new_arg.shift(old_arg.get_center()) if last_args != [arg0, arg1]: - self.animate(*[ + self.play(*[ DelayByOrder(Transform(*pair, run_time = 0.5*rest_time)) for pair in zip(last_args, new_args) ]) @@ -2003,7 +2003,7 @@ class OtherRationalNumbers(Scene): ] for pair, locus in zip(pairs, locii): fraction = tex_mobject("\\frac{%d}{%d}"%pair).shift(locus) - self.animate(ShimmerIn(fraction)) + self.play(ShimmerIn(fraction)) self.dither() class PAdicMetric(Scene): @@ -2022,18 +2022,18 @@ class PAdicMetric(Scene): for prime, count in zip(primes, it.count()): prime.scale(1.0).highlight(colors.next()) prime.shift(center_of_mass([p_str.get_top(), p_str.get_center()])) - self.animate(DelayByOrder(Transform(curr, prime))) + self.play(DelayByOrder(Transform(curr, prime))) self.dither() if count == 2: self.spill(CompoundMobject(curr, text), arrow, new_numbers) self.remove(curr) curr = prime - self.animate(DelayByOrder(Transform(curr, p_str))) + self.play(DelayByOrder(Transform(curr, p_str))) self.dither() def spill(self, start, arrow, end): start.sort_points(lambda p : p[1]) - self.animate( + self.play( ShowCreation( arrow, alpha_func = squish_alpha_func(smooth, 0.5, 1.0) @@ -2043,7 +2043,7 @@ class PAdicMetric(Scene): Point(arrow.points[0]).highlight("white") )) ) - self.animate(ShimmerIn(end)) + self.play(ShimmerIn(end)) class FuzzyDiscoveryToNewMath(Scene): @@ -2098,12 +2098,12 @@ class FuzzyDiscoveryToNewMath(Scene): midpoints.append(count*UP) self.add(fuzzy, lines) - self.animate(*map(ShimmerIn, fuzzy_discoveries)) + self.play(*map(ShimmerIn, fuzzy_discoveries)) self.dither() - self.animate(DelayByOrder(Transform( + self.play(DelayByOrder(Transform( deepcopy(fuzzy), new_math ))) - self.animate(*[ + self.play(*[ DelayByOrder(Transform(deepcopy(disc), math)) for disc, math in zip(fuzzy_discoveries, new_maths) ]) @@ -2129,7 +2129,7 @@ class DiscoveryAndInvention(Scene): nrd.get_bottom(), tail = discovery.get_top() ) - self.animate( + self.play( FadeIn(nrd), ShowCreation(arrow) ) @@ -2139,14 +2139,14 @@ class DiscoveryAndInvention(Scene): invention.get_top(), tail = nrd.get_bottom() ) - self.animate(ShowCreation(arrow)) + self.play(ShowCreation(arrow)) arrows.append(arrow) self.dither() arrow = Arrow( rt.get_top(), tail = invention.get_bottom() ) - self.animate( + self.play( FadeIn(rt), ShowCreation(arrow) ) @@ -2156,12 +2156,12 @@ class DiscoveryAndInvention(Scene): discovery.get_bottom(), tail = rt.get_top() ) - self.animate(ShowCreation(arrow)) + self.play(ShowCreation(arrow)) self.dither() arrows.append(arrow) for color in Color("yellow").range_to("red", 4): for arrow in arrows: - self.animate( + self.play( ShowCreation(deepcopy(arrow).highlight(color)), run_time = 0.25 ) diff --git a/scripts/moser_main.py b/scripts/moser_main.py index f258d1cd..ffcca87e 100644 --- a/scripts/moser_main.py +++ b/scripts/moser_main.py @@ -133,7 +133,7 @@ class CountSections(CircleScene): def __init__(self, *args, **kwargs): CircleScene.__init__(self, *args, **kwargs) self.remove(*self.lines) - self.animate(*[ + self.play(*[ Transform(Dot(points[i]),Line(points[i], points[1-i])) for points in it.combinations(self.points, 2) for i in (0, 1) @@ -219,13 +219,13 @@ class HardProblemsSimplerQuestions(Scene): for c in [left_center, right_center] ] self.add(fermat["n"]) - self.animate(*[ + self.play(*[ Transform(deepcopy(fermat["n"]), f_copy) for f_copy in copies ]) self.remove(*self.mobjects) self.add(fermat["n"]) - self.animate(*[ + self.play(*[ CounterclockwiseTransform(mobs[0], mobs[1]) for f_copy, sym in zip(copies, ["3", "2"]) for mobs in zip(f_copy.split(), fermat[sym].split()) @@ -257,7 +257,7 @@ class HardProblemsSimplerQuestions(Scene): mob.scale(0.5).shift(left_center + (0, 2, 0)) self.add(circle_grid, other_grid) - self.animate( + self.play( FadeIn(fermat2_jargon), FadeIn(fermat3_jargon), CounterclockwiseTransform(start_line, end_line), @@ -266,7 +266,7 @@ class HardProblemsSimplerQuestions(Scene): self.dither() all_mobjects = CompoundMobject(*self.mobjects) self.remove(*self.mobjects) - self.animate( + self.play( Transform( all_mobjects, Point((SPACE_WIDTH, 0, 0)) @@ -301,7 +301,7 @@ class CountLines(CircleScene): ] self.add(text) self.dither() - self.animate(*[ + self.play(*[ Transform(line1, line2, run_time = 2) for line1, line2 in zip(self.lines, new_lines) ]) @@ -314,7 +314,7 @@ class CountLines(CircleScene): anims.append(Transform(mob, answer)) else: anims.append(FadeOut(mob)) - self.animate(*anims, run_time = 1) + self.play(*anims, run_time = 1) class CountIntersectionPoints(CircleScene): def __init__(self, radians, *args, **kwargs): @@ -347,7 +347,7 @@ class CountIntersectionPoints(CircleScene): else: anims.append(FadeOut(mob)) anims.append(Animation(formula)) - self.animate(*anims, run_time = 1) + self.play(*anims, run_time = 1) class NonGeneralPosition(CircleScene): args_list = [] @@ -383,7 +383,7 @@ class NonGeneralPosition(CircleScene): self.dither(2) self.remove(text, arrow) self.reset_background() - self.animate(*[ + self.play(*[ Transform(mob1, mob2, run_time = DEFAULT_ANIMATION_RUN_TIME) for mob1, mob2 in zip(self.mobjects, new_self.mobjects) ]) @@ -430,12 +430,12 @@ class GeneralPositionRule(Scene): for i, j in pairs for line in [Line(cs.points[i], cs.points[j])] ] - self.animate(*[ + self.play(*[ ShowCreation(line, run_time = 1.0) for line in intersecting_lines ]) if first_time: - self.animate(Transform( + self.play(Transform( CompoundMobject(*intersecting_lines), words_mob )) @@ -465,18 +465,18 @@ class LineCorrespondsWithPair(CircleScene): self.dots.remove(dot0) self.dots.remove(dot1) self.dither() - self.animate(*[ + self.play(*[ ApplyMethod(mob.fade, 0.2) for mob in self.lines + self.dots ]) - self.animate(*[ + self.play(*[ Transform( dot, Dot(dot.get_center(), 3*dot.radius), alpha_func = there_and_back ) for dot in (dot0, dot1) ]) - self.animate(Transform(line, dot0)) + self.play(Transform(line, dot0)) class IllustrateNChooseK(Scene): args_list = [ @@ -550,7 +550,7 @@ class IllustrateNChooseK(Scene): self.remove(count_mob) self.remove(tuple_copy) self.add(count_mob) - self.animate(FadeIn(CompoundMobject(form1, form2, pronunciation))) + self.play(FadeIn(CompoundMobject(form1, form2, pronunciation))) class IntersectionPointCorrespondances(CircleScene): args_list = [ @@ -602,16 +602,16 @@ class IntersectionPointCorrespondances(CircleScene): fade_outs.append(FadeOut(mob, alpha_func = not_quite_there)) self.add(intersection_dot_arrow) - self.animate(Highlight(intersection_dot)) + self.play(Highlight(intersection_dot)) self.remove(intersection_dot_arrow) - self.animate(*fade_outs) + self.play(*fade_outs) self.dither() self.add(line_statement) - self.animate(*line_highlights) + self.play(*line_highlights) self.remove(line_statement) self.dither() self.add(dots_statement, *dot_pointers) - self.animate(*dot_highlights) + self.play(*dot_highlights) self.remove(dots_statement, *dot_pointers) class LinesIntersectOutside(CircleScene): @@ -637,11 +637,11 @@ class LinesIntersectOutside(CircleScene): self.lines[pairs.index((indices[p0], indices[p1]))] for p0, p1 in [(0, 1), (2, 3)] ] - self.animate(*[ + self.play(*[ FadeOut(mob, alpha_func = not_quite_there) for mob in self.mobjects if mob not in lines_to_save ]) - self.animate(*[ + self.play(*[ Transform( Line(self.points[indices[p0]], self.points[indices[p1]]), Line(self.points[indices[p0]], intersection_point)) @@ -665,7 +665,7 @@ class QuadrupletsToIntersections(CircleScene): dot_quad.highlight() self.add(dot_quad) self.dither(frame_time / 3) - self.animate(Transform( + self.play(Transform( dot_quad, intersection_dot, run_time = 3*frame_time/2 @@ -684,19 +684,19 @@ class GraphsAndEulersFormulaJoke(Scene): ) graph.filter_out(lambda (x, y, z) : abs(y) > SPACE_HEIGHT) self.add(axes) - self.animate(ShowCreation(graph), run_time = 1.0) + self.play(ShowCreation(graph), run_time = 1.0) eulers = tex_mobject("e^{\pi i} = -1").shift((0, 3, 0)) - self.animate(CounterclockwiseTransform( + self.play(CounterclockwiseTransform( deepcopy(graph), eulers )) self.dither() self.remove(*self.mobjects) self.add(eulers) - self.animate(CounterclockwiseTransform( + self.play(CounterclockwiseTransform( CompoundMobject(axes, graph), Point((-SPACE_WIDTH, SPACE_HEIGHT, 0)) )) - self.animate(CounterclockwiseTransform( + self.play(CounterclockwiseTransform( eulers, Point((SPACE_WIDTH, SPACE_HEIGHT, 0)) )) @@ -710,16 +710,16 @@ class DefiningGraph(GraphScene): dots, lines = self.vertices, self.edges self.remove(*dots + lines) all_dots = CompoundMobject(*dots) - self.animate(ShowCreation(all_dots)) + self.play(ShowCreation(all_dots)) self.remove(all_dots) self.add(*dots) - self.animate(FadeIn(vertices_word)) + self.play(FadeIn(vertices_word)) self.dither() self.remove(vertices_word) - self.animate(*[ + self.play(*[ ShowCreation(line) for line in lines ]) - self.animate(FadeIn(edges_word)) + self.play(FadeIn(edges_word)) #Move to new graph # new_graph = deepcopy(self.graph) @@ -728,7 +728,7 @@ class DefiningGraph(GraphScene): # for v in new_graph.vertices # ] # new_graph_scene = GraphScene(new_graph) - # self.animate(*[ + # self.play(*[ # Transform(m[0], m[1]) # for m in zip(self.mobjects, new_graph_scene.mobjects) # ], run_time = 7.0) @@ -741,7 +741,7 @@ class IntersectCubeGraphEdges(GraphScene): def __init__(self, *args, **kwargs): GraphScene.__init__(self, CubeGraph(), *args, **kwargs) self.remove(self.edges[0], self.edges[4]) - self.animate(*[ + self.play(*[ Transform( Line(self.points[i], self.points[j]), CurvedLine(self.points[i], self.points[j]), @@ -772,7 +772,7 @@ class DoubledEdges(GraphScene): Transform(backwards, outward, **kwargs), ] outward_curved_lines.append(outward) - self.animate(*anims) + self.play(*anims) self.dither() self.remove(*outward_curved_lines) @@ -846,12 +846,12 @@ class CannotDirectlyApplyEulerToMoser(CircleScene): yellow_lines = CompoundMobject(*[ l.highlight("yellow") for l in deepcopy(self.lines) ]) - self.animate(*[ + self.play(*[ ShowCreation(dot) for dot in yellow_dots ], run_time = 1.0) self.dither() self.remove(*yellow_dots) - self.animate(ShowCreation(yellow_lines)) + self.play(ShowCreation(yellow_lines)) self.dither() self.remove(yellow_lines) cannot_intersect = text_mobject(r""" @@ -868,7 +868,7 @@ class CannotDirectlyApplyEulerToMoser(CircleScene): for mob in self.mobjects: mob.fade(1/0.3) self.generate_intersection_dots() - self.animate(FadeIn(intersection_count), *[ + self.play(FadeIn(intersection_count), *[ ShowCreation(dot) for dot in self.intersection_dots ]) @@ -899,7 +899,7 @@ class ShowMoserGraphLines(CircleScene): compound = CompoundMobject(*mobs) if mobs in (self.dots, self.intersection_dots): self.remove(*mobs) - self.animate(CounterclockwiseTransform( + self.play(CounterclockwiseTransform( compound, deepcopy(compound).scale(1.05), alpha_func = there_and_back, @@ -907,12 +907,12 @@ class ShowMoserGraphLines(CircleScene): )) else: compound.highlight("yellow") - self.animate(ShowCreation(compound)) + self.play(ShowCreation(compound)) self.remove(compound) if mobs == self.intersection_dots: self.remove(n, plus_n_choose_4) - self.animate(*[ + self.play(*[ Transform(line, small_line, run_time = 3.0) for line, small_line in zip(self.lines, small_lines) ]) @@ -920,16 +920,16 @@ class ShowMoserGraphLines(CircleScene): line.highlight("yellow") for line in small_lines ]) self.add(plus_2_n_choose_4) - self.animate(ShowCreation(yellow_lines)) + self.play(ShowCreation(yellow_lines)) self.dither() self.remove(yellow_lines) self.chop_circle_at_points() - self.animate(*[ + self.play(*[ Transform(p, sp, run_time = 3.0) for p, sp in zip(self.circle_pieces, self.smaller_circle_pieces) ]) self.add(plus_n) - self.animate(ShowCreation(CompoundMobject(*[ + self.play(ShowCreation(CompoundMobject(*[ mob.highlight("yellow") for mob in self.circle_pieces ]))) @@ -961,7 +961,7 @@ class HowIntersectionChopsLine(CircleScene): for p0, p1 in [(0, 2), (1, 3)] ]) self.add(*lines) - self.animate(*[ + self.play(*[ FadeOut(mob) for mob in self.mobjects if mob not in lines @@ -973,7 +973,7 @@ class HowIntersectionChopsLine(CircleScene): Line(intersection_point, line.end) for line in lines ] - self.animate(*[ + self.play(*[ Transform( line, Line( @@ -986,7 +986,7 @@ class HowIntersectionChopsLine(CircleScene): for line, h in zip(lines, (-1, 1)) ]) self.remove(*lines) - self.animate(*[ + self.play(*[ Transform( line, deepcopy(line).scale(1.1).scale_in_place(1/1.1), @@ -1054,7 +1054,7 @@ class ApplyEulerToMoser(CircleScene): d[key].get_center() - main_center ) - self.animate(*[ + self.play(*[ CounterclockwiseTransform(d[1], d[2], run_time = 2.0) for d in [V, minus, E, plus, F, equals, two] ]) @@ -1069,7 +1069,7 @@ class ApplyEulerToMoser(CircleScene): F[1].highlight("white") E[1].highlight() self.remove(*self.lines + self.circle_pieces) - self.animate(*[ + self.play(*[ Transform( deepcopy(line), deepcopy(line).scale_in_place(0.5), @@ -1088,7 +1088,7 @@ class ApplyEulerToMoser(CircleScene): V[1].highlight() self.add(*self.dots + self.intersection_dots) self.remove(*self.lines + self.circle_pieces) - self.animate(*[ + self.play(*[ Transform( deepcopy(dot), deepcopy(dot).scale_in_place(1.4).highlight("yellow") @@ -1110,7 +1110,7 @@ class ApplyEulerToMoser(CircleScene): self.dither() self.add(*all_mobs) self.remove(*[d[1] for d in [V, minus, E, plus, F, equals, two]]) - self.animate( + self.play( Transform(V[2].repeat(2), CompoundMobject(n[3], minus1[3], nc4[3])), *[ Transform(d[2], d[3]) @@ -1119,7 +1119,7 @@ class ApplyEulerToMoser(CircleScene): ) self.dither() self.remove(*self.mobjects) - self.animate( + self.play( Transform(E[3], CompoundMobject( nc2[4], plus1[4], two1[4], nc41[4], plus2[4], n1[4] )), @@ -1140,7 +1140,7 @@ class ApplyEulerToMoser(CircleScene): ) self.dither() self.remove(*self.mobjects) - self.animate( + self.play( Transform( CompoundMobject(plus2[4], n1[4], minus[4], n[4]), Point((SPACE_WIDTH, SPACE_HEIGHT, 0)) @@ -1153,7 +1153,7 @@ class ApplyEulerToMoser(CircleScene): ) self.dither() self.remove(*self.mobjects) - self.animate( + self.play( Transform(nc41[5], nc4[6]), Transform(two1[5], Point(nc4[6].get_center())), *[ @@ -1163,7 +1163,7 @@ class ApplyEulerToMoser(CircleScene): ) self.dither() self.remove(*self.mobjects) - self.animate( + self.play( CounterclockwiseTransform(two[6], two[7]), CounterclockwiseTransform(plus[6], plus[7]), *[ @@ -1184,7 +1184,7 @@ class ApplyEulerToMoser(CircleScene): one = tex_mobject("1").shift(two.get_center()) two.highlight("red") self.add(two) - self.animate(CounterclockwiseTransform(two, one)) + self.play(CounterclockwiseTransform(two, one)) class FormulaRelatesToPowersOfTwo(Scene): def __init__(self, *args, **kwargs): @@ -1207,11 +1207,11 @@ class FormulaRelatesToPowersOfTwo(Scene): sums = everything[1::3] results = everything[2::3] self.add(*forms) - self.animate(*[ + self.play(*[ FadeIn(s) for s in sums ]) self.dither() - self.animate(*[ + self.play(*[ Transform(deepcopy(s), result) for s, result in zip(sums, results) ]) @@ -1225,7 +1225,7 @@ class FormulaRelatesToPowersOfTwo(Scene): self.dither() self.remove(*self.mobjects) self.add(*forms + sums + results) - self.animate(*[ + self.play(*[ CounterclockwiseTransform(result, pof2) for result, pof2 in zip(results, powers_of_two) ]) @@ -1245,7 +1245,7 @@ class DrawPascalsTriangle(PascalsTriangleScene): for k in range(1, n) ] starts.append(deepcopy(self.coords_to_mobs[n-1][n-1])) - self.animate(*[ + self.play(*[ Transform(starts[i], self.coords_to_mobs[n][i], run_time = 1.5, black_out_extra_points = False) for i in range(n+1) @@ -1276,7 +1276,7 @@ class PascalsTriangleWithNChooseK(PascalsTriangleScene): for i in [0, 1]: self.dither() self.remove(*self.mobjects) - self.animate(*[ + self.play(*[ CounterclockwiseTransform( deepcopy(mob_dicts[i][n][k]), mob_dicts[1-i][n][k] @@ -1305,7 +1305,7 @@ class PascalsTriangleNChooseKExample(PascalsTriangleScene): self.remove(*triangle_terms) self.add(*formula_terms) self.dither() - self.animate(* + self.play(* [ ShowCreation(mob) for mob in triangle_terms ]+[ @@ -1339,7 +1339,7 @@ class PascalsTriangleNChooseKExample(PascalsTriangleScene): if b < k: self.coords_to_mobs[n][b].highlight("green") self.remove(b_mob) - self.animate(*[ + self.play(*[ ApplyMethod(mob.fade, 0.2) for mob in triangle_terms if mob != self.coords_to_mobs[n][k] @@ -1384,13 +1384,13 @@ class PascalsTriangleSumRows(PascalsTriangleScene): powers_of_two.append(pof2) equalses.append(new_equals) powers_of_two_symbols.append(symbol) - self.animate(FadeIn(CompoundMobject(*pluses))) + self.play(FadeIn(CompoundMobject(*pluses))) run_time = 0.5 to_remove = [] for n in range(self.nrows): start = CompoundMobject(*[self.coords_to_mobs[n][k] for k in range(n+1)]) to_remove.append(start) - self.animate( + self.play( Transform(start, powers_of_two[n]), FadeIn(equalses[n]), run_time = run_time @@ -1399,7 +1399,7 @@ class PascalsTriangleSumRows(PascalsTriangleScene): self.remove(*to_remove) self.add(*powers_of_two) for n in range(self.nrows): - self.animate(CounterclockwiseTransform( + self.play(CounterclockwiseTransform( powers_of_two[n], powers_of_two_symbols[n], run_time = run_time )) @@ -1438,7 +1438,7 @@ class MoserSolutionInPascal(PascalsTriangleScene): target_terms.append(new_term) self.add(*terms) self.dither() - self.animate(* + self.play(* [ FadeIn(self.coords_to_n_choose_k[n0][k0]) for n0, k0 in self.coords @@ -1454,7 +1454,7 @@ class MoserSolutionInPascal(PascalsTriangleScene): (k, deepcopy(self.coords_to_mobs[n][k]).highlight(term_color)) for k in term_range ]) - self.animate(* + self.play(* [ CounterclockwiseTransform( self.coords_to_n_choose_k[n0][k0], @@ -1479,7 +1479,7 @@ class MoserSolutionInPascal(PascalsTriangleScene): self.coords_to_n_choose_k[n-1][k], ] self.add(self.coords_to_mobs[n][k]) - self.animate(Transform( + self.play(Transform( terms[k], CompoundMobject(*above_terms).highlight(term_color) )) @@ -1488,7 +1488,7 @@ class MoserSolutionInPascal(PascalsTriangleScene): terms_sum = tex_mobject(str(moser_function(n))) terms_sum.shift((SPACE_WIDTH-1, terms[0].get_center()[1], 0)) terms_sum.highlight(term_color) - self.animate(Transform(CompoundMobject(*terms), terms_sum)) + self.play(Transform(CompoundMobject(*terms), terms_sum)) class RotatingPolyhedra(Scene): args_list = [ @@ -1511,13 +1511,13 @@ class RotatingPolyhedra(Scene): ] curr_mob = polyhedra.pop() for mob in polyhedra: - self.animate(TransformAnimations( + self.play(TransformAnimations( Rotating(curr_mob, **rot_kwargs), Rotating(mob, **rot_kwargs) )) for m in polyhedra: m.rotate(rot_kwargs["radians"], rot_kwargs["axis"]) - self.animate(Rotating(curr_mob, **rot_kwargs)) + self.play(Rotating(curr_mob, **rot_kwargs)) class ExplainNChoose2Formula(Scene): args_list = [(7,2,6)] @@ -1545,8 +1545,8 @@ class ExplainNChoose2Formula(Scene): self.add(parens, n_mob) up_unit = np.array((0, height, 0)) - self.animate(ApplyMethod(nums_compound.shift, -(n-1)*up_unit)) - self.animate(ApplyMethod(nums_compound.shift, (n-a)*up_unit)) + self.play(ApplyMethod(nums_compound.shift, -(n-1)*up_unit)) + self.play(ApplyMethod(nums_compound.shift, (n-a)*up_unit)) self.remove(nums_compound) nums = nums_compound.split() a_mob = nums.pop(a-1) @@ -1555,23 +1555,23 @@ class ExplainNChoose2Formula(Scene): self.dither() right_shift = b_mob.get_center() - a_mob.get_center() right_shift[1] = 0 - self.animate( + self.play( ApplyMethod(nums_compound.shift, right_shift), FadeIn(n_minus_1) ) - self.animate(ApplyMethod(nums_compound.shift, (a-b)*up_unit)) + self.play(ApplyMethod(nums_compound.shift, (a-b)*up_unit)) self.remove(nums_compound) nums = nums_compound.split() b_mob = nums.pop(b-2 if a < b else b-1) self.add(b_mob) - self.animate(*[ + self.play(*[ CounterclockwiseTransform( mob, Point(mob.get_center()).highlight("black") ) for mob in nums ]) - self.animate(*[ + self.play(*[ ApplyMethod(mob.shift, (0, 1, 0)) for mob in parens, a_mob, b_mob ]) @@ -1581,7 +1581,7 @@ class ExplainNChoose2Formula(Scene): a_copy = deepcopy(a_mob).center().shift(b_center - (0, 2, 0)) b_copy = deepcopy(b_mob).center().shift(a_center - (0, 2, 0)) self.add(over_2, deepcopy(a_mob), deepcopy(b_mob)) - self.animate( + self.play( CounterclockwiseTransform(a_mob, a_copy), CounterclockwiseTransform(b_mob, b_copy), FadeIn(parens_copy), @@ -1619,7 +1619,7 @@ class ExplainNChoose4Formula(Scene): up_unit = np.array((0, height, 0)) for i in range(4): self.add(form_mobs[i]) - self.animate(ApplyMethod( + self.play(ApplyMethod( nums_compound.shift, (curr_num-quad[i])*up_unit)) self.remove(nums_compound) nums = nums_compound.split() @@ -1630,11 +1630,11 @@ class ExplainNChoose4Formula(Scene): if i < 3: right_shift = quad_mobs[i+1].get_center() - chosen.get_center() right_shift[1] = 0 - self.animate( + self.play( ApplyMethod(nums_compound.shift, right_shift) ) else: - self.animate(*[ + self.play(*[ CounterclockwiseTransform( mob, Point(mob.get_center()).highlight("black") @@ -1658,7 +1658,7 @@ class ExplainNChoose4Formula(Scene): for i in range(4) ] compound_quad = CompoundMobject(*quad_mobs) - self.animate(CounterclockwiseTransform( + self.play(CounterclockwiseTransform( compound_quad, CompoundMobject(*new_quad_mobs) )) @@ -1688,7 +1688,7 @@ class IntersectionChoppingExamples(Scene): self.add(tex_mobject(exp).shift((0, SPACE_HEIGHT-1, 0))) self.add(*lines) self.dither() - self.animate(*[ + self.play(*[ Transform(line, deepcopy(line).scale(1.2).scale_in_place(1/1.2)) for line in lines ]) diff --git a/scripts/music_and_measure.py b/scripts/music_and_measure.py index d2fe8e7b..fbd63a39 100644 --- a/scripts/music_and_measure.py +++ b/scripts/music_and_measure.py @@ -12,6 +12,7 @@ from constants import * from region import * from scene import Scene from script_wrapper import command_line_create_scene +from inventing_math import underbrace import random @@ -47,6 +48,10 @@ def fraction_mobject(fraction): n, d = fraction.numerator, fraction.denominator return tex_mobject("\\frac{%d}{%d}"%(n, d)) +def continued_fraction(int_list): + if len(int_list) == 1: + return int_list[0] + return int_list[0] + Fraction(1, continued_fraction(int_list[1:])) def zero_to_one_interval(): interval = NumberLine( @@ -69,6 +74,31 @@ class OpenInterval(Mobject): self.stretch(0.5+0.5*scale_factor, 1) self.shift(center) +class Piano(ImageMobject): + SHOULD_BUFF_POINTS = False + def __init__(self, **kwargs): + ImageMobject.__init__(self, "piano_keyboard", invert = False) + jump = self.get_width()/24 + self.scale(0.5).center() + self.half_note_jump = self.get_width()/24 + self.ivory_jump = self.get_width()/14 + + def split(self): + left = self.get_left()[0] + keys = [] + for count in range(14): + key = Mobject(color = "white") + x0 = left + count*self.ivory_jump + x1 = x0 + self.ivory_jump + key.add_points( + self.points[ + (self.points[:,0] > x0)*(self.points[:,0] < x1) + ] + ) + keys.append(key) + return keys + + class VibratingString(Animation): def __init__(self, num_periods = 1, @@ -84,7 +114,7 @@ class VibratingString(Animation): self.center = center def func(x, t): return sum([ - (amplitude/((k+1)**2))*np.sin(2*mult*t)*np.sin(k*mult*x) + (amplitude/((k+1)**2.5))*np.sin(2*mult*t)*np.sin(k*mult*x) for k in range(overtones) for mult in [(num_periods+k)*np.pi] ]) @@ -95,16 +125,18 @@ class VibratingString(Animation): def update_mobject(self, alpha): self.mobject.init_points() + epsilon = self.mobject.epsilon self.mobject.add_points([ - [x*self.radius, self.func(x, alpha*self.run_time), 0] - for x in np.arange(-1, 1, self.mobject.epsilon/self.radius) + [x*self.radius, self.func(x, alpha*self.run_time)+y, 0] + for x in np.arange(-1, 1, epsilon/self.radius) + for y in epsilon*np.arange(3) ]) self.mobject.shift(self.center) class IntervalScene(Scene): def construct(self): - self.interval = zero_to_one_interval() + self.interval = UnitInterval() self.add(self.interval) def show_all_fractions(self, @@ -144,8 +176,8 @@ class IntervalScene(Scene): ) def add_open_interval(self, num, width, color = None, run_time = 0): - width *= 2*self.interval.radius - center_point = self.num_to_point(num) + width *= self.interval.unit_length_to_spacial_width + center_point = self.interval.number_to_point(num) open_interval = OpenInterval(center_point, width) if color: open_interval.highlight(color) @@ -155,7 +187,7 @@ class IntervalScene(Scene): interval_line.highlight("yellow") if run_time > 0: squished_interval = deepcopy(open_interval).stretch_to_fit_width(0) - self.animate( + self.play( Transform(squished_interval, open_interval), ShowCreation(interval_line), run_time = run_time @@ -164,11 +196,6 @@ class IntervalScene(Scene): self.add(open_interval, interval_line) return open_interval, interval_line - def num_to_point(self, num): - assert(num <= 1 and num >= 0) - radius = self.interval.radius - return (num*2*radius - radius)*RIGHT - class TwoChallenges(Scene): def construct(self): @@ -196,10 +223,10 @@ class TwoChallenges(Scene): self.dither() self.add(two, measure) self.dither() - self.animate(ShowCreation(arrow_to_int)) + self.play(ShowCreation(arrow_to_int)) self.add(integration) self.dither() - self.animate(ShowCreation(arrow_to_prob)) + self.play(ShowCreation(arrow_to_prob)) self.add(probability) self.dither() @@ -213,9 +240,9 @@ class MeasureTheoryToHarmony(IntervalScene): self.clear() radius = self.interval.radius line = Line(radius*LEFT, radius*RIGHT).highlight("white") - self.animate(DelayByOrder(Transform(all_mobs, line))) + self.play(DelayByOrder(Transform(all_mobs, line))) self.clear() - self.animate(VibratingString(alpha_func = smooth)) + self.play(VibratingString(alpha_func = smooth)) self.clear() self.add(line) self.dither() @@ -224,21 +251,440 @@ class MeasureTheoryToHarmony(IntervalScene): class ChallengeOne(Scene): def construct(self): title = text_mobject("Challenge #1").to_edge(UP) - bottom_vibration = VibratingString( - num_periods = 1, run_time = 1.0, + start_color = Color("blue") + colors = start_color.range_to("white", 6) + self.bottom_vibration = VibratingString( + num_periods = 1, run_time = 3.0, + center = DOWN, color = start_color + ) + top_vibrations = [ + VibratingString( + num_periods = freq, run_time = 3.0, + center = 2*UP, color = colors.next() + ) + for freq in [1, 2, 5.0/3, 4.0/3, 2] + ] + freq_220 = text_mobject("220 Hz") + freq_r220 = text_mobject("$r\\times$220 Hz") + freq_330 = text_mobject("1.5$\\times$220 Hz") + freq_sqrt2 = text_mobject("$\\sqrt{2}\\times$220 Hz") + freq_220.shift(1.5*DOWN) + for freq in freq_r220, freq_330, freq_sqrt2: + freq.shift(1.5*UP) + r_constraint = tex_mobject("(1