def construct(self): circle = Circle() square = Square() self.add(circle) self.add(square) self.play(UpdateFromAlphaFunc(circle, self.update_stuff), UpdateFromAlphaFunc(square, self.update_stuff, rate_func=linear)) self.wait()
def __init__(self, point, color=YELLOW, **kwargs): digest_config(self, kwargs) lines = VGroup() for angle in np.arange(0, TAU, TAU / self.num_lines): line = Line(ORIGIN, self.line_length * RIGHT) line.shift((self.flash_radius - self.line_length) * RIGHT) line.rotate(angle, about_point=ORIGIN) lines.add(line) lines.move_to(point) lines.set_color(color) lines.set_stroke(width=3) line_anims = [ ShowCreationThenDestruction( line, rate_func=squish_rate_func(smooth, 0, 0.5) ) for line in lines ] fade_anims = [ UpdateFromAlphaFunc( line, lambda m, a: m.set_stroke( width=self.line_stroke_width * (1 - a) ), rate_func=squish_rate_func(smooth, 0, 0.75) ) for line in lines ] AnimationGroup.__init__( self, *line_anims + fade_anims, **kwargs )
def compile_play_args_to_animation_list(self, *args, **kwargs): """ Add animations so that all pi creatures look at the first mobject being animated with each .play call """ animations = Scene.compile_play_args_to_animation_list( self, *args, **kwargs) if not self.any_pi_creatures_on_screen(): return animations pi_creatures = self.get_on_screen_pi_creatures() non_pi_creature_anims = [ anim for anim in animations if len( set(anim.mobject.get_family()).intersection(pi_creatures)) == 0 ] if len(non_pi_creature_anims) == 0: return animations # Get pi creatures to look at whatever # is being animated first_anim = non_pi_creature_anims[0] main_mobject = first_anim.mobject animations += [ UpdateFromAlphaFunc( pi_creature, lambda p, a: p.look_at( interpolate( p.get_look_at_spot(), main_mobject.get_center(), a, )), ) for pi_creature in pi_creatures ] return animations
def construct(self): self.phase = 0 big_wave = self.make_graph(lambda x: self.upper_func(x) * 3, UPPER_COLOR).shift(4.5 * LEFT) self.play(ShowCreation(big_wave), run_time=2, rate_func=lambda t: running_start(t, pull_factor=1)) self.wait() upper_axes = self.make_axes(0.9, "E_1").shift(UPPER_POSITION) self.upper_graph = self.make_graph(self.upper_func, UPPER_COLOR).shift(UPPER_POSITION) middle_axes = self.make_axes(0.9, "E_2").shift(MIDDLE_POSITION) self.middle_graph = self.make_graph( self.middle_func, MIDDLE_COLOR).shift(MIDDLE_POSITION) lower_axes = self.make_axes(1.4, "E_1 + E_2").shift(LOWER_POSITION) self.lower_graph = self.make_graph(self.lower_func, LOWER_COLOR).shift(LOWER_POSITION) self.play( AnimationGroup(Transform(big_wave, self.upper_graph, run_time=1.2), FadeIn(upper_axes), lag_ratio=0.5)) self.bring_to_back(upper_axes) self.play(FadeIn(middle_axes), FadeIn(self.middle_graph)) # self.wait() self.play(FadeIn(lower_axes), FadeIn(self.lower_graph)) self.wait(0.5) self.play( UpdateFromAlphaFunc(VGroup(self.middle_graph, self.lower_graph), self.anim_pi_2), run_time=2, ) self.wait(0.5) self.play( UpdateFromAlphaFunc(VGroup(self.middle_graph, self.lower_graph), self.anim_pi_3), run_time=1.5, ) self.wait() self.wait()
def get_animation_integral_bounds_change( self, graph, curr_t_min, curr_t_max, new_t_min, new_t_max, fade_close_to_origin=True, run_time=1.0 ): self.area = self.get_area(graph, curr_t_min, curr_t_max) curr_t_min = self.x_axis.point_to_number(self.area.get_left()) curr_t_max = self.x_axis.point_to_number(self.area.get_right()) if new_t_min is None: new_t_min = curr_t_min if new_t_max is None: new_t_max = curr_t_max group = VGroup(self.area) group.add(self.left_v_line) group.add(self.left_T_label_group) group.add(self.right_v_line) group.add(self.right_T_label_group) def update_group(group, alpha): area, left_v_line, left_T_label, right_v_line, right_T_label = group t_min = interpolate(curr_t_min, new_t_min, alpha) t_max = interpolate(curr_t_max, new_t_max, alpha) new_area = self.get_area(graph, t_min, t_max) new_left_v_line = self.get_vertical_line_to_graph( t_min, graph ) new_left_v_line.set_color(left_v_line.get_color()) left_T_label.move_to(new_left_v_line.get_bottom(), UP) new_right_v_line = self.get_vertical_line_to_graph( t_max, graph ) new_right_v_line.set_color(right_v_line.get_color()) right_T_label.move_to(new_right_v_line.get_bottom(), UP) # Fade close to 0 if fade_close_to_origin: if len(left_T_label) > 0: left_T_label[0].set_fill(opacity=min(1, np.abs(t_min))) if len(right_T_label) > 0: right_T_label[0].set_fill(opacity=min(1, np.abs(t_max))) area.become(new_area) left_v_line.become(new_left_v_line) right_v_line.become(new_right_v_line) return group return UpdateFromAlphaFunc(group, update_group, run_time=run_time)
def construct(self): a = 1 c = FunctionGraph(lambda x: 2 * np.exp(-2 * (x - a * 1)**2)) axes = Axes(y_min=-3, y_max=3) def update_curve(c, dt): alpha = interpolate(1, 4, dt) c_c = FunctionGraph(lambda x: 2 * np.exp(-2 * (x - a * alpha)**2)) c.become(c_c) self.play(ShowCreation(axes), ShowCreation(c)) self.wait() self.play(UpdateFromAlphaFunc(c, update_curve), rate_func=there_and_back, run_time=4) self.wait()
def animate_secant_slope_group_change( self, secant_slope_group, target_dx=None, target_x=None, run_time=3, added_anims=None, **anim_kwargs ): if target_dx is None and target_x is None: raise Exception( "At least one of target_x and target_dx must not be None") if added_anims is None: added_anims = [] start_dx = secant_slope_group.kwargs["dx"] start_x = secant_slope_group.kwargs["x"] if target_dx is None: target_dx = start_dx if target_x is None: target_x = start_x def update_func(group, alpha): dx = interpolate(start_dx, target_dx, alpha) x = interpolate(start_x, target_x, alpha) kwargs = dict(secant_slope_group.kwargs) kwargs["dx"] = dx kwargs["x"] = x new_group = self.get_secant_slope_group(**kwargs) Transform(group, new_group).update(1) return group self.play( UpdateFromAlphaFunc( secant_slope_group, update_func, run_time=run_time, **anim_kwargs ), *added_anims ) secant_slope_group.kwargs["x"] = target_x secant_slope_group.kwargs["dx"] = target_dx
def animate_secant_slope_group_change(self, secant_slope_group, target_dx=None, target_x=None, run_time=3, added_anims=None, **anim_kwargs): """ This method animates the change of the secant slope group from the old secant slope group, into a new secant slope group. Parameters ---------- secant_slope_group (VGroup) The old secant_slope_group target_dx Union[int, float] The new dx value. target_x Union[int, float] The new x value at which the secant should be. run_time Union[int,float=3] The run time for this change when animated. added_anims Any exta animations that should be played alongside. **anim_kwargs Any valid kwargs of a self.play call. NOTE: At least one of target_dx and target_x should be not None. """ if target_dx is None and target_x is None: raise Exception( "At least one of target_x and target_dx must not be None") if added_anims is None: added_anims = [] start_dx = secant_slope_group.kwargs["dx"] start_x = secant_slope_group.kwargs["x"] if target_dx is None: target_dx = start_dx if target_x is None: target_x = start_x def update_func(group, alpha): dx = interpolate(start_dx, target_dx, alpha) x = interpolate(start_x, target_x, alpha) kwargs = dict(secant_slope_group.kwargs) kwargs["dx"] = dx kwargs["x"] = x new_group = self.get_secant_slope_group(**kwargs) group.become(new_group) return group self.play( UpdateFromAlphaFunc(secant_slope_group, update_func, run_time=run_time, **anim_kwargs), *added_anims) secant_slope_group.kwargs["x"] = target_x secant_slope_group.kwargs["dx"] = target_dx
def get_animation_integral_bounds_change(self, graph, new_t_min, new_t_max, fade_close_to_origin=True, run_time=1.0): """ This method requires a lot of prerequisites: self.area must be defined from self.get_area() self.left_v_line and self.right_v_line must be defined from self.get_v_line self.left_T_label_group and self.right_T_label_group must be defined from self.add_T_label This method will returna VGroup of new mobjects for each of those, when provided the graph/curve, the new t_min and t_max, the run_time and a bool stating whether or not to fade when close to the origin. Parameters ---------- graph (ParametricFunction) The graph for which this must be done. new_t_min (Union[int,float]) The new lower bound. new_t_max (Union[int,float]) The new upper bound. fade_close_to_origin (bool=True) Whether or not to fade when close to the origin. run_time (Union[int,float=1.0]) The run_time of the animation of this change. """ curr_t_min = self.x_axis.point_to_number(self.area.get_left()) curr_t_max = self.x_axis.point_to_number(self.area.get_right()) if new_t_min is None: new_t_min = curr_t_min if new_t_max is None: new_t_max = curr_t_max group = VGroup(self.area) group.add(self.left_v_line) group.add(self.left_T_label_group) group.add(self.right_v_line) group.add(self.right_T_label_group) def update_group(group, alpha): area, left_v_line, left_T_label, right_v_line, right_T_label = group t_min = interpolate(curr_t_min, new_t_min, alpha) t_max = interpolate(curr_t_max, new_t_max, alpha) new_area = self.get_area(graph, t_min, t_max) new_left_v_line = self.get_vertical_line_to_graph(t_min, graph) new_left_v_line.set_color(left_v_line.get_color()) left_T_label.move_to(new_left_v_line.get_bottom(), UP) new_right_v_line = self.get_vertical_line_to_graph(t_max, graph) new_right_v_line.set_color(right_v_line.get_color()) right_T_label.move_to(new_right_v_line.get_bottom(), UP) # Fade close to 0 if fade_close_to_origin: if len(left_T_label) > 0: left_T_label[0].set_fill(opacity=min(1, np.abs(t_min))) if len(right_T_label) > 0: right_T_label[0].set_fill(opacity=min(1, np.abs(t_max))) Transform(area, new_area).update(1) Transform(left_v_line, new_left_v_line).update(1) Transform(right_v_line, new_right_v_line).update(1) return group return UpdateFromAlphaFunc(group, update_group, run_time=run_time)
def construct(self): self.phase = 0 point_x, point_y = self.comp_point(0) self.make_axes() self.ellipse = VMobject(color=self.path_color) self.phi = TexMobject(r"\Delta \Phi = ").set_color(BLACK).shift(4 * RIGHT + 2 * UP) self.phi_0 = TexMobject("0").set_color(BLACK).next_to(self.phi, RIGHT) self.phi_pi_2 = TexMobject(r"\frac{\pi}{2}").set_color(BLACK).next_to( self.phi, RIGHT).shift(0.06 * DOWN) self.phi_3_pi_4 = TexMobject(r"\frac{3 \pi}{4}").set_color( BLACK).next_to(self.phi, RIGHT) self.x_vector = Vector(point_x * RIGHT, color=self.axes_vector_color, **self.vector_args) self.y_vector = Vector(point_y * UP, color=self.axes_vector_color, **self.vector_args) self.xy_vector = Vector(point_x * RIGHT + point_y * UP, color=self.xy_vector_color, **self.vector_args) update_group = VGroup( self.ellipse, self.xy_vector, self.x_vector, self.y_vector, ) self.wait(1.6) self.add(self.ellipse) self.play(FadeIn(self.x_vector)) # self.wait(1) self.play(FadeIn(self.y_vector)) self.wait(4) self.play(FadeIn(self.xy_vector)) self.play(UpdateFromAlphaFunc(update_group, self.do_vectors_and_ellipse_period), run_time=self.period, rate_func=linear) self.play( UpdateFromAlphaFunc(update_group, self.do_vectors_only_period, run_time=self.period, rate_func=linear)) self.play( AnimationGroup(UpdateFromAlphaFunc(update_group, self.do_vectors_only_period, run_time=self.period, rate_func=linear), AnimationGroup(FadeIn(self.phi), FadeIn(self.phi_0)), lag_ratio=0.7)) self.play( UpdateFromAlphaFunc(update_group, self.do_vectors_only_period, run_time=self.period, rate_func=linear)) self.x_vector.set_color(BLACK) self.play(UpdateFromAlphaFunc(update_group, self.do_90_phase_shift, rate_func=linear), FadeOut(self.ellipse), FadeOut(self.phi_0), FadeIn(self.phi_pi_2), run_time=self.period / 4) self.phase = np.pi / 2 self.ellipse.set_points([]) self.x_vector.set_color(self.axes_vector_color) self.play(UpdateFromAlphaFunc(update_group, self.do_vectors_and_ellipse_period), run_time=self.period, rate_func=linear) for _ in range(3): self.play(UpdateFromAlphaFunc(update_group, self.do_vectors_only_period), run_time=self.period, rate_func=linear) self.x_vector.set_color(BLACK) self.play(UpdateFromAlphaFunc(update_group, self.do_45_phase_shift, rate_func=linear), FadeOut(self.ellipse), FadeOut(self.phi_pi_2), FadeIn(self.phi_3_pi_4), run_time=self.period / 8) self.phase = 3 * np.pi / 4 self.ellipse.set_points([]) self.x_vector.set_color(self.axes_vector_color) self.play(UpdateFromAlphaFunc(update_group, self.do_vectors_and_ellipse_period), run_time=self.period, rate_func=linear) self.play( AnimationGroup(UpdateFromAlphaFunc( update_group, self.do_vectors_only_period_hide, rate_func=linear, run_time=self.period), AnimationGroup(FadeOut(self.phi_3_pi_4), FadeOut(self.phi)), lag_ratio=0.7)) self.play(FadeOut(self.axes), FadeOut(self.axes_labels)) self.wait()