Esempio n. 1
0
    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, submobject_mode="all_at_once"),
            Transform(y_coord_start, y_coord, submobject_mode="all_at_once"),
            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
Esempio n. 2
0
 def tex(self, latex):
     eq = TextMobject(latex)
     anims = []
     anims.append(Write(eq))
     for mobject in self.mobjects:
         anims.append(ApplyMethod(mobject.shift, 2 * UP))
     self.play(*anims)
Esempio n. 3
0
    def coords_to_vector(self,
                         vector,
                         coords_start=2 * RIGHT + 2 * UP,
                         clean_up=True):
        starting_mobjects = list(self.mobjects)
        array = Matrix(vector)
        array.shift(coords_start)
        arrow = Vector(vector)
        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()

        self.play(Write(array, run_time=1))
        self.wait()
        self.play(
            ApplyFunction(
                lambda x: self.position_x_coordinate(x, x_line, vector),
                x_coord))
        self.play(ShowCreation(x_line))
        self.play(
            ApplyFunction(
                lambda y: self.position_y_coordinate(y, y_line, vector),
                y_coord), FadeOut(array.get_brackets()))
        y_coord, brackets = self.get_mobjects_from_last_animation()
        self.play(ShowCreation(y_line))
        self.play(ShowCreation(arrow))
        self.wait()
        if clean_up:
            self.clear()
            self.add(*starting_mobjects)
Esempio n. 4
0
    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),
            run_time=4.5,
        )
Esempio n. 5
0
    def add_T_label(self,
                    x_val,
                    side=RIGHT,
                    label=None,
                    color=WHITE,
                    animated=False,
                    **kwargs):
        triangle = RegularPolygon(n=3, start_angle=np.pi / 2)
        triangle.scale_to_fit_height(MED_SMALL_BUFF)
        triangle.move_to(self.coords_to_point(x_val, 0), UP)
        triangle.set_fill(color, 1)
        triangle.set_stroke(width=0)
        if label == None:
            T_label = TexMobject(self.variable_point_label, fill_color=color)
        else:
            T_label = TexMobject(label, fill_color=color)

        T_label.next_to(triangle, DOWN)
        v_line = self.get_vertical_line_to_graph(x_val,
                                                 self.v_graph,
                                                 color=YELLOW)

        if animated:
            self.play(DrawBorderThenFill(triangle), ShowCreation(v_line),
                      Write(T_label, run_time=1), **kwargs)

        if np.all(side == LEFT):
            self.left_T_label_group = VGroup(T_label, triangle)
            self.left_v_line = v_line
            self.add(self.left_T_label_group, self.left_v_line)
        elif np.all(side == RIGHT):
            self.right_T_label_group = VGroup(T_label, triangle)
            self.right_v_line = v_line
            self.add(self.right_T_label_group, self.right_v_line)
Esempio n. 6
0
    def construct(self):
        logo = self.logo
        name = self.channel_name

        self.play(Write(name, run_time=3, lag_factor=2.5),
                  *self.get_logo_animations(logo))
        self.wait()
Esempio n. 7
0
    def construct(self):
        self.quote = self.get_quote()
        self.author = self.get_author(self.quote)

        self.play(FadeIn(self.quote, **self.fade_in_kwargs))
        self.wait(2)
        self.play(Write(self.author, run_time=3))
        self.wait()
Esempio n. 8
0
    def solve_the_equations(self):
        rects = VGroup(*[
            CoverRectangle(
                equation[0].get_exponent(), stroke_color = color,
                text = str(num), text_color = color
            )
            for equation, color, num in zip(self.equations, self.colors, self.nums)
        ])
        self.play(DrawBorderThenFill(rects))
        self.wait()

        sps = VGroup()
        for equation, num, color in zip(self.equations, self.nums, self.colors):
            sp = TexMobject("x", "^{%d}" % num, "=", "%d" % num)
            sp[1::2].set_color(color)
            sp.scale(2)
            sp.next_to(equation, DOWN, buff = 1)
            sps.add(sp)

        rss = VGroup()
        for num, sp, color in zip(self.nums, sps, self.colors):
            rs = TexMobject("x", "=", "%d" % num , "^{{1}\\over{%d}}" % num, "=\\sqrt{2}")
            for tex in (rs[2], rs[3][2]):
                tex.set_color(color)
            rs.match_height(sp).move_to(sp)
            rss.add(rs)

        tf_anims = []
        for sp, rs in zip(sps, rss):
            tf_anims.append(ReplacementTransform(sp[0], rs[0]))
            tf_anims.append(ReplacementTransform(sp[1], rs[3][2], path_arc = -TAU/4))
            tf_anims.append(ReplacementTransform(sp[2], rs[1]))
            tf_anims.append(ReplacementTransform(sp[3], rs[2]))
            tf_anims.append(Write(rs[3][:2]))

        self.play(FadeIn(sps))
        self.wait()
        self.play(AnimationGroup(*tf_anims), run_time = 2)
        self.wait()
        self.play(Write(VGroup(*[rs[4:] for rs in rss]), submobject_mode = "all_at_once"))
        self.wait()
        self.play(FadeOut(rects))
        self.wait()

        self.rss = rss
Esempio n. 9
0
 def ask_to_solve(self):
     question = TextMobject("解", "方程($x>0$)", ":")
     solve = TextMobject("解", ":")
     for tex in (question, solve):
         tex.scale(1.2)
         tex.to_corner(LEFT+UP)
     self.play(Write(question), run_time = 1)
     self.wait()
     self.question = question
     self.solve = solve
Esempio n. 10
0
 def add_title(self, title, scale_factor=1.5, animate=False):
     if not isinstance(title, Mobject):
         title = TextMobject(title).scale(scale_factor)
     title.to_edge(UP)
     title.add_background_rectangle()
     if animate:
         self.play(Write(title))
     self.add_foreground_mobject(title)
     self.title = title
     return self
Esempio n. 11
0
    def rhs_could_be_any_number(self):
        rhs_list = [
            "2",         # The journey starts here.
            "3",         # The first number that pops into your head when you hear "2".
            "\\pi",      # The good ol' pi.
            "\\sqrt{2}", # The (most) famous irrational number.
            "42",        # The answer to everything.
            "17.29",     # TAXI.CAB
            "-1",        # A negative number, because why not?
            "e",         # The (most) famous mathematical constant.
            "\\dfrac{3+\\sqrt{13}}{2}", # The bronze ratio... and a fraction.
            "570",       # 1/3 of the author.
            "\\varphi",  # The golden ratio.
            "g_{64}",    # Gigigigigigigigantic...
            "0",         # And... stop!
            "N",
        ]
        anything_text = TextMobject("等号右边似乎可以放任何数...")
        anything_text.set_color(YELLOW)
        anything_text.to_edge(UP)
        equations = [
            VGroup(ExpTower(order = 5), TexMobject("=", rhs).scale(0.8)).scale(2.5)
            for rhs in rhs_list
        ]
        init_equation = equations[0]
        init_equation.arrange_submobjects(RIGHT, aligned_edge = DOWN)
        init_equation.next_to(anything_text, DOWN, buff = self.tower_edge_buff)
        init_equation.to_edge(LEFT, buff = self.tower_edge_buff)
        for equation in equations:
            equation[0].move_to(init_equation[0])
            equation[1][0].move_to(init_equation[1][0])
            equation[1][1].move_to(init_equation[1][1], aligned_edge = LEFT)

        self.play(FadeIn(init_equation))
        self.wait()
        self.play(Write(anything_text), run_time = 1)
        self.play(
            ShowCreationThenDestruction(SurroundingRectangle(init_equation[1][1])),
            run_time = 2
        )
        self.wait()
        for k, equation in enumerate(equations):
            if k > 0 and k != len(equations)-1:
                equation[0].move_to(init_equation[0])
                equation[1].move_to(init_equation[1], aligned_edge = LEFT)
                self.remove(equations[k-1])
                self.add(equations[k])
                self.wait(1./3)
            elif k == len(equations)-1:
                self.wait()
                self.play(ReplacementTransform(equations[k-1], equations[k]))
                self.wait()

        self.anything_text = anything_text
        self.equation = equations[-1]
Esempio n. 12
0
    def build_the_tower(self):
        highest_order = 6
        towers = [
            ExpTower(order = k, is_infinite = False)
            for k in range(1, highest_order + 1)
        ]
        towers.append(ExpTower(order = highest_order, is_infinite = True))
        heights = list(np.linspace(3, 4.5, highest_order + 2))
        for tower, height in zip(towers, heights):
            tower.set_height(height)

        init_tower = towers[0]
        final_tower = towers[-1]
        self.play(Write(init_tower))
        self.wait()
        for k, tower in enumerate(towers):
            if k < len(towers) - 2:
                new_tower = towers[k+1]
                new_exponent = new_tower.get_exponent()
                new_base = new_tower.get_base()
                self.play(
                    ReplacementTransform(tower, new_exponent),
                    Write(new_base),
                )
                self.wait()
            else:
                xs = final_tower.get_elements()
                expdots = final_tower.get_expdots()
                sur_rect = SurroundingRectangle(expdots)
                self.play(
                    ReplacementTransform(tower, xs, run_time = 1),
                    Write(expdots, run_time = 2),
                )
                self.play(
                    Indicate(expdots, run_time = 1),
                    ShowCreationThenDestruction(sur_rect, run_time = 2),
                )
                self.wait()
                break
        self.tower = final_tower
        self.highest_order = highest_order
Esempio n. 13
0
    def build_the_equation(self):
        l_part = self.tower.copy()
        r_part = TexMobject("=", "2")
        r_part.match_height(l_part.get_base())
        equation = VGroup(l_part, r_part)
        equation.arrange_submobjects(RIGHT, aligned_edge = DOWN)

        self.play(
            ReplacementTransform(self.tower, l_part, run_time = 1),
            Write(r_part, run_time = 2),
        )
        self.equation = equation
Esempio n. 14
0
 def rewind_and_play_again(self):
     watch_again = TextMobject("再看一遍...")
     watch_again.set_color(YELLOW)
     rewind, play = buttons = VGroup(*[
         Button().get_symbol().set_color(YELLOW).set_height(1)
         for Button in (RewindButton, PlayButton)
     ])
     group = VGroup(watch_again, rewind)
     group.arrange_submobjects(DOWN, aligned_edge = RIGHT)
     group.to_corner(DOWN+RIGHT)
     play.move_to(rewind, aligned_edge = RIGHT)
     self.play(Write(watch_again), run_time = 0.5)
     self.wait()
     self.add(rewind)
     self.words.reverse()
     for word in self.words:
         self.play(FadeOut(VGroup(word)), run_time = 0.2)
         self.wait(0.1)
     self.remove(rewind)
     self.add(play)
     self.play(FadeOut(watch_again), run_time = 0.5)
     self.wait(0.5)
     self.remove(play)
Esempio n. 15
0
    def reveal_2_is_4(self):
        sqrt2_towers = VGroup(*[
            ExpTower(element = "\\sqrt{2}", order = 5).match_height(x_tower) \
                .move_to(x_tower, aligned_edge = RIGHT)
            for x_tower in self.x_towers
        ])
        self.play(
            Transform(self.x_towers, sqrt2_towers, submobject_mode = "lagged_start"),
            run_time = 2,
        )
        self.wait()
        self.play(FadeOut(self.rss))
        self.wait()

        two_equals_four = TexMobject("2", "=", "4")
        for tex, color in zip(two_equals_four, [GREEN, WHITE, RED]):
            tex.set_color(color)
        two_equals_four.scale(3)
        two_equals_four.to_edge(DOWN, buff = 1)
        sources = VGroup(*[
            self.equations[i][j][k].copy()
            for i, j, k in [(0, 1, 1), (1, 1, 0), (1, 1, 1)]
        ])
        for source, target in zip(sources, two_equals_four):
            self.play(Transform(source, target))
        self.wait()

        fake_qed = FakeQEDSymbol(order = 2, jagged_percentage = 0.3)
        fake_qed.next_to(two_equals_four, RIGHT, aligned_edge = DOWN, buff = 1)
        self.play(FadeIn(fake_qed))
        self.wait()

        issue = TextMobject("思考:\\\\问题在哪?")
        issue.set_color(YELLOW)
        issue.to_corner(RIGHT+DOWN)
        self.play(Write(issue), run_time = 1)
        self.wait(2)
Esempio n. 16
0
 def label_vector(self, vector, label, animate=True, **kwargs):
     label = self.get_vector_label(vector, label, **kwargs)
     if animate:
         self.play(Write(label, run_time=1))
     self.add(label)
     return label
Esempio n. 17
0
    def setup_axes(self, animate=False):
        # TODO, once eoc is done, refactor this to be less redundant.
        x_num_range = float(self.x_max - self.x_min)
        self.space_unit_to_x = self.x_axis_width / x_num_range
        if self.x_labeled_nums is None:
            self.x_labeled_nums = []
        if self.x_leftmost_tick is None:
            self.x_leftmost_tick = self.x_min
        x_axis = NumberLine(x_min=self.x_min,
                            x_max=self.x_max,
                            unit_size=self.space_unit_to_x,
                            tick_frequency=self.x_tick_frequency,
                            leftmost_tick=self.x_leftmost_tick,
                            numbers_with_elongated_ticks=self.x_labeled_nums,
                            color=self.axes_color)
        x_axis.shift(self.graph_origin - x_axis.number_to_point(0))
        if len(self.x_labeled_nums) > 0:
            if self.exclude_zero_label:
                self.x_labeled_nums = filter(lambda x: x != 0,
                                             self.x_labeled_nums)
            x_axis.add_numbers(*self.x_labeled_nums)
        if self.x_axis_label:
            x_label = TextMobject(self.x_axis_label)
            x_label.next_to(x_axis.get_tick_marks(),
                            UP + RIGHT,
                            buff=SMALL_BUFF)
            x_label.shift_onto_screen()
            x_axis.add(x_label)
            self.x_axis_label_mob = x_label

        y_num_range = float(self.y_max - self.y_min)
        self.space_unit_to_y = self.y_axis_height / y_num_range

        if self.y_labeled_nums is None:
            self.y_labeled_nums = []
        if self.y_bottom_tick is None:
            self.y_bottom_tick = self.y_min
        y_axis = NumberLine(
            x_min=self.y_min,
            x_max=self.y_max,
            unit_size=self.space_unit_to_y,
            tick_frequency=self.y_tick_frequency,
            leftmost_tick=self.y_bottom_tick,
            numbers_with_elongated_ticks=self.y_labeled_nums,
            color=self.axes_color,
            line_to_number_vect=LEFT,
        )
        y_axis.shift(self.graph_origin - y_axis.number_to_point(0))
        y_axis.rotate(np.pi / 2, about_point=y_axis.number_to_point(0))
        if len(self.y_labeled_nums) > 0:
            if self.exclude_zero_label:
                self.y_labeled_nums = filter(lambda y: y != 0,
                                             self.y_labeled_nums)
            y_axis.add_numbers(*self.y_labeled_nums)
        if self.y_axis_label:
            y_label = TextMobject(self.y_axis_label)
            y_label.next_to(y_axis.get_tick_marks(),
                            UP + RIGHT,
                            buff=SMALL_BUFF)
            y_label.shift_onto_screen()
            y_axis.add(y_label)
            self.y_axis_label_mob = y_label

        if animate:
            self.play(Write(VGroup(x_axis, y_axis)))
        else:
            self.add(x_axis, y_axis)
        self.x_axis, self.y_axis = self.axes = VGroup(x_axis, y_axis)
        self.default_graph_colors = it.cycle(self.default_graph_colors)
Esempio n. 18
0
    def construct(self):
        # Setup
        axes_group = self.axes_group
        pos_axis, time_axis = axes_group[:2]
        title_pq = self.title_pq
        walk_q = self.walk_q
        parts_q = self.parts_q
        l_arrow = self.l_arrow
        self.add(axes_group, title_pq, walk_q, l_arrow)
        walk_q_copy = walk_q.copy()

        # Q_4 -> P_4
        steps_qp = VGroup(*[
            TextMobject(text) for text in [
                "1. 找到路径终点的位置坐标$h$", "2. 找到最晚一次穿过$\\frac{h}{2}$的时刻",
                "3. 在这个时刻上进行分割", "4. 将第一段水平翻转", "5. 拼接两个片段"
            ]
        ])
        for step in steps_qp:
            step.set_color(YELLOW)
            step.add_background_rectangle()
        step1_qp, step2_qp, step3_qp, step4_qp, step5_qp = steps_qp

        # 1. Find the endpoint
        step1_qp.next_to(time_axis.number_to_point(4.5), UP)
        end_horiz_line = DashedLine(LEFT_SIDE, RIGHT_SIDE, color=YELLOW)
        end_horiz_line.move_to(pos_axis.number_to_point(-4))
        end_horiz_line.horizontally_center()
        end_brace_line = DashedLine(time_axis.number_to_point(8),
                                    walk_q.get_end_point())
        end_brace = Brace(end_brace_line, direction=RIGHT, color=YELLOW)
        h = TexMobject("h").set_color(YELLOW)
        end_brace.put_at_tip(h)
        self.play(Write(step1_qp), ShowCreation(end_horiz_line), run_time=1)
        self.play(GrowFromCenter(end_brace), GrowFromCenter(h))
        self.wait(1.5)
        self.play(FadeOut(step1_qp))

        # 2. Find the last time it GOES THROUGH half its final value
        half_point = walk_q.get_arrow_end_point(3)
        step2_qp.next_to(time_axis.number_to_point(4.5), UP)
        half_horiz_line = end_horiz_line.copy().shift(2 * UP)
        half_brace_line = DashedLine(time_axis.number_to_point(4), half_point)
        half_brace = Brace(half_brace_line, direction=RIGHT, color=YELLOW)
        half_h = TexMobject("\\frac{h}{2}").set_color(YELLOW)
        half_brace.put_at_tip(half_h)
        half_dot = Dot(half_point, color=YELLOW)
        self.play(FadeIn(step2_qp), run_time=1)
        self.wait(0.5)
        self.play(
            ReplacementTransform(end_brace, half_brace),
            ReplacementTransform(end_horiz_line, half_horiz_line),
            ReplacementTransform(h, half_h[0]),
            Write(half_h[1:]),
        )
        self.play(DrawBorderThenFill(half_dot))
        self.wait(1.5)
        self.play(
            FadeOut(VGroup(step2_qp, half_horiz_line, half_brace, half_h)))

        # 3. Split
        vert_line = DashedLine(2.5 * UP, 2.5 * DOWN, color=YELLOW)
        vert_line.move_to(half_point)
        step3_qp.next_to(vert_line, UP)
        left_part_q, right_part_q = parts_q
        self.play(ShowCreation(vert_line), Write(step3_qp), run_time=1)
        self.play(
            FadeOut(half_dot),
            left_part_q.shift,
            0.5 * DOWN + 0.5 * LEFT,
            right_part_q.shift,
            0.5 * UP + 0.5 * RIGHT,
        )
        self.wait(1.5)
        self.play(FadeOut(vert_line), FadeOut(step3_qp))

        # 4. Flip the first segment horizontally
        flip_axis = DashedLine(2 * UP, 2 * DOWN, color=GREY)
        flip_axis.move_to(left_part_q)
        step4_qp.next_to(flip_axis, DOWN)
        self.play(
            ShowCreation(flip_axis),
            Write(step4_qp),
            run_time=1,
        )
        self.play(
            left_part_q.flip,
            Animation(flip_axis),
        )
        self.wait(1.5)
        self.play(FadeOut(step4_qp), FadeOut(flip_axis))

        # 5. Put the pieces together
        step5_qp.shift(2.5 * DOWN)
        flip_arrow_anims = walk_q.get_flip_arrows_animation(3, color=ORANGE)
        self.play(Write(step5_qp), run_time=1)
        self.wait(0.5)
        self.play(flip_arrow_anims, right_part_q.set_color, ORANGE)
        self.wait(0.5)
        self.play(
            left_part_q.shift,
            2.5 * UP + 0.5 * RIGHT,
            right_part_q.shift,
            3.5 * UP + 0.5 * LEFT,
            Animation(step5_qp),
        )
        self.wait(0.5)
        self.play(FadeOut(step5_qp))
        self.wait(1.5)

        # Now Reset
        self.play(FadeOut(walk_q))
        self.play(FadeIn(walk_q_copy))
        self.wait()
Esempio n. 19
0
 def write_vector_coordinates(self, vector, **kwargs):
     coords = vector_coordinate_label(vector, **kwargs)
     self.play(Write(coords))
     return coords
Esempio n. 20
0
    def construct(self):
        # Setup
        axes_group = self.axes_group
        title_pq = self.title_pq
        walk_p = self.walk_p
        parts_p = self.parts_p
        r_arrow = self.r_arrow
        self.add(axes_group, title_pq, walk_p, r_arrow)
        walk_p_copy = walk_p.copy()

        # P_4 -> Q_4
        steps_pq = VGroup(*[
            TextMobject(text) for text in [
                "1. 第一步是沿着正方向走的", "2. 找到第一次到达最大值的时刻", "3. 在这个时刻上进行分割",
                "4. 将第一段水平翻转", "5. 拼接两个片段"
            ]
        ])
        for step in steps_pq:
            step.set_color(YELLOW)
            step.add_background_rectangle()
        step1_pq, step2_pq, step3_pq, step4_pq, step5_pq = steps_pq

        # 1. Check the first step of the walk
        step1_circle = Circle(color=YELLOW)
        first_arrow = walk_p.get_arrow_by_number(0)
        step1_circle.surround(first_arrow)
        step1_pq.next_to(step1_circle, RIGHT + DOWN)
        self.play(ShowCreation(step1_circle), Write(step1_pq), run_time=1)
        self.wait(1.5)
        self.play(FadeOut(step1_circle), FadeOut(step1_pq))

        # 2. Find the first time it reaches the maximum
        peak = walk_p.get_arrow_end_point(3)
        horiz_line = DashedLine(2.5 * LEFT, 2.5 * RIGHT, color=YELLOW)
        horiz_line.move_to(peak)
        dot = Dot(color=YELLOW)
        dot.move_to(peak)
        step2_pq.next_to(horiz_line, UP)
        self.play(ShowCreation(horiz_line),
                  DrawBorderThenFill(dot),
                  Write(step2_pq),
                  run_time=1)
        self.wait(1.5)
        self.play(FadeOut(horiz_line), FadeOut(step2_pq))

        # 3. Split
        vert_line = DashedLine(2.5 * UP, 2.5 * DOWN, color=YELLOW)
        vert_line.move_to(peak)
        step3_pq.next_to(vert_line, DOWN)
        left_part_p, right_part_p = parts_p
        self.play(ShowCreation(vert_line), Write(step3_pq), run_time=1)
        self.play(
            FadeOut(dot),
            left_part_p.shift,
            0.5 * DOWN + 0.5 * LEFT,
            right_part_p.shift,
            DOWN + 0.5 * RIGHT,
        )
        self.wait(1.5)
        self.play(FadeOut(vert_line), FadeOut(step3_pq))

        # 4. Flip the first segment horizontally
        flip_axis = DashedLine(2 * UP, 2 * DOWN, color=GREY)
        flip_axis.move_to(left_part_p)
        step4_pq.next_to(flip_axis, DOWN)
        self.play(
            ShowCreation(flip_axis),
            Write(step4_pq),
            run_time=1,
        )
        self.play(
            left_part_p.flip,
            Animation(flip_axis),
        )
        self.wait(1.5)
        self.play(FadeOut(step4_pq), FadeOut(flip_axis))

        # 5. Put the pieces together
        step5_pq.move_to(dot)
        flip_arrow_anims = walk_p.get_flip_arrows_animation(3, color=GREEN)
        self.play(Write(step5_pq), run_time=1)
        self.wait(0.5)
        self.play(flip_arrow_anims, right_part_p.set_color, GREEN)
        self.wait(0.5)
        self.play(
            left_part_p.shift,
            1.5 * DOWN + 0.5 * RIGHT,
            right_part_p.shift,
            3 * DOWN + 0.5 * LEFT,
            Animation(step5_pq),
        )
        self.wait(0.5)
        self.play(FadeOut(step5_pq))
        self.wait(1.5)

        # Now Reset
        self.play(FadeOut(walk_p))
        self.play(FadeIn(walk_p_copy))
        self.wait()