Пример #1
0
    def construct(self):
        title = TextMobject("(A few) Fathers of Calculus")
        title.to_edge(UP)
        self.add(title)

        men = Mobject()
        for name in self.names:
            image = ImageMobject(name, invert=False)
            image.scale_to_fit_height(self.picture_height)
            title = TextMobject(name)
            title.scale(0.8)
            title.next_to(image, DOWN)
            image.add(title)
            men.add(image)
        men.arrange_submobjects(RIGHT, aligned_edge=UP)
        men.shift(DOWN)

        discover_brace = Brace(Mobject(*men[:3]), UP)
        discover = discover_brace.get_text("Discovered it")
        VGroup(discover_brace, discover).highlight(BLUE)
        rigor_brace = Brace(Mobject(*men[3:]), UP)
        rigor = rigor_brace.get_text("Made it rigorous")
        rigor.shift(0.1 * DOWN)
        VGroup(rigor_brace, rigor).highlight(YELLOW)

        for man in men:
            self.play(FadeIn(man))
        self.play(GrowFromCenter(discover_brace), Write(discover, run_time=1))
        self.play(GrowFromCenter(rigor_brace), Write(rigor, run_time=1))
        self.dither()
Пример #2
0
    def construct(self):
        words = TextMobject("Order 2 Pseudo-Hilbert Curve")
        words.to_edge(UP, buff=0.3)
        words.highlight(GREEN)
        grid2 = Grid(2, 2)
        grid4 = Grid(4, 4, point_thickness=2)
        # order_1_curve = HilbertCurve(order = 1)
        # squaggle_curve = order_1_curve.copy().apply_function(
        #     lambda (x, y, z) : (x + np.cos(3*y), y + np.sin(3*x), z)
        # )
        # squaggle_curve.show()
        mini_curves = [
            HilbertCurve(order=1).scale(0.5).shift(1.5 * vect)
            for vect in [LEFT + DOWN, LEFT + UP, RIGHT + UP, RIGHT + DOWN]
        ]
        last_curve = mini_curves[0]
        naive_curve = Mobject(last_curve)
        for mini_curve in mini_curves[1:]:
            line = Line(last_curve.points[-1], mini_curve.points[0])
            naive_curve.add(line, mini_curve)
            last_curve = mini_curve
        naive_curve.ingest_sub_mobjects()
        naive_curve.gradient_highlight(RED, GREEN)
        order_2_curve = HilbertCurve(order=2)

        self.add(words, grid2)
        self.dither()
        self.play(ShowCreation(grid4))
        self.play(*[ShowCreation(mini_curve) for mini_curve in mini_curves])
        self.dither()
        self.play(ShowCreation(naive_curve, run_time=5))
        self.remove(*mini_curves)
        self.dither()
        self.play(Transform(naive_curve, order_2_curve))
        self.dither()
Пример #3
0
    def construct(self, order):
        start_color, end_color = RED, GREEN
        curve = HilbertCurve(order = order)
        line = Line(5*LEFT, 5*RIGHT)
        for mob in curve, line:
            mob.gradient_highlight(start_color, end_color)
        freq_line = get_freq_line()
        freq_line.replace(line, stretch = True)

        unit = 6./(2**order) #sidelength of pixel
        up = unit*UP
        right = unit*RIGHT
        lower_left = 3*(LEFT+DOWN)
        squares = Mobject(*[
            Square(
                side_length = unit, 
                color = WHITE
            ).shift(x*right+y*up)
            for x, y in it.product(range(2**order), range(2**order))
        ])
        squares.center()
        targets = Mobject()
        for square in squares.submobjects:
            center = square.get_center()
            distances = np.apply_along_axis(
                lambda p : np.linalg.norm(p-center),
                1,
                curve.points
            )
            index_along_curve = np.argmin(distances)
            fraction_along_curve = index_along_curve/float(curve.get_num_points())
            target = square.copy().center().scale(0.8/(2**order))
            line_index = int(fraction_along_curve*line.get_num_points())
            target.shift(line.points[line_index])
            targets.add(target)


        self.add(squares)
        self.play(ShowCreation(
            curve,
            run_time = 5, 
            rate_func = None
        ))
        self.dither()
        self.play(
            Transform(curve, line),
            Transform(squares, targets),
            run_time = 3
        )
        self.dither()
        self.play(ShowCreation(freq_line))
        self.dither()
Пример #4
0
    def construct(self):
        words = TextMobject("Order 2 Pseudo-Hilbert Curve")
        words.to_edge(UP, buff = 0.3)
        words.highlight(GREEN)
        grid2 = Grid(2, 2)
        grid4 = Grid(4, 4, stroke_width = 2)
        # order_1_curve = HilbertCurve(order = 1)
        # squaggle_curve = order_1_curve.copy().apply_function(
        #     lambda (x, y, z) : (x + np.cos(3*y), y + np.sin(3*x), z)
        # )
        # squaggle_curve.show()
        mini_curves = [
            HilbertCurve(order = 1).scale(0.5).shift(1.5*vect)
            for vect in [
                LEFT+DOWN,
                LEFT+UP,
                RIGHT+UP,
                RIGHT+DOWN
            ]
        ]
        last_curve = mini_curves[0]
        naive_curve = Mobject(last_curve)
        for mini_curve in mini_curves[1:]:
            line = Line(last_curve.points[-1], mini_curve.points[0])
            naive_curve.add(line, mini_curve)
            last_curve = mini_curve
        naive_curve.ingest_submobjects()
        naive_curve.gradient_highlight(RED, GREEN)
        order_2_curve = HilbertCurve(order = 2)

        self.add(words, grid2)
        self.dither()
        self.play(ShowCreation(grid4))
        self.play(*[
            ShowCreation(mini_curve)
            for mini_curve in mini_curves
        ])
        self.dither()
        self.play(ShowCreation(naive_curve, run_time = 5))
        self.remove(*mini_curves)
        self.dither()
        self.play(Transform(naive_curve, order_2_curve))
        self.dither()
Пример #5
0
    def construct(self):
        self.remove(self.get_primary_pi_creature())

        NUM_CONES = 7
        NUM_VISIBLE_CONES = 6
        INDICATOR_RADIUS = 0.5
        OPACITY_FOR_UNIT_INTENSITY = 1.0

        self.number_line = NumberLine(
            x_min=0,
            color=WHITE,
            number_at_center=1.6,
            stroke_width=1,
            numbers_with_elongated_ticks=range(1, 5),
            numbers_to_show=range(1, 5),
            unit_size=2,
            tick_frequency=0.2,
            line_to_number_buff=LARGE_BUFF,
            label_direction=UP,
        )

        self.number_line.label_direction = DOWN
        #self.number_line.shift(3*UP)

        self.number_line_labels = self.number_line.get_number_mobjects()
        self.add(self.number_line, self.number_line_labels)
        self.wait()

        origin_point = self.number_line.number_to_point(0)

        self.default_pi_creature_class = Randolph
        randy = self.get_primary_pi_creature()

        randy.scale(0.5)
        randy.flip()
        right_pupil = randy.pupils[1]
        randy.next_to(origin_point,
                      LEFT,
                      buff=0,
                      submobject_to_align=right_pupil)

        randy_copy = randy.copy()
        randy_copy.target = randy.copy().shift(DOWN)

        bubble = ThoughtBubble(direction=RIGHT,
                               width=4,
                               height=3,
                               file_name="Bubbles_thought.svg")
        bubble.next_to(randy, LEFT + UP)
        bubble.set_fill(color=BLACK, opacity=1)

        self.play(
            randy.change,
            "wave_2",
            ShowCreation(bubble),
        )

        euler_sum = TexMobject("1", "+", "{1\over 4}", "+", "{1\over 9}", "+",
                               "{1\over 16}", "+", "{1\over 25}", "+",
                               "\cdots", " ")
        # the last entry is a dummy element which makes looping easier
        # used just for putting the fractions into the light indicators

        intensities = np.array([1. / (n + 1)**2 for n in range(NUM_CONES)])
        opacities = intensities * OPACITY_FOR_UNIT_INTENSITY

        # repeat:

        # fade in lighthouse
        # switch on / fade in ambient light
        # show creation / write light indicator
        # move indicator onto origin
        # while morphing and dimming
        # move indicator into thought bubble
        # while indicators already inside shift to the back
        # and while term appears in the series below

        point = self.number_line.number_to_point(1)
        v = point - self.number_line.number_to_point(0)
        light_source = LightSource()
        light_source.move_source_to(point)
        #light_source.ambient_light.move_source_to(point)
        #light_source.lighthouse.move_to(point)

        self.play(FadeIn(light_source.lighthouse))
        self.play(SwitchOn(light_source.ambient_light))

        # create an indicator that will move along the number line
        indicator = LightIndicator(
            color=LIGHT_COLOR,
            radius=INDICATOR_RADIUS,
            opacity_for_unit_intensity=OPACITY_FOR_UNIT_INTENSITY,
            show_reading=False)
        indicator_reading = euler_sum[0]
        indicator_reading.scale_to_fit_height(0.5 * indicator.get_height())
        indicator_reading.move_to(indicator.get_center())
        indicator.add(indicator_reading)
        indicator.tex_reading = indicator_reading
        # the TeX reading is too bright at full intensity
        indicator.tex_reading.set_fill(color=BLACK)
        indicator.foreground.set_fill(None, opacities[0])

        indicator.move_to(point)
        indicator.set_intensity(intensities[0])

        self.play(FadeIn(indicator))
        self.add_foreground_mobject(indicator)

        collection_point = np.array([-6., 2., 0.])
        left_shift = 0.2 * LEFT
        collected_indicators = Mobject()

        for i in range(2, NUM_VISIBLE_CONES + 1):

            previous_point = self.number_line.number_to_point(i - 1)
            point = self.number_line.number_to_point(i)

            v = point - previous_point
            #print v
            # Create and position the target indicator (next on number line).
            indicator_target = indicator.deepcopy()
            indicator_target.shift(v)

            # Here we make a copy that will move into the thought bubble.
            bubble_indicator = indicator.deepcopy()
            # And its target
            bubble_indicator_target = bubble_indicator.deepcopy()
            bubble_indicator_target.set_intensity(intensities[i - 2])

            # give the target the appropriate reading
            euler_sum[2 * i - 4].move_to(bubble_indicator_target)
            bubble_indicator_target.remove(bubble_indicator_target.tex_reading)
            bubble_indicator_target.tex_reading = euler_sum[2 * i - 4].copy()
            bubble_indicator_target.add(bubble_indicator_target.tex_reading)
            # center it in the indicator

            if bubble_indicator_target.tex_reading.get_tex_string() != "1":
                bubble_indicator_target.tex_reading.scale_to_fit_height(
                    0.8 * indicator.get_height())
            # the target is less bright, possibly switch to a white text color
            if bubble_indicator_target.intensity < 0.7:
                bubble_indicator.tex_reading.set_fill(color=WHITE)

            # position the target in the thought bubble
            bubble_indicator_target.move_to(collection_point)

            self.add_foreground_mobject(bubble_indicator)

            self.wait()

            self.play(
                Transform(bubble_indicator, bubble_indicator_target),
                collected_indicators.shift,
                left_shift,
            )

            collected_indicators.add(bubble_indicator)

            new_light = light_source.deepcopy()
            w = new_light.get_source_point()
            new_light.move_source_to(w + (i - 2) * v)
            w2 = new_light.get_source_point()

            self.add(new_light.lighthouse)
            self.play(
                Transform(indicator, indicator_target),
                new_light.lighthouse.shift,
                v,
            )
            new_light.move_source_to(w + (i - 1) * v)
            new_light.lighthouse.move_to(w + (i - 1) * v)

            self.play(SwitchOn(new_light.ambient_light), )

        # quickly switch on off-screen light cones
        for i in range(NUM_VISIBLE_CONES, NUM_CONES):
            indicator_start_time = 0.5 * (
                i + 1
            ) * FAST_SWITCH_ON_RUN_TIME / light_source.ambient_light.radius * self.number_line.unit_size
            indicator_stop_time = indicator_start_time + FAST_INDICATOR_UPDATE_TIME
            indicator_rate_func = squish_rate_func(  #smooth, 0.8, 0.9)
                smooth, indicator_start_time, indicator_stop_time)
            ls = LightSource()
            point = point = self.number_line.number_to_point(i)
            ls.move_source_to(point)
            self.play(
                SwitchOn(ls.ambient_light, run_time=FAST_SWITCH_ON_RUN_TIME), )

        # and morph indicator stack into limit value

        sum_indicator = LightIndicator(
            color=LIGHT_COLOR,
            radius=INDICATOR_RADIUS,
            opacity_for_unit_intensity=OPACITY_FOR_UNIT_INTENSITY,
            show_reading=False)
        sum_indicator.set_intensity(intensities[0] * np.pi**2 / 6)
        sum_indicator_reading = TexMobject("{\pi^2 \over 6}")
        sum_indicator_reading.set_fill(color=BLACK)
        sum_indicator_reading.scale_to_fit_height(0.8 *
                                                  sum_indicator.get_height())
        sum_indicator.add(sum_indicator_reading)
        sum_indicator.move_to(collection_point)

        self.play(Transform(collected_indicators, sum_indicator))

        self.wait()
Пример #6
0
    def construct(self):
        glass = Region(lambda x, y : y < 0, color = BLUE_E)
        self.generate_start_and_end_points()
        left = self.start_point[0]*RIGHT
        right = self.end_point[0]*RIGHT
        start_x = interpolate(left, right, 0.2)
        end_x = interpolate(left, right, 1.0)
        left_line = Line(self.start_point, left, color = RED_D)
        right_line = Line(self.end_point, right, color = RED_D)
        h_1, h_2 = map(TexMobject, ["h_1", "h_2"])
        h_1.next_to(left_line, LEFT)
        h_2.next_to(right_line, RIGHT)
        point_a = Dot(self.start_point)
        point_b = Dot(self.end_point)
        A = TextMobject("A").next_to(point_a, UP)
        B = TextMobject("B").next_to(point_b, DOWN)

        x = start_x
        left_brace = Brace(Mobject(Point(left), Point(x)))
        right_brace = Brace(Mobject(Point(x), Point(right)), UP)
        x_mob = TexMobject("x")
        x_mob.next_to(left_brace, DOWN)
        w_minus_x = TexMobject("w-x")
        w_minus_x.next_to(right_brace, UP)
        top_line = Line(self.start_point, x)
        bottom_line = Line(x, self.end_point)
        top_dist = TexMobject("\\sqrt{h_1^2+x^2}")
        top_dist.scale(0.5)
        a = 0.3
        n = top_line.get_num_points()
        point = top_line.points[int(a*n)]
        top_dist.next_to(Point(point), RIGHT, buff = 0.3)
        bottom_dist = TexMobject("\\sqrt{h_2^2+(w-x)^2}")
        bottom_dist.scale(0.5)
        n = bottom_line.get_num_points()
        point = bottom_line.points[int((1-a)*n)]
        bottom_dist.next_to(Point(point), LEFT, buff = 1)

        end_top_line = Line(self.start_point, end_x)
        end_bottom_line = Line(end_x, self.end_point)
        end_brace = Brace(Mobject(Point(left), Point(end_x)))
        end_x_mob = TexMobject("x").next_to(end_brace, DOWN)

        axes = Mobject(
            NumberLine(),
            NumberLine().rotate(np.pi/2).shift(7*LEFT)
        )
        graph = FunctionGraph(
            lambda x : 0.4*(x+1)*(x-3)+4,
            x_min = -2,
            x_max = 4
        )
        graph.highlight(YELLOW)
        Mobject(axes, graph).scale(0.2).to_corner(UP+RIGHT, buff = 1)
        axes.add(TexMobject("x", size = "\\small").next_to(axes, RIGHT))
        axes.add(TextMobject("Travel time", size = "\\small").next_to(
            axes, UP
        ))
        new_graph = graph.copy()
        midpoint = new_graph.points[new_graph.get_num_points()/2]
        new_graph.filter_out(lambda p : p[0] < midpoint[0])
        new_graph.reverse_points()
        pairs_for_end_transform = [
            (mob, mob.copy())
            for mob in top_line, bottom_line, left_brace, x_mob
        ]

        self.add(glass, point_a, point_b, A, B)
        line = Mobject(top_line, bottom_line).ingest_submobjects()
        self.play(ShowCreation(line))
        self.wait()
        self.play(
            GrowFromCenter(left_brace), 
            GrowFromCenter(x_mob)
        )
        self.play(
            GrowFromCenter(right_brace), 
            GrowFromCenter(w_minus_x)
        )
        self.play(ShowCreation(left_line), ShimmerIn(h_1))
        self.play(ShowCreation(right_line), GrowFromCenter(h_2))
        self.play(ShimmerIn(top_dist))
        self.play(GrowFromCenter(bottom_dist))
        self.wait(3)
        self.clear()
        self.add(glass, point_a, point_b, A, B, 
                 top_line, bottom_line, left_brace, x_mob)
        self.play(ShowCreation(axes))
        kwargs = {
            "run_time" : 4,
        }
        self.play(*[
            Transform(*pair, **kwargs)
            for pair in [
                (top_line, end_top_line),
                (bottom_line, end_bottom_line),
                (left_brace, end_brace),
                (x_mob, end_x_mob)
            ]
        ]+[ShowCreation(graph, **kwargs)])
        self.wait()
        self.show_derivatives(graph)
        line = self.show_derivatives(new_graph)
        self.add(line)
        self.play(*[
            Transform(*pair, rate_func = lambda x : 0.3*smooth(x))
            for pair in pairs_for_end_transform
        ])
        self.wait()
Пример #7
0
    def construct(self):
        glass = Region(lambda x, y : y < 0, color = BLUE_E)
        self.generate_start_and_end_points()
        left = self.start_point[0]*RIGHT
        right = self.end_point[0]*RIGHT
        start_x = interpolate(left, right, 0.2)
        end_x = interpolate(left, right, 1.0)
        left_line = Line(self.start_point, left, color = RED_D)
        right_line = Line(self.end_point, right, color = RED_D)
        h_1, h_2 = map(TexMobject, ["h_1", "h_2"])
        h_1.next_to(left_line, LEFT)
        h_2.next_to(right_line, RIGHT)
        point_a = Dot(self.start_point)
        point_b = Dot(self.end_point)
        A = TextMobject("A").next_to(point_a, UP)
        B = TextMobject("B").next_to(point_b, DOWN)

        x = start_x
        left_brace = Brace(Mobject(Point(left), Point(x)))
        right_brace = Brace(Mobject(Point(x), Point(right)), UP)
        x_mob = TexMobject("x")
        x_mob.next_to(left_brace, DOWN)
        w_minus_x = TexMobject("w-x")
        w_minus_x.next_to(right_brace, UP)
        top_line = Line(self.start_point, x)
        bottom_line = Line(x, self.end_point)
        top_dist = TexMobject("\\sqrt{h_1^2+x^2}")
        top_dist.scale(0.5)
        a = 0.3
        n = top_line.get_num_points()
        point = top_line.points[int(a*n)]
        top_dist.next_to(Point(point), RIGHT, buff = 0.3)
        bottom_dist = TexMobject("\\sqrt{h_2^2+(w-x)^2}")
        bottom_dist.scale(0.5)
        n = bottom_line.get_num_points()
        point = bottom_line.points[int((1-a)*n)]
        bottom_dist.next_to(Point(point), LEFT, buff = 1)

        end_top_line = Line(self.start_point, end_x)
        end_bottom_line = Line(end_x, self.end_point)
        end_brace = Brace(Mobject(Point(left), Point(end_x)))
        end_x_mob = TexMobject("x").next_to(end_brace, DOWN)

        axes = Mobject(
            NumberLine(),
            NumberLine().rotate(np.pi/2).shift(7*LEFT)
        )
        graph = FunctionGraph(
            lambda x : 0.4*(x+1)*(x-3)+4,
            x_min = -2,
            x_max = 4
        )
        graph.highlight(YELLOW)
        Mobject(axes, graph).scale(0.2).to_corner(UP+RIGHT, buff = 1)
        axes.add(TexMobject("x", size = "\\small").next_to(axes, RIGHT))
        axes.add(TextMobject("Travel time", size = "\\small").next_to(
            axes, UP
        ))
        new_graph = graph.copy()
        midpoint = new_graph.points[new_graph.get_num_points()/2]
        new_graph.filter_out(lambda p : p[0] < midpoint[0])
        new_graph.reverse_points()
        pairs_for_end_transform = [
            (mob, mob.copy())
            for mob in top_line, bottom_line, left_brace, x_mob
        ]

        self.add(glass, point_a, point_b, A, B)
        line = Mobject(top_line, bottom_line).ingest_submobjects()
        self.play(ShowCreation(line))
        self.dither()
        self.play(
            GrowFromCenter(left_brace), 
            GrowFromCenter(x_mob)
        )
        self.play(
            GrowFromCenter(right_brace), 
            GrowFromCenter(w_minus_x)
        )
        self.play(ShowCreation(left_line), ShimmerIn(h_1))
        self.play(ShowCreation(right_line), GrowFromCenter(h_2))
        self.play(ShimmerIn(top_dist))
        self.play(GrowFromCenter(bottom_dist))
        self.dither(3)
        self.clear()
        self.add(glass, point_a, point_b, A, B, 
                 top_line, bottom_line, left_brace, x_mob)
        self.play(ShowCreation(axes))
        kwargs = {
            "run_time" : 4,
        }
        self.play(*[
            Transform(*pair, **kwargs)
            for pair in [
                (top_line, end_top_line),
                (bottom_line, end_bottom_line),
                (left_brace, end_brace),
                (x_mob, end_x_mob)
            ]
        ]+[ShowCreation(graph, **kwargs)])
        self.dither()
        self.show_derivatives(graph)
        line = self.show_derivatives(new_graph)
        self.add(line)
        self.play(*[
            Transform(*pair, rate_func = lambda x : 0.3*smooth(x))
            for pair in pairs_for_end_transform
        ])
        self.dither()