Example #1
0
    def scroll_through_patrons(self):
        logo_box = Square(side_length=2.5)
        logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF)
        total_width = FRAME_X_RADIUS - logo_box.get_right()[0]

        black_rect = Rectangle(
            fill_color=BLACK,
            fill_opacity=1,
            stroke_width=0,
            width=FRAME_WIDTH,
            height=0.6 * FRAME_HEIGHT,
        )
        black_rect.to_edge(UP, buff=0)
        line = DashedLine(FRAME_X_RADIUS * LEFT, FRAME_X_RADIUS * RIGHT)
        line.move_to(ORIGIN)
        self.add(line)

        thanks = TextMobject("Funded by the community, with special thanks to:")
        thanks.scale(0.9)
        thanks.next_to(black_rect.get_bottom(), UP, SMALL_BUFF)
        thanks.set_color(YELLOW)
        underline = Line(LEFT, RIGHT)
        underline.scale_to_fit_width(thanks.get_width() + MED_SMALL_BUFF)
        underline.next_to(thanks, DOWN, SMALL_BUFF)
        thanks.add(underline)
        self.add(thanks)

        patrons = VGroup(*map(TextMobject, self.specific_patrons))
        patrons.scale(self.patron_scale_val)
        for patron in patrons:
            if patron.get_width() > self.max_patron_width:
                patron.scale_to_fit_width(self.max_patron_width)
        columns = VGroup(*[
            VGroup(*patrons[i::self.n_patron_columns])
            for i in range(self.n_patron_columns)
        ])
        for column in columns:
            for n, name in enumerate(column):
                name.shift(n * self.name_y_spacing * DOWN)
        columns.arrange_submobjects(
            RIGHT, buff=LARGE_BUFF,
            aligned_edge=UP,
        )
        columns.scale_to_fit_width(total_width - 1)
        columns.next_to(black_rect, DOWN, 3 * LARGE_BUFF)
        columns.to_edge(RIGHT)

        thanks.align_to(columns, alignment_vect=RIGHT)

        self.play(
            columns.move_to, 2 * DOWN, DOWN,
            columns.to_edge, RIGHT,
            Animation(black_rect),
            Animation(line),
            Animation(thanks),
            rate_func=None,
            run_time=self.run_time,
        )
Example #2
0
    def add_words(self):
        # Wallis product
        product = TexMobject(*(["\\text{Wallis公式:}"] + [
            "{%d \\over %d} \\," % (wallis_numer(n), wallis_denom(n))
            for n in range(1, 8)
        ] + ["\\cdots = {\\pi \\over 2}"])).set_color(YELLOW)
        rect = SurroundingRectangle(product, color=YELLOW, buff=0.25)
        wallis_product = VGroup(product, rect)
        wallis_product.set_width(6)

        # All those steps
        nums = [TextMobject("%d. " % k) for k in [1, 2, 3, 4]]
        words = [
            TextMobject(word) for word in [
                "构造合适的矩形边长",
                "同种颜色的矩形的面积之和恒为1",
                "整个图形又像一个${1 \\over 4}$圆,半径是",
                "比较${1 \\over 4}$圆与矩形的面积",
            ]
        ]
        formulae = [
            TextMobject(formula) for formula in [
                "$a_0 = 1,\\, a_n = {1 \\over 2} \cdot {3 \\over 4} \cdots {2n-1 \\over 2n} (n \geq 1)$",
                "$a_0 a_n + a_1 a_{n-1} + \\cdots + a_n a_0 = 1$",
                "$\\begin{aligned} \
                r_n & = a_0 + a_1 + \\cdots + a_{n-1} \\\\ \
                    & = \\textstyle{3 \\over 2} \cdot {5 \\over 4} \cdots {2n-1 \\over 2n-2} \
                    \\quad (n \geq 2) \
                \\end{aligned}$",
                "${1 \\over 4} \\pi {r_n}^2 \\approx n \\quad \\Rightarrow \\quad \\text{Wallis公式}$"
            ]
        ]

        steps = VGroup()
        for num, word, formula in zip(nums, words, formulae):
            num.next_to(word, LEFT)
            formula.next_to(word, DOWN, aligned_edge=LEFT)
            steps.add(VGroup(num, word, formula))
        steps.arrange_submobjects(DOWN, buff=0.6, aligned_edge=LEFT)
        steps.set_width(6)
        steps.next_to(wallis_product, DOWN)
        VGroup(wallis_product, steps).center().to_edge(RIGHT, buff=0.15)

        # Sep line and QED
        sep_line = DashedLine(2 * TOP, 2 * BOTTOM, color=GREY, buff=0.5)
        sep_line.next_to(steps, LEFT)
        qed = QEDSymbol(height=0.570 / 2)
        qed.next_to(steps[-1][-1][-1], RIGHT, aligned_edge=DOWN)

        # Add everything
        self.add(wallis_product, steps, sep_line, qed)
Example #3
0
    def scroll_through_patrons(self):
        logo_box = Square(side_length=2.5)
        logo_box.to_corner(DOWN + LEFT, buff=MED_LARGE_BUFF)
        total_width = FRAME_X_RADIUS - logo_box.get_right()[0]

        black_rect = Rectangle(fill_color=BLACK,
                               fill_opacity=1,
                               stroke_width=0,
                               width=FRAME_WIDTH,
                               height=1.1 * FRAME_Y_RADIUS)
        black_rect.to_edge(UP, buff=0)
        line = DashedLine(FRAME_X_RADIUS * LEFT, FRAME_X_RADIUS * RIGHT)
        line.move_to(black_rect, DOWN)
        line.shift(SMALL_BUFF * SMALL_BUFF * DOWN)
        self.add(line)

        patrons = VGroup(*map(TextMobject, self.specific_patrons))
        patrons.scale(self.patron_scale_val)
        for patron in patrons:
            if patron.get_width() > self.max_patron_width:
                patron.scale_to_fit_width(self.max_patron_width)
        columns = VGroup(*[
            VGroup(*patrons[i::self.n_patron_columns])
            for i in range(self.n_patron_columns)
        ])
        for column in columns:
            for n, name in enumerate(column):
                name.shift(n * self.name_y_spacing * DOWN)
        columns.arrange_submobjects(
            RIGHT,
            buff=LARGE_BUFF,
            aligned_edge=UP,
        )
        columns.scale_to_fit_width(total_width - 1)
        columns.next_to(black_rect, DOWN, 3 * LARGE_BUFF)
        columns.to_edge(RIGHT)

        self.play(
            columns.move_to,
            2 * DOWN,
            DOWN,
            columns.to_edge,
            RIGHT,
            Animation(black_rect),
            rate_func=None,
            run_time=self.run_time,
        )
Example #4
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()
Example #5
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()
Example #6
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()
        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)
        group = VGroup(pos_axis, time_axis, pos_text, time_text)
        group.to_edge(LEFT, buff=2)
        self.add(group)

        # Some preparations
        sequences = [
            "UDDDUDUD", "DUUDDDUD", "DDUUUDUD", "UUUDDUDU", "UDDDUDUD"
        ]
        nums = [1, 3, 7, -1, 1]
        walks = [
            RandomWalk1DArrow(sequence).move_start_to(
                pos_axis.number_to_point(0)) for sequence in sequences
        ]
        parts = [walk.split_at(num) for walk, num in zip(walks, nums)]
        split_lines = [
            DashedLine(TOP, BOTTOM, color = GREY) \
            .move_to(time_axis.number_to_point(num+1))
            for num in nums
        ]
        zero_words = [
            TextMobject("“正点到家” \\\\ $P_%s$" % str((num+1)//2)) \
            .next_to(line, LEFT).shift(2.8 * DOWN).set_color(ORANGE)
            for num, line in zip(nums, split_lines)
        ]
        nocross_words = [
            TextMobject("“不经过家门” \\\\ $Q_%s$" % str(4-(num+1)//2)) \
            .next_to(line, RIGHT).shift(2.8 * DOWN).set_color(GREEN)
            for num, line in zip(nums, split_lines)
        ]
        for words, direction in zip([zero_words, nocross_words],
                                    [RIGHT, LEFT]):
            for word in words:
                text, symbol = VGroup(word[:-2]), VGroup(word[-2:])
                symbol.scale(1.5)
                symbol.next_to(text, DOWN, aligned_edge=direction)
                word.add_background_rectangle()

        # Demonstrate how to split
        self.add(walks[0], split_lines[0], zero_words[0], nocross_words[0])
        l = len(walks)
        for k in range(l - 1):
            cur_walk = walks[k]
            cur_line = split_lines[k]
            cur_zero_word = zero_words[k]
            cur_nocross_word = nocross_words[k]
            next_walk = walks[k + 1]
            next_line = split_lines[k + 1]
            next_zero_word = zero_words[k + 1]
            next_nocross_word = nocross_words[k + 1]
            part1, part2 = parts[k]
            cur_walk.save_state()
            self.play(
                part1.set_color,
                ORANGE,
                part2.set_color,
                GREEN,
            )
            self.wait()
            self.play(cur_walk.restore)
            self.wait()
            self.play(
                ReplacementTransform(cur_walk, next_walk),
                ReplacementTransform(cur_line, next_line),
                ReplacementTransform(cur_zero_word, next_zero_word),
                ReplacementTransform(cur_nocross_word, next_nocross_word),
            )
            self.wait()