Пример #1
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)
Пример #2
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()
Пример #3
0
 def construct(self):
     author = TextMobject("@Solara570")
     support = TextMobject("(Powered by @3Blue1Brown)")
     author.scale(1.8)
     support.match_width(author)
     group = VGroup(author, support)
     group.arrange_submobjects(DOWN)
     group.to_corner(RIGHT+DOWN)
     self.play(FadeIn(group))
     self.wait(2)
Пример #4
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]
Пример #5
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
Пример #6
0
 def show_comments(self):
     height = 1.5
     simple, but, trap = texts = TextMobject("简单直观", "但是", "暗藏陷阱")
     texts.scale(1.5)
     texts.arrange_submobjects(DOWN, buff = 0.8)
     tick = TickButton()
     tick.set_height(height)
     tick.next_to(simple, RIGHT)
     danger = DangerSign()
     danger.set_height(height)
     danger.next_to(trap, LEFT)
     words = [(simple, tick), (but, ), (danger, trap)]
     colors = [GREEN, WHITE, RED]
     for word, color in zip(words, colors):
         VGroup(word).set_color(color)
         self.play(FadeIn(VGroup(word)), run_time = 1)
         self.wait(0.5)
     self.wait()
     self.words = words
Пример #7
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
Пример #8
0
 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,
                   submobject_mode="lagged_start"))
     return result
Пример #9
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)
Пример #10
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)
Пример #11
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()
Пример #12
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()
Пример #13
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()