def vector_to_coords(self, vector, integer_labels=True, clean_up=True): """ This method displays vector as a Vector() based vector, and then shows the corresponding lines that make up the x and y components of the vector. Then, a column matrix (henceforth called the label) is created near the head of the Vector. Parameters ---------- vector Union(np.ndarray, list, tuple) The vector to show. integer_label (bool=True) Whether or not to round the value displayed. in the vector's label to the nearest integer clean_up (bool=True) Whether or not to remove whatever this method did after it's done. """ starting_mobjects = list(self.mobjects) show_creation = False if isinstance(vector, Arrow): arrow = vector vector = arrow.get_end()[:2] else: arrow = Vector(vector) show_creation = True array = vector_coordinate_label(arrow, integer_labels=integer_labels) x_line = Line(ORIGIN, vector[0] * RIGHT) y_line = Line(x_line.get_end(), arrow.get_end()) x_line.set_color(X_COLOR) y_line.set_color(Y_COLOR) x_coord, y_coord = array.get_mob_matrix().flatten() x_coord_start = self.position_x_coordinate(x_coord.copy(), x_line, vector) y_coord_start = self.position_y_coordinate(y_coord.copy(), y_line, vector) brackets = array.get_brackets() if show_creation: self.play(ShowCreation(arrow)) self.play(ShowCreation(x_line), Write(x_coord_start), run_time=1) self.play(ShowCreation(y_line), Write(y_coord_start), run_time=1) self.wait() self.play( Transform(x_coord_start, x_coord, lag_ratio=0), Transform(y_coord_start, y_coord, lag_ratio=0), Write(brackets, run_time=1), ) self.wait() self.remove(x_coord_start, y_coord_start, brackets) self.add(array) if clean_up: self.clear() self.add(*starting_mobjects) return array, x_line, y_line
def __init__(self, mobject, direction=None, **kwargs): digest_config(self, kwargs) target = mobject.copy() if direction is None: direction = self.direction mobject.shift(direction) mobject.fade(1) Transform.__init__(self, mobject, target, **kwargs)
def __init__(self, mobject, point, **kwargs): digest_config(self, kwargs) target = mobject.copy() mobject.scale(0) mobject.move_to(point) if self.point_color: mobject.set_color(self.point_color) Transform.__init__(self, mobject, target, **kwargs)
def __init__(self, ct_mob, **kwargs): digest_config(self, kwargs, locals()) source_tiles = mobs_shuffle(ct_mob.get_all_tiles()) target_tiles = source_tiles.copy() for tile in target_tiles: tile.scale_in_place(0) tile.set_stroke(width=0) Transform.__init__(self, source_tiles, target_tiles, **kwargs)
def __init__(self, mobject, target_mobject, **kwargs): digest_config(self, kwargs) assert (isinstance(mobject, self.mobject_type)) assert (isinstance(target_mobject, self.mobject_type)) source_map = self.get_shape_map(mobject) target_map = self.get_shape_map(target_mobject) # Create two mobjects whose submobjects all match each other # according to whatever keys are used for source_map and # target_map transform_source = self.group_type() transform_target = self.group_type() kwargs["final_alpha_value"] = 0 for key in set(source_map).intersection(target_map): transform_source.add(source_map[key]) transform_target.add(target_map[key]) anims = [Transform(transform_source, transform_target, **kwargs)] # User can manually specify when one part should transform # into another despite not matching by using key_map key_mapped_source = self.group_type() key_mapped_target = self.group_type() for key1, key2 in self.key_map.items(): if key1 in source_map and key2 in target_map: key_mapped_source.add(source_map[key1]) key_mapped_target.add(target_map[key2]) source_map.pop(key1, None) target_map.pop(key2, None) if len(key_mapped_source) > 0: anims.append( FadeTransformPieces( key_mapped_source, key_mapped_target, )) fade_source = self.group_type() fade_target = self.group_type() for key in set(source_map).difference(target_map): fade_source.add(source_map[key]) for key in set(target_map).difference(source_map): fade_target.add(target_map[key]) if self.transform_mismatches: anims.append(Transform(fade_source.copy(), fade_target, **kwargs)) if self.fade_transform_mismatches: anims.append( FadeTransformPieces(fade_source, fade_target, **kwargs)) else: anims.append( FadeOutToPoint(fade_source, fade_target.get_center(), **kwargs)) anims.append( FadeInFromPoint(fade_target.copy(), fade_source.get_center(), **kwargs)) super().__init__(*anims) self.to_remove = mobject self.to_add = target_mobject
def __init__(self, mobject, point, **kwargs): digest_config(self, kwargs) target = mobject.copy() point_mob = VectorizedPoint(point) if self.point_color: point_mob.set_color(self.point_color) mobject.replace(point_mob) mobject.set_color(point_mob.get_color()) Transform.__init__(self, mobject, target, **kwargs)
def construct(self): circle = Circle() square = Square() line = Line((3, 0, 0), (5, 0, 0)) triangle = Polygon((0, 0, 0), (1, 1, 0), (1, -1, 0)) self.play(ShowCreation(circle), run_time=5) self.play(FadeOut(circle), GrowFromCenter(square)) self.add(line) self.play(Transform(square, triangle)) self.play(Transform(triangle)) self.wait()
def animate_product(self, left, right, result): l_matrix = left.get_mob_matrix() r_matrix = right.get_mob_matrix() result_matrix = result.get_mob_matrix() circle = Circle( radius=l_matrix[0][0].get_height(), color=GREEN ) circles = VGroup(*[ entry.get_point_mobject() for entry in (l_matrix[0][0], r_matrix[0][0]) ]) (m, k), n = l_matrix.shape, r_matrix.shape[1] for mob in result_matrix.flatten(): mob.set_color(BLACK) lagging_anims = [] for a in range(m): for b in range(n): for c in range(k): l_matrix[a][c].set_color(YELLOW) r_matrix[c][b].set_color(YELLOW) for c in range(k): start_parts = VGroup( l_matrix[a][c].copy(), r_matrix[c][b].copy() ) result_entry = result_matrix[a][b].split()[c] new_circles = VGroup(*[ circle.copy().shift(part.get_center()) for part in start_parts.split() ]) self.play(Transform(circles, new_circles)) self.play( Transform( start_parts, result_entry.copy().set_color(YELLOW), path_arc=-np.pi / 2, submobject_mode="all_at_once", ), *lagging_anims ) result_entry.set_color(YELLOW) self.remove(start_parts) lagging_anims = [ ApplyMethod(result_entry.set_color, WHITE) ] for c in range(k): l_matrix[a][c].set_color(WHITE) r_matrix[c][b].set_color(WHITE) self.play(FadeOut(circles), *lagging_anims) self.wait()
def __init__(self, mobject_or_point, **kwargs): digest_config(self, kwargs) big_dot = Dot( radius=FRAME_X_RADIUS + FRAME_Y_RADIUS, stroke_width=0, fill_color=self.color, fill_opacity=0, ) little_dot = Dot(radius=0) little_dot.set_fill(self.color, opacity=self.opacity) little_dot.move_to(mobject_or_point) Transform.__init__(self, big_dot, little_dot, **kwargs)
def vector_to_coords(self, vector, integer_labels=True, clean_up=True): starting_mobjects = list(self.mobjects) show_creation = False if isinstance(vector, Arrow): arrow = vector vector = arrow.get_end()[:2] else: arrow = Vector(vector) show_creation = True array = vector_coordinate_label(arrow, integer_labels=integer_labels) x_line = Line(ORIGIN, vector[0] * RIGHT) y_line = Line(x_line.get_end(), arrow.get_end()) x_line.set_color(X_COLOR) y_line.set_color(Y_COLOR) x_coord, y_coord = array.get_mob_matrix().flatten() x_coord_start = self.position_x_coordinate( x_coord.copy(), x_line, vector ) y_coord_start = self.position_y_coordinate( y_coord.copy(), y_line, vector ) brackets = array.get_brackets() if show_creation: self.play(ShowCreation(arrow)) self.play( ShowCreation(x_line), Write(x_coord_start), run_time=1 ) self.play( ShowCreation(y_line), Write(y_coord_start), run_time=1 ) self.wait() self.play( Transform(x_coord_start, x_coord, lag_ratio=0), Transform(y_coord_start, y_coord, lag_ratio=0), Write(brackets, run_time=1), ) self.wait() self.remove(x_coord_start, y_coord_start, brackets) self.add(array) if clean_up: self.clear() self.add(*starting_mobjects) return array, x_line, y_line
def __init__(self, mobject, angle=np.pi, axis=OUT, **kwargs): if "path_arc" not in kwargs: kwargs["path_arc"] = angle if "path_arc_axis" not in kwargs: kwargs["path_arc_axis"] = axis digest_config(self, kwargs, locals()) target = mobject.copy() if self.in_place: self.about_point = mobject.get_center() target.rotate( angle, axis=axis, about_point=self.about_point, ) Transform.__init__(self, mobject, target, **kwargs)
def change_tilings(self): # Pattern doesn't matter old_ct = self.cts[0] pattern_ct = self.cts[1] self.play( Transform(old_ct, pattern_ct, path_arc=np.pi, path_arc_axis=np.array([1., 1., 1.])), run_time=3, ) self.wait() self.fill_and_unfill_multiple_sets(old_ct, old_ct.get_directions()) # Size doesn't matter either old_reflines = self.reflines size_ct = self.cts[2] old_tiles = old_ct.get_all_tiles() new_reflines = Reflines(size_ct) self.play(FadeOut(old_tiles), run_time=1) self.play(FadeOut(old_reflines), Animation(self.border), run_time=1) self.play(FadeIn(new_reflines), Animation(self.border), run_time=1) self.wait() self.play(TilesGrow(size_ct)) self.wait() self.fill_and_unfill_multiple_sets(size_ct, size_ct.get_directions())
def construct(self): quote = TextMobject("Imagination is more important than knowledge") quote.set_color(RED) quote.to_edge(UP) quote2 = TextMobject( "A person who never made a mistake never tried anything new") quote2.set_color(YELLOW) author = TextMobject("- Albert Einstein") author.scale(0.75) corner = quote.get_corner(DOWN + RIGHT) print("corner", corner) author.next_to(corner, ORIGIN) self.add(quote, author) self.wait(2) self.play( Transform(quote, quote2), ApplyMethod(author.move_to, quote2.get_corner(DOWN + RIGHT) + DOWN + 2 * LEFT)) self.play(ApplyMethod(author.scale, 1.5)) author.match_color(quote2) self.play(FadeOut(quote), FadeOut(author)) self.wait()
def construct(self): # Generate transformation animations of the twin dragon curve anims = list() fractal = VMobject() fractal.shift(UP) for order in range(-1, self.max_order+1): new_fractal = TwinDragon(order = order) new_fractal.shift(UP) run_time = 0.5 if order >= 0 else 0 anims.append( Transform( fractal, new_fractal, submobject_mode = "all_at_once", run_time = run_time, ) ) fractal = new_fractal # Add the channel name text = TextMobject("Solara570") text.scale(2).to_edge(DOWN, buff = 1.2) # Now sit back and watch self.play( Succession(*anims, rate_func = smooth), Write(text, lag_factor = 2.5, rate_func = squish_rate_func(smooth, 0.1, 0.9)), run_time = 4.5, )
def transform_between_riemann_rects(self, curr_rects, new_rects, **kwargs): """ This method is used to transform between two VGroups of Riemann Rectangles, if they were obtained by get_riemann_rectangles or get_riemann_rectangles_list. No animation is returned, and the animation is directly played. Parameters ---------- curr_rects : VGroup The current Riemann Rectangles new_rects : VGroup The Riemann Rectangles to transform to. **kwargs added_anims Any other animations to play simultaneously. """ transform_kwargs = {"run_time": 2, "lag_ratio": 0.5} added_anims = kwargs.get("added_anims", []) transform_kwargs.update(kwargs) curr_rects.align_submobjects(new_rects) x_coords = set() # Keep track of new repetitions for rect in curr_rects: x = rect.get_center()[0] if x in x_coords: rect.set_fill(opacity=0) else: x_coords.add(x) self.play(Transform(curr_rects, new_rects, **transform_kwargs), *added_anims)
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
def show_ghost_movement(self, vector): if isinstance(vector, Arrow): vector = vector.get_end() - vector.get_start() elif len(vector) == 2: vector = np.append(np.array(vector), 0.0) x_max = int(FRAME_X_RADIUS + abs(vector[0])) y_max = int(FRAME_Y_RADIUS + abs(vector[1])) dots = VMobject(*[ Dot(x * RIGHT + y * UP) for x in range(-x_max, x_max) for y in range(-y_max, y_max) ]) dots.set_fill(BLACK, opacity=0) dots_halfway = dots.copy().shift(vector / 2).set_fill(WHITE, 1) dots_end = dots.copy().shift(vector) self.play(Transform(dots, dots_halfway, rate_func=rush_into)) self.play(Transform(dots, dots_end, rate_func=rush_from)) self.remove(dots)
def get_student_changes(self, *modes, **kwargs): pairs = list(zip(self.get_students(), modes)) pairs = [(s, m) for s, m in pairs if m is not None] start = VGroup(*[s for s, m in pairs]) target = VGroup(*[s.copy().change_mode(m) for s, m in pairs]) if "look_at_arg" in kwargs: for pi in target: pi.look_at(kwargs["look_at_arg"]) lag_ratio = kwargs.get("lag_ratio", 0.5) return Transform(start, target, lag_ratio=lag_ratio, run_time=2)
def change_mode(self, mode): new_self = self.__class__(mode=mode, ) new_self.match_style(self) new_self.match_height(self) if self.is_flipped() != new_self.is_flipped(): new_self.flip() new_self.shift(self.eyes.get_center() - new_self.eyes.get_center()) if hasattr(self, "purposeful_looking_direction"): new_self.look(self.purposeful_looking_direction) Transform(self, new_self).update(1) self.mode = mode return self
def update_sectors(self): if self.screen is None: return for submob in self.submobjects: if type(submob) == AnnularSector: lower_angle, upper_angle = self.viewing_angles(self.screen) # dr = submob.outer_radius - submob.inner_radius dr = self.radius / self.num_levels new_submob = self.new_sector(submob.inner_radius, dr, lower_angle, upper_angle) # submob.points = new_submob.points # submob.set_fill(opacity = 10 * self.opacity_function(submob.outer_radius)) Transform(submob, new_submob).update(1)
def construct(self): circle = Circle() square = Square() line = Line(np.array([3, 0, 0]), np.array([5, 0, 0])) triangle = Polygon(np.array([0, 0, 0]), np.array([1, 1, 0]), np.array([1, -1, 0])) self.add(line) self.play(ShowCreation(circle)) self.play(FadeOut(circle)) self.play(GrowFromCenter(square)) self.play(Transform(square, triangle)) self.wait()
def get_student_changes(self, *modes, **kwargs): pairs = list(zip(self.get_students(), modes)) pairs = [(s, m) for s, m in pairs if m is not None] start = VGroup(*[s for s, m in pairs]) target = VGroup(*[s.copy().change_mode(m) for s, m in pairs]) if "look_at_arg" in kwargs: for pi in target: pi.look_at(kwargs["look_at_arg"]) submobject_mode = kwargs.get("submobject_mode", "lagged_start") return Transform(start, target, submobject_mode=submobject_mode, run_time=2)
def transform_between_riemann_rects(self, curr_rects, new_rects, **kwargs): transform_kwargs = {"run_time": 2, "lag_ratio": 0.5} added_anims = kwargs.get("added_anims", []) transform_kwargs.update(kwargs) curr_rects.align_submobjects(new_rects) x_coords = set() # Keep track of new repetitions for rect in curr_rects: x = rect.get_center()[0] if x in x_coords: rect.set_fill(opacity=0) else: x_coords.add(x) self.play(Transform(curr_rects, new_rects, **transform_kwargs), *added_anims)
def construct(self): my_first_text = TextMobject("Writing with manim is fun") second_line = TextMobject("and easy to do!") second_line.next_to(my_first_text, DOWN) third_line = TextMobject("for me and you!") third_line.next_to(my_first_text, DOWN) self.add(my_first_text, second_line) self.wait(2) self.play(Transform(second_line, third_line)) self.wait(2) second_line.shift(3 * DOWN) self.play(ApplyMethod(my_first_text.shift, 3 * UP)) self.wait()
def get_student_changes(self, *modes, **kwargs): pairs = list(zip(self.get_students(), modes)) pairs = [(s, m) for s, m in pairs if m is not None] start = VGroup(*[s for s, m in pairs]) target = VGroup(*[s.copy().change_mode(m) for s, m in pairs]) if "look_at_arg" in kwargs: for omega in target: omega.look_at(kwargs["look_at_arg"]) anims = [Transform(s, t) for s, t in zip(start, target)] return LaggedStart( *anims, lag_ratio=kwargs.get("lag_ratio", 0.5), run_time=1, )
def construct(self): my_first_text = TextMobject("Writing with manim is fun") second_line = TextMobject("and easy to do!") second_line.next_to(my_first_text, DOWN) third_line = TextMobject("for me and you!") third_line.next_to(my_first_text, DOWN) self.play(FadeIn(my_first_text), FadeIn(second_line)) self.wait(2) self.play(Transform(second_line, third_line)) self.wait(2) self.play(ApplyMethod(my_first_text.shift, 3 * UP)) self.play(Rotating(second_line), radians=PI, run_time=2) self.wait()
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 proof_part_2(self): self.play(DrawBorderThenFill(self.rhombi, submobject_mode="all_at_once"), run_time=2) self.wait() self.wait(12) self.play(Write(self.time_texts), run_time=3) self.wait() source_texts = VGroup(*[texts[1] for texts in self.time_texts]) target_texts = VGroup(*self.conclusions[0][::2]) equal_signs = VGroup(self.conclusions[0][1::2]) qed = self.conclusions[1] self.play(Transform(source_texts.copy(), target_texts), Write(equal_signs), run_time=2) self.wait() self.play(FadeIn(qed)) self.wait(2)
def get_digit_increment_animations(self): result = [] self.number += 1 is_next_digit = self.is_next_digit() if is_next_digit: self.max_place += 1 new_number_mob = self.get_number_mob(self.number) new_number_mob.move_to(self.number_mob, RIGHT) if is_next_digit: self.add_configuration() place = len(new_number_mob.split()) - 1 result.append(FadeIn(self.dot_templates[place])) arrow = Arrow(new_number_mob[place].get_top(), self.dot_templates[place].get_bottom(), color=self.digit_place_colors[place]) self.arrows.add(arrow) result.append(ShowCreation(arrow)) result.append(Transform(self.number_mob, new_number_mob, lag_ratio=0.5)) return result
def get_piece_movement(self, pieces): """ This method returns an animation that moves an arbitrary mobject in "pieces" to its corresponding .target value. If self.leave_ghost_vectors is True, ghosts of the original positions/mobjects are left on screen Parameters ---------- pieces (Union[list, tuple, np.array]) The pieces for which the movement must be shown. Returns ------- Animation The animation of the movement. """ start = VGroup(*pieces) target = VGroup(*[mob.target for mob in pieces]) if self.leave_ghost_vectors: self.add(start.copy().fade(0.7)) return Transform(start, target, lag_ratio=0)