Beispiel #1
0
    def construct(self):
        # Setup
        pos_axis = NumberLine(x_min=-3.5, x_max=3.5, color=WHITE)
        pos_axis.rotate(np.pi / 2)
        pos_axis.add_tip()
        time_axis = NumberLine(x_min=0, x_max=9.5, color=WHITE)
        time_axis.add_tip()
        house = House()
        house.rotate(np.pi / 2)
        house.place_on(pos_axis.number_to_point(0))
        zero_drunk = Drunk(direction=UP, color=self.zero_color)
        zero_drunk.step_on(pos_axis.number_to_point(0))
        neg_drunk = Drunk(direction=UP, color=self.neg_color)
        neg_drunk.step_on(pos_axis.number_to_point(0))
        group = VGroup(house, VGroup(pos_axis, time_axis), zero_drunk,
                       neg_drunk)
        group.to_edge(LEFT)
        pos_text = TextMobject("位置")
        pos_text.next_to(pos_axis.number_to_point(3.5), LEFT)
        time_text = TextMobject("时间")
        time_text.next_to(time_axis.number_to_point(9.5), DOWN)
        self.add(group, pos_text, time_text)
        old_zero_drunk = zero_drunk.copy()
        old_neg_drunk = neg_drunk.copy()

        # Start Wandering
        zero_sequence = "UUUDDDDU"
        zero_walk = RandomWalk1DArrow(
            zero_sequence,
            up_color=self.zero_color,
            down_color=self.zero_color,
        )
        zero_walk.move_start_to(pos_axis.number_to_point(0))
        neg_sequence = "DDUDDUDU"
        neg_walk = RandomWalk1DArrow(
            neg_sequence,
            up_color=self.neg_color,
            down_color=self.neg_color,
        )
        neg_walk.move_start_to(pos_axis.number_to_point(0))
        for k, (zero_char,
                neg_char) in enumerate(zip(zero_sequence, neg_sequence)):
            zero_increment = 1 if zero_char == "U" else -1
            neg_increment = 1 if neg_char == "U" else -1
            zero_arrow = zero_walk.get_arrow_by_number(k)
            neg_arrow = neg_walk.get_arrow_by_number(k)
            self.play(DrunkWander(zero_drunk, zero_increment, direction=UP),
                      DrunkWander(neg_drunk, neg_increment, direction=UP),
                      ShowCreation(zero_arrow), ShowCreation(neg_arrow))
        self.wait()

        # Reset
        self.play(
            Transform(zero_drunk, old_zero_drunk),
            Transform(neg_drunk, old_neg_drunk),
            FadeOut(zero_walk),
            FadeOut(neg_walk),
        )
        self.wait()
Beispiel #2
0
    def __init__(self, pi_creature, **kwargs):
        assert hasattr(pi_creature, "bubble")
        digest_config(self, kwargs, locals())

        pi_creature.generate_target()
        pi_creature.target.change_mode(self.target_mode)
        if self.look_at_arg is not None:
            pi_creature.target.look_at(self.look_at_arg)

        AnimationGroup.__init__(
            self,
            MoveToTarget(pi_creature),
            FadeOut(pi_creature.bubble),
            FadeOut(pi_creature.bubble.content),
        )
Beispiel #3
0
    def __init__(self,
                 eq1,
                 eq2,
                 regex,
                 regex2=None,
                 map_list=None,
                 align_char=None):
        # align equations
        if align_char:
            difference_vec = \
                self.mob_from_char(eq1, eq1.tex_string, align_char).get_center() - \
                self.mob_from_char(eq2, eq2.tex_string, align_char).get_center()
        else:
            difference_vec = eq1.get_center() - eq2.get_center()
        eq2.shift(difference_vec)

        if regex2 is None:
            g1 = self.split_by_regex(eq1, regex)
            g2 = self.split_by_regex(eq2, regex)
            assert (len(g1.submobjects) == len(g2.submobjects))
            trans = ReplacementTransform(g1, g2)
            AnimationGroup.__init__(self, trans)
        else:
            assert (map_list)
            g1 = self.split_by_regex(eq1, regex)
            g2 = self.split_by_regex(eq2, regex2)
            self.g1 = g1
            self.g2 = g2
            G1 = VGroup()
            G2 = VGroup()
            F1 = Group()
            F2 = Group()
            g1_nodes = set(pair[0] for pair in map_list)
            g2_nodes = set(pair[1] for pair in map_list)
            while map_list:
                l1 = [g1.submobjects[map_list[0][0]]]
                l2 = [g2.submobjects[map_list[0][1]]]
                new_list = []
                for i in range(1, len(map_list)):
                    if map_list[i][0] == map_list[0][0]:
                        l2.append(g2.submobjects[map_list[i][1]])
                    elif map_list[i][1] == map_list[0][1]:
                        l1.append(g1.submobjects[map_list[i][0]])
                    else:
                        new_list.append(map_list[i])
                map_list = new_list
                G1.submobjects.append(VGroup(*l1))
                G2.submobjects.append(VGroup(*l2))
            for i in range(len(g1.submobjects)):
                if i not in g1_nodes:
                    F1.submobjects.append(g1.submobjects[i])
            for i in range(len(g2.submobjects)):
                if i not in g2_nodes:
                    F2.submobjects.append(g2.submobjects[i])
            self.g1 = g1
            self.g2 = g2
            trans = ReplacementTransform(G1, G2)
            fadeout = FadeOut(F1)
            fadein = FadeIn(F2)
            AnimationGroup.__init__(self, trans, fadeout, fadein)
Beispiel #4
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)
Beispiel #5
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)
Beispiel #6
0
    def construct(self):
        morty = Mortimer()
        morty.next_to(ORIGIN, DOWN)

        patreon_logo = PatreonLogo()
        patreon_logo.to_edge(UP)

        n_patrons = len(self.specific_patrons)
        patrons = map(TextMobject, self.specific_patrons)
        num_groups = float(len(patrons)) / self.max_patron_group_size
        proportion_range = np.linspace(0, 1, num_groups + 1)
        indices = (len(patrons) * proportion_range).astype('int')
        patron_groups = [
            VGroup(*patrons[i:j])
            for i, j in zip(indices, indices[1:])
        ]

        for i, group in enumerate(patron_groups):
            left_group = VGroup(*group[:len(group) / 2])
            right_group = VGroup(*group[len(group) / 2:])
            for subgroup, vect in (left_group, LEFT), (right_group, RIGHT):
                subgroup.arrange_submobjects(DOWN, aligned_edge=LEFT)
                subgroup.scale(self.patron_scale_val)
                subgroup.to_edge(vect)

        last_group = None
        for i, group in enumerate(patron_groups):
            anims = []
            if last_group is not None:
                self.play(
                    FadeOut(last_group),
                    morty.look, UP + LEFT
                )
            else:
                anims += [
                    DrawBorderThenFill(patreon_logo),
                ]
            self.play(
                LaggedStart(
                    FadeIn, group,
                    run_time=2,
                ),
                morty.change, "gracious", group.get_corner(UP + LEFT),
                *anims
            )
            self.play(morty.look_at, group.get_corner(DOWN + LEFT))
            self.play(morty.look_at, group.get_corner(UP + RIGHT))
            self.play(morty.look_at, group.get_corner(DOWN + RIGHT))
            self.play(Blink(morty))
            last_group = group
Beispiel #7
0
    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()
Beispiel #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
Beispiel #9
0
 def update_mobject(self, new_mob, animate=True):
     """
     Returns a list of animations of the mobject being updated
     """
     ret = []
     if animate:
         if type(self.mobject) == Line and type(new_mob) == Arrow:
             ret.extend([
                 FadeOut(self.mobject, parent=self),
                 FadeIn(new_mob, parent=self),
             ])
         else:
             ret.extend(
                 [ReplacementTransform(self.mobject, new_mob, parent=self)])
     else:
         if hasattr(self, "mobject"):
             self.remove(self.mobject)
         self.add(new_mob)
     self.mobject = new_mob
     return ret
Beispiel #10
0
 def __init__(self, drunk, pos, total_time=1, turn_ratio=0.25):
     anims = []
     if self.is_same_direction(drunk, pos):
         anims.append(ApplyMethod(drunk.step_on, pos, run_time=total_time))
     else:
         turn_target = drunk.deepcopy().turn_around()
         move_target = turn_target.deepcopy().step_on(pos)
         ## TODO: This part is currently broken!
         anims.append(
             Succession(
                 ApplyMethod(drunk.turn_around,
                             run_time=turn_ratio * total_time),
                 ApplyMethod(turn_target.step_on,
                             pos,
                             run_time=(1 - turn_ratio) * total_time),
                 FadeOut(turn_target, run_time=0),
                 Transform(drunk, move_target, run_time=0),
             ))
         drunk.change_direction()
     AnimationGroup.__init__(self, *anims)
Beispiel #11
0
    def construct(self):
        # Setup
        self.set_camera_orientation(phi = np.pi/3, theta = 3*np.pi/4)
        self.begin_ambient_camera_rotation(np.pi/50)

        # Part 1: Increasing the order
        for order in range(1, self.max_order+1):
            if order == 1:
                fractal = HilbertCurve3D(order = 1)
                self.play(ShowCreation(fractal), run_time = 2)
                cur_order = fractal.order
            else:
                new_fractal = HilbertCurve3D(order = cur_order + 1)
                self.play(Transform(fractal, new_fractal))
                cur_order = new_fractal.order
                self.wait(2)
        self.wait(5)
        self.play(FadeOut(fractal))
        self.wait(3)

        # Part 2: Show one-touch construction
        self.play(ShowCreation(fractal, run_time = 60))
        self.wait(5)

        # Part 3: Decreasing the order till it vanishes
        for k in reversed(range(1, self.max_order)):
            new_fractal = HilbertCurve3D(order = cur_order - 1)
            self.play(Transform(fractal, new_fractal))
            cur_order = new_fractal.order
            self.wait(2)
        self.play(Uncreate(fractal), run_time = 1)

        # The end
        self.stop_ambient_camera_rotation()
        self.set_camera_orientation(phi = 0, theta = -np.pi/2)
        author = TextMobject("@Solara570")
        author.scale(1.5)
        author.to_corner(RIGHT+DOWN)
        self.play(FadeIn(author), run_time = 1)
        self.wait(2)
Beispiel #12
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)
Beispiel #13
0
    def construct(self):
        # Setup
        pos_axis = NumberLine(x_min=-3.5, x_max=3.5, color=WHITE)
        pos_axis.rotate(np.pi / 2)
        pos_axis.add_tip()
        time_axis = NumberLine(x_min=0, x_max=9.5, color=WHITE)
        time_axis.add_tip()
        house = House()
        house.rotate(np.pi / 2)
        house.place_on(pos_axis.number_to_point(0))
        drunk = Drunk(direction=UP)
        drunk.step_on(pos_axis.number_to_point(0))
        group = VGroup(house, VGroup(pos_axis, time_axis), drunk)
        group.to_edge(LEFT)
        pos_text = TextMobject("位置")
        pos_text.next_to(pos_axis.number_to_point(3.5), LEFT)
        time_text = TextMobject("时间")
        time_text.next_to(time_axis.number_to_point(9.5), DOWN)
        self.add(group, pos_text, time_text)
        old_drunk = drunk.copy()

        # Start Wandering
        sequence = "UDUDDDUD"
        random_walk = RandomWalk1DArrow(sequence)
        random_walk.move_start_to(pos_axis.number_to_point(0))
        for k, walk_char in enumerate(sequence):
            increment = 1 if walk_char == "U" else -1
            arrow = random_walk.get_arrow_by_number(k)
            self.play(
                DrunkWander(drunk, increment, direction=UP),
                ShowCreation(arrow),
            )
        self.wait()

        # Reset
        self.play(Transform(drunk, old_drunk), FadeOut(random_walk))
        self.wait()
Beispiel #14
0
    def show_the_solution(self):
        # Prepare for the solution
        pre_solve = VGroup(*self.question[::2])
        self.play(
            ReplacementTransform(pre_solve, self.solve),
            FadeOut(self.question[1]),
            run_time = 1,
        )
        self.wait()

        # Manipulate LHS
        old_l_part, r_part = self.equation
        new_l_part = ExpTower(order = self.highest_order+1, is_infinite = True)
        new_l_part.match_height(old_l_part)
        new_l_part.next_to(r_part, LEFT, aligned_edge = DOWN)
        old_rect, new_rect = rects = [
            CoverRectangle(part, text = "2")
            for part in (old_l_part, new_l_part.get_exponent())
        ]
        old_two, new_two = twos = [
            rect.get_text_mob()
            for rect in rects
        ]
        self.play(DrawBorderThenFill(old_rect, run_time = 1))
        self.wait()
        self.play(
            ReplacementTransform(old_l_part, new_l_part),
            ReplacementTransform(old_rect, new_rect),
        )
        self.wait()
        new_equation = VGroup(new_l_part, r_part, new_rect)
        new_equation.generate_target()
        new_equation.target.scale(0.8)
        new_equation.target.shift(UP)
        self.play(MoveToTarget(new_equation))
        self.wait()

        # A little bit clean-up
        source_eq = VGroup(*[
            mob.copy()
            for mob in (new_l_part.get_base(), new_two, r_part[0], r_part[1])
        ])
        source_eq.generate_target()
        target_eq = TexMobject("x", "^2", "=", "2")
        target_eq.scale(3).next_to(source_eq, DOWN, buff = 1)
        for k, (old_part, new_part) in enumerate(zip(source_eq.target, target_eq)):
            old_part.move_to(new_part)
            if k == 1:
                old_part.scale(0.5)
                old_part.shift(RIGHT/4)
        self.play(
            FadeOut(new_rect),
            MoveToTarget(source_eq),
        )
        self.wait()

        # Reveal the final answer
        result = TexMobject("x", "=", "\\sqrt", "2")
        result.set_height(source_eq.get_height() * 0.7)
        result.move_to(source_eq)
        self.play(*[
            ReplacementTransform(source_eq[m], result[n], path_arc = angle)
            for m, n, angle in [(0, 0, 0), (1, 2, -TAU/3), (2, 1, 0), (3, 3, 0)]
        ])
        self.wait()
        qed = QEDSymbol()
        qed.next_to(result, RIGHT, aligned_edge = DOWN, buff = 1.5)
        self.play(FadeIn(qed))
        self.wait()
Beispiel #15
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()
Beispiel #16
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()
Beispiel #17
0
 def fadeout_everthing(self):
     mobs = VGroup(self.mobjects)
     self.play(FadeOut(mobs), run_time = 1)