Пример #1
0
    def setup(self):
        self.input_color = YELLOW_C
        self.output_color = RED
        def spiril(t):
            theta = 2*np.pi*t
            return t*np.cos(theta)*RIGHT+t*np.sin(theta)*UP

        self.spiril1 = ParametricFunction(
            lambda t : 1.5*RIGHT + DOWN + 2*spiril(t),
            density = 5*DEFAULT_POINT_DENSITY_1D,
        )
        self.spiril2 = ParametricFunction(
            lambda t : 5.5*RIGHT + UP - 2*spiril(1-t),
            density = 5*DEFAULT_POINT_DENSITY_1D,
        )
        Mobject.align_data(self.spiril1, self.spiril2)
        self.output = Mobject(self.spiril1, self.spiril2)
        self.output.ingest_submobjects()
        self.output.highlight(GREEN_A)

        self.interval = UnitInterval()
        self.interval.scale_to_fit_width(SPACE_WIDTH-1)
        self.interval.to_edge(LEFT)

        self.input_dot = Dot(color = self.input_color)
        self.output_dot = self.input_dot.copy().highlight(self.output_color)
        left, right = self.interval.get_left(), self.interval.get_right()
        self.input_homotopy = lambda (x, y, z, t) : (x, y, t) + interpolate(left, right, t)
        output_size = self.output.get_num_points()-1
        output_points = self.output.points        
        self.output_homotopy = lambda (x, y, z, t) : (x, y, z) + output_points[int(t*output_size)]
Пример #2
0
    def construct(self, order):
        if order == 2:
            result_tex = "(0.125, 0.75)"
        elif order == 3:
            result_tex = "(0.0758,  0.6875)"

        phc, arg, result = TexMobject([
            "\\text{PHC}_%d"%order, 
            "(0.3)", 
            "= %s"%result_tex
        ]).to_edge(UP).split()
        function = TextMobject("Function", size = "\\normal")
        function.shift(phc.get_center()+DOWN+2*LEFT)
        function_arrow = Arrow(function, phc)

        line = Line(5*LEFT, 5*RIGHT)
        curve = HilbertCurve(order = order)
        line.match_colors(curve)
        grid = Grid(2**order, 2**order)
        grid.fade()
        for mob in curve, grid:
            mob.scale(0.7)
        index = int(0.3*line.get_num_points())
        dot1 = Dot(line.points[index])
        arrow1 = Arrow(arg, dot1, buff = 0.1)
        dot2 = Dot(curve.points[index])
        arrow2 = Arrow(result.get_bottom(), dot2, buff = 0.1)

        self.add(phc)
        self.play(
            ShimmerIn(function),
            ShowCreation(function_arrow)
        )
        self.wait()
        self.remove(function_arrow, function)
        self.play(ShowCreation(line))
        self.wait()
        self.play(
            ShimmerIn(arg),
            ShowCreation(arrow1),
            ShowCreation(dot1)
        )
        self.wait()
        self.remove(arrow1)
        self.play(
            FadeIn(grid),            
            Transform(line, curve),
            Transform(dot1, dot2),
            run_time = 2
        )
        self.wait()
        self.play(
            ShimmerIn(result),
            ShowCreation(arrow2)
        )
        self.wait()
Пример #3
0
    def construct(self):
        val = 0.3
        text = TextMobject([
            "PHC", "$_n", "(", "%3.1f"%val, ")$", 
            " has a ", "limit point ", "as $n \\to \\infty$"
        ])
        func_parts = text.copy().split()[:5]
        Mobject(*func_parts).center().to_edge(UP)
        num_str, val_str = func_parts[1], func_parts[3]
        curve = UnitInterval()
        curve.sort_points(lambda p : p[0])
        dot = Dot().shift(curve.number_to_point(val))
        arrow = Arrow(val_str, dot, buff = 0.1)
        curve.add_numbers(0, 1)

        self.play(ShowCreation(curve))
        self.play(
            ShimmerIn(val_str),
            ShowCreation(arrow),
            ShowCreation(dot)
        )
        self.wait()
        self.play(
            FadeOut(arrow),
            *[
                FadeIn(func_parts[i])
                for i in 0, 1, 2, 4
            ]
        )
        for num in range(2,9):
            new_curve = HilbertCurve(order = num)
            new_curve.scale(0.8)
            new_dot = Dot(new_curve.points[int(val*new_curve.get_num_points())])
            new_num_str = TexMobject(str(num)).replace(num_str)
            self.play(
                Transform(curve, new_curve),
                Transform(dot, new_dot),
                Transform(num_str, new_num_str)
            )
            self.wait()

        text.to_edge(UP)
        text_parts = text.split()
        for index in 1, -1:
            text_parts[index].highlight()
        starters = Mobject(*func_parts + [
            Point(mob.get_center(), stroke_width=1)
            for mob in text_parts[5:]
        ])
        self.play(Transform(starters, text))
        arrow = Arrow(text_parts[-2].get_bottom(), dot, buff = 0.1)
        self.play(ShowCreation(arrow))
        self.wait()
Пример #4
0
    def __init__(self, mobject_or_point, **kwargs):
        digest_config(self, kwargs)
        big_dot = Dot(
            radius = SPACE_WIDTH+SPACE_HEIGHT,
            stroke_width = 0,
            fill_color = self.color,
            fill_opacity = 0,
        )
        little_dot = Dot(radius = 0)
        little_dot.set_fill(self.color, opacity = self.opacity)
        little_dot.move_to(mobject_or_point)

        Transform.__init__(self, big_dot, little_dot, **kwargs)
Пример #5
0
    def construct(self):
        big_grid_dim = 20.
        small_grid_dim = 6.
        big_grid = Grid(64, 64, height=big_grid_dim, width=big_grid_dim)
        big_grid.to_corner(UP + RIGHT, buff=2)
        small_grid = big_grid.copy()
        small_grid.scale(small_grid_dim / big_grid_dim)
        small_grid.center()
        pixel = MobjectFromRegion(
            region_from_polygon_vertices(
                *0.2 *
                np.array([RIGHT + DOWN, RIGHT + UP, LEFT + UP, LEFT + DOWN])))
        pixel.set_color(WHITE)
        pixel_width = big_grid.width / big_grid.columns
        pixel.scale_to_fit_width(pixel_width)
        pixel.to_corner(UP + RIGHT, buff=2)
        pixel.shift(5 * pixel_width * (2 * LEFT + DOWN))

        freq_line = get_freq_line()
        dot = Dot()
        dot.shift(freq_line.get_center() + 2 * RIGHT)
        string = Line(LEFT, RIGHT, color=GREEN)
        arrow = Arrow(dot, string.get_center())
        vibration_config = {
            "overtones": 1,
            "spatial_period": 2,
        }
        vibration, loud_vibration, quiet_vibration = [
            Vibrate(string.copy(), amplitude=a, **vibration_config)
            for a in [0.5, 1., 0.25]
        ]

        self.add(small_grid)
        self.dither()
        self.play(Transform(small_grid, big_grid))
        self.play(FadeIn(pixel))
        self.dither()
        self.play(FadeOut(small_grid), ShowCreation(freq_line))
        self.remove(small_grid)
        self.play(Transform(pixel, dot), )
        self.dither()
        self.play(ShowCreation(arrow))
        self.play(loud_vibration)
        self.play(TransformAnimations(loud_vibration, quiet_vibration),
                  ApplyMethod(dot.fade, 0.9))
        self.clear()
        self.add(freq_line, dot, arrow)
        self.play(quiet_vibration)
Пример #6
0
    def setup(self):
        self.input_color = YELLOW_C
        self.output_color = RED
        def spiril(t):
            theta = 2*np.pi*t
            return t*np.cos(theta)*RIGHT+t*np.sin(theta)*UP

        self.spiril1 = ParametricFunction(
            lambda t : 1.5*RIGHT + DOWN + 2*spiril(t),
            density = 5*DEFAULT_POINT_DENSITY_1D,
        )
        self.spiril2 = ParametricFunction(
            lambda t : 5.5*RIGHT + UP - 2*spiril(1-t),
            density = 5*DEFAULT_POINT_DENSITY_1D,
        )
        Mobject.align_data(self.spiril1, self.spiril2)
        self.output = Mobject(self.spiril1, self.spiril2)
        self.output.ingest_sub_mobjects()
        self.output.highlight(GREEN_A)

        self.interval = UnitInterval()
        self.interval.scale_to_fit_width(SPACE_WIDTH-1)
        self.interval.to_edge(LEFT)

        self.input_dot = Dot(color = self.input_color)
        self.output_dot = self.input_dot.copy().highlight(self.output_color)
        left, right = self.interval.get_left(), self.interval.get_right()
        self.input_homotopy = lambda (x, y, z, t) : (x, y, t) + interpolate(left, right, t)
        output_size = self.output.get_num_points()-1
        output_points = self.output.points        
        self.output_homotopy = lambda (x, y, z, t) : (x, y, z) + output_points[int(t*output_size)]
Пример #7
0
 def construct(self):
     start_curve = SnakeCurve(order = 6)
     end_curve = SnakeCurve(order = 7)
     start_dots, end_dots = [
         Mobject(*[
             Dot(
                 curve.points[int(x*curve.get_num_points())],
                 color = color
             )
             for x, color in [
                 (0.202, GREEN),
                 (0.48, BLUE),
                 (0.7, RED)
             ]
         ])
         for curve in start_curve, end_curve
     ]
     self.add(start_curve)
     self.dither()
     self.play(
         ShowCreation(start_dots, run_time = 2),
         ApplyMethod(start_curve.fade)
     )
     end_curve.fade()
     self.play(
         Transform(start_curve, end_curve),
         Transform(start_dots, end_dots)
     )
     self.dither()
Пример #8
0
    def construct(self):
        line = get_freq_line().center()
        line.sort_points(lambda p: p[0])
        curves = [self.CURVE_CLASS(order=order) for order in range(3, 10)]
        alpha = 0.48
        dot = Dot(UP)
        start_dot = Dot(0.1 * LEFT)
        dots = [
            Dot(curve.points[alpha * curve.get_num_points()])
            for curve in curves
        ]

        self.play(ShowCreation(line))
        self.play(Transform(dot, start_dot))
        self.dither()
        for new_dot, curve in zip(dots, curves):
            self.play(Transform(line, curve), Transform(dot, new_dot))
            self.dither()
Пример #9
0
    def construct(self):
        val = 0.7
        text = TexMobject([
            "\\text{HC}(", "x", ")",
            "=\\lim_{n \\to \\infty}\\text{PHC}_n(", "x", ")"
        ])
        text.to_edge(UP)
        x1 = text.split()[1]
        x2 = text.split()[-2]
        x2.highlight(BLUE)
        explanation = TextMobject("Actual Hilbert curve function")
        exp_arrow = Arrow(explanation, text.split()[0])
        curve = UnitInterval()
        dot = Dot(curve.number_to_point(val))
        x_arrow = Arrow(x1.get_bottom(), dot, buff = 0)
        curve.sort_points(lambda p : p[0])
        curve.add_numbers(0, 1)

        self.add(*text.split()[:3])
        self.play(
            ShimmerIn(explanation),
            ShowCreation(exp_arrow)
        )
        self.wait()
        self.remove(explanation, exp_arrow)
        self.play(ShowCreation(curve))
        self.play(
            ApplyMethod(x1.highlight, BLUE),
            ShowCreation(x_arrow), 
            ShowCreation(dot)
        )
        self.wait()
        self.remove(x_arrow)
        limit = Mobject(*text.split()[3:]).ingest_submobjects()
        limit.stroke_width = 1
        self.play(ShimmerIn(limit))
        for num in range(1, 9):
            new_curve = HilbertCurve(order = num)
            new_curve.scale(0.8)
            new_dot = Dot(new_curve.points[int(val*new_curve.get_num_points())])
            self.play(
                Transform(curve, new_curve),
                Transform(dot, new_dot),
            )
Пример #10
0
    def increment(self, run_time_per_anim = 1):
        moving_dot = Dot(
            self.counting_dot_starting_position,
            radius = self.count_dot_starting_radius,
            color = self.digit_place_colors[0],
        )
        moving_dot.generate_target()
        moving_dot.set_fill(opacity = 0)
        kwargs = {
            "run_time" : run_time_per_anim
        }

        continue_rolling_over = True
        first_move = True
        place = 0
        while continue_rolling_over:
            added_anims = []                
            if first_move:
                added_anims += self.get_digit_increment_animations()
                first_move = False
            moving_dot.target.replace(
                self.dot_template_iterators[place].next()
            )
            self.play(MoveToTarget(moving_dot), *added_anims, **kwargs)
            self.curr_configurations[place].add(moving_dot)


            if len(self.curr_configurations[place].split()) == self.get_place_max(place):
                full_configuration = self.curr_configurations[place]
                self.curr_configurations[place] = VGroup()
                place += 1
                center = full_configuration.get_center_of_mass()
                radius = 0.6*max(
                    full_configuration.get_width(),
                    full_configuration.get_height(),
                )
                circle = Circle(
                    radius = radius,
                    stroke_width = 0,
                    fill_color = self.digit_place_colors[place],
                    fill_opacity = 0.5,
                )
                circle.move_to(center)
                moving_dot = VGroup(circle, full_configuration)
                moving_dot.generate_target()
                moving_dot[0].set_fill(opacity = 0)
            else:
                continue_rolling_over = False
Пример #11
0
    def construct(self):
        text = TextMobject([
            "PHC", "_n", "(", "x", ")$", 
            " has a limit point ", "as $n \\to \\infty$",
            "\\\\ for all $x$"
        ])
        parts = text.split()
        parts[-1].next_to(Mobject(*parts[:-1]), DOWN)
        parts[-1].highlight(BLUE)
        parts[3].highlight(BLUE)
        parts[1].highlight()
        parts[-2].highlight()
        text.to_edge(UP)
        curve = UnitInterval()
        curve.sort_points(lambda p : p[0])
        vals = np.arange(0.1, 1, 0.1)
        dots = Mobject(*[
            Dot(curve.number_to_point(val))
            for val in vals
        ])
        curve.add_numbers(0, 1)
        starter_dots = dots.copy().ingest_submobjects()
        starter_dots.shift(2*UP)

        self.add(curve, text)
        self.wait()
        self.play(DelayByOrder(ApplyMethod(starter_dots.shift, 2*DOWN)))
        self.wait()
        self.remove(starter_dots)
        self.add(dots)
        for num in range(1, 10):
            new_curve = HilbertCurve(order = num)
            new_curve.scale(0.8)
            new_dots = Mobject(*[
                Dot(new_curve.points[int(val*new_curve.get_num_points())])
                for val in vals
            ])
            self.play(
                Transform(curve, new_curve),
                Transform(dots, new_dots),
            )
Пример #12
0
    def construct(self):
        grid = get_grid()
        grid.scale_to_fit_width(6)
        grid.to_edge(LEFT)
        freq_line = get_freq_line()
        freq_line.scale_to_fit_width(6)
        freq_line.center().to_edge(RIGHT)
        arrow =  Arrow(grid, freq_line)

        color1, color2 = YELLOW_C, RED
        square_length = 0.01
        dot1 = Dot(color = color1)
        dot1.shift(3*RIGHT)
        dot2 = Dot(color = color2)
        dot2.shift(3.1*RIGHT)
        arrow1 = Arrow(2*RIGHT+UP, dot1, color = color1, buff = 0.1)
        arrow2 = Arrow(4*RIGHT+UP, dot2, color = color2, buff = 0.1)
        dot3, arrow3 = [
            mob.copy().shift(5*LEFT+UP)
            for mob in dot1, arrow1
        ]
        dot4, arrow4 = [
            mob.copy().shift(5*LEFT+0.9*UP)
            for mob in dot2, arrow2
        ]

        self.add(grid, freq_line, arrow)
        self.dither()
        self.play(ApplyMethod(
            arrow.rotate, np.pi, 
            path_func = clockwise_path()
        ))
        self.dither()
        self.play(ShowCreation(arrow1))
        self.add(dot1)
        self.play(ShowCreation(arrow2))
        self.add(dot2)
        self.dither()
        self.remove(arrow1, arrow2)
        self.play(
            Transform(dot1, dot3),
            Transform(dot2, dot4)
        )
        self.play(
            ApplyMethod(grid.fade, 0.8),
            Animation(Mobject(dot3, dot4))
        )
        self.play(ShowCreation(arrow3))
        self.play(ShowCreation(arrow4))
        self.dither()
Пример #13
0
 def get_dot_template(self, place):
     #This should be replaced for non-base-10 counting scenes
     down_right = (0.5) * RIGHT + (np.sqrt(3) / 2) * DOWN
     dots = VGroup(*[
         Dot(
             point,
             radius=0.25,
             fill_opacity=0,
             stroke_width=2,
             stroke_color=WHITE,
         ) for point in self.get_template_configuration(place)
     ])
     dots.scale_to_fit_height(self.dot_configuration_height)
     return dots
Пример #14
0
    def __init__(self, mobject_or_point, **kwargs):
        digest_config(self, kwargs)
        big_dot = Dot(
            radius=SPACE_WIDTH + SPACE_HEIGHT,
            stroke_width=0,
            fill_color=self.color,
            fill_opacity=0,
        )
        little_dot = Dot(radius=0)
        little_dot.set_fill(self.color, opacity=self.opacity)
        little_dot.move_to(mobject_or_point)

        Transform.__init__(self, big_dot, little_dot, **kwargs)
Пример #15
0
    def __init__(self, mobject_or_point, **kwargs):
        digest_config(self, kwargs)
        big_dot = Dot(
            radius = FRAME_X_RADIUS+FRAME_Y_RADIUS,
            stroke_width = 0,
            fill_color = self.color,
            fill_opacity = 0,
        )
        little_dot = Dot(radius = 0)
        little_dot.set_fill(self.color, opacity = self.opacity)
        little_dot.move_to(mobject_or_point)

        Transform.__init__(self, big_dot, little_dot, **kwargs)
Пример #16
0
    def construct(self):
        start_words = TextMobject([
            "``", "Space Filling", "Curve ''",
        ]).to_edge(TOP, buff = 0.25)
        quote, space_filling, curve_quote = start_words.copy().split()
        curve_quote.shift(
            space_filling.get_left()-\
            curve_quote.get_left()
        )
        space_filling = Point(space_filling.get_center())                
        end_words = Mobject(*[
            quote, space_filling, curve_quote
        ]).center().to_edge(TOP, buff = 0.25)
        space_filling_fractal = TextMobject("""
            ``Space Filling Fractal''
        """).to_edge(UP)
        curve = HilbertCurve(order = 2).shift(DOWN)
        fine_curve = HilbertCurve(order = 8)
        fine_curve.replace(curve)
        dots = Mobject(*[
            Dot(
                curve.points[n*curve.get_num_points()/15],
                color = YELLOW_C
            )
            for n in range(1, 15)
            if n not in [4, 11]
        ])

        start_words.shift(2*(UP+LEFT))
        self.play(
            ApplyMethod(start_words.shift, 2*(DOWN+RIGHT))
        )
        self.wait()
        self.play(Transform(start_words, end_words))
        self.wait()
        self.play(ShowCreation(curve))
        self.wait()
        self.play(ShowCreation(
            dots, 
            run_time = 3,
        ))
        self.wait()
        self.clear()
        self.play(ShowCreation(fine_curve, run_time = 5))
        self.wait()
        self.play(ShimmerIn(space_filling_fractal))
        self.wait()
Пример #17
0
    def show_ghost_movement(self, vector):
        if isinstance(vector, Arrow):
            vector = vector.get_end() - vector.get_start()
        elif len(vector) == 2:
            vector = np.append(np.array(vector), 0.0)
        x_max = int(SPACE_WIDTH + abs(vector[0]))
        y_max = int(SPACE_HEIGHT + abs(vector[1]))
        dots = VMobject(*[
            Dot(x * RIGHT + y * UP) for x in range(-x_max, x_max)
            for y in range(-y_max, y_max)
        ])
        dots.set_fill(BLACK, opacity=0)
        dots_halfway = dots.copy().shift(vector / 2).set_fill(WHITE, 1)
        dots_end = dots.copy().shift(vector)

        self.play(Transform(dots, dots_halfway, rate_func=rush_into))
        self.play(Transform(dots, dots_end, rate_func=rush_from))
        self.remove(dots)
Пример #18
0
    def construct(self):
        overtones = 5
        floor = 2 * DOWN
        main_string = Vibrate(color=BLUE_D)
        component_strings = [
            Vibrate(num_periods=k + 1,
                    overtones=1,
                    color=color,
                    center=2 * DOWN + UP * k)
            for k, color in zip(range(overtones),
                                Color(BLUE_E).range_to(WHITE, overtones))
        ]
        dots = [
            Dot(string.mobject.get_center(), color=string.mobject.get_color())
            for string in component_strings
        ]

        freq_line = get_freq_line()
        freq_line.shift(floor)
        freq_line.sort_points(np.linalg.norm)
        brace = Brace(freq_line, UP)
        words = TextMobject("Range of frequency values")
        words.next_to(brace, UP)

        self.play(*[
            TransformAnimations(main_string.copy(), string, run_time=5)
            for string in component_strings
        ])
        self.clear()
        self.play(*[
            TransformAnimations(string, Animation(dot))
            for string, dot in zip(component_strings, dots)
        ])
        self.clear()
        self.play(
            ShowCreation(freq_line), GrowFromCenter(brace), ShimmerIn(words),
            *[
                Transform(dot,
                          dot.copy().scale(2).rotate(-np.pi / 2).shift(floor),
                          path_func=path_along_arc(np.pi / 3)) for dot in dots
            ])
        self.dither(0.5)
Пример #19
0
class FormalDefinitionOfContinuity(Scene):
    def construct(self):
        self.setup()
        self.label_spaces()
        self.move_dot()
        self.label_jump()
        self.draw_circles()
        self.vary_circle_sizes()
        self.discontinuous_point()


    def setup(self):
        self.input_color = YELLOW_C
        self.output_color = RED
        def spiril(t):
            theta = 2*np.pi*t
            return t*np.cos(theta)*RIGHT+t*np.sin(theta)*UP

        self.spiril1 = ParametricFunction(
            lambda t : 1.5*RIGHT + DOWN + 2*spiril(t),
            density = 5*DEFAULT_POINT_DENSITY_1D,
        )
        self.spiril2 = ParametricFunction(
            lambda t : 5.5*RIGHT + UP - 2*spiril(1-t),
            density = 5*DEFAULT_POINT_DENSITY_1D,
        )
        Mobject.align_data(self.spiril1, self.spiril2)
        self.output = Mobject(self.spiril1, self.spiril2)
        self.output.ingest_submobjects()
        self.output.highlight(GREEN_A)

        self.interval = UnitInterval()
        self.interval.scale_to_fit_width(SPACE_WIDTH-1)
        self.interval.to_edge(LEFT)

        self.input_dot = Dot(color = self.input_color)
        self.output_dot = self.input_dot.copy().highlight(self.output_color)
        left, right = self.interval.get_left(), self.interval.get_right()
        self.input_homotopy = lambda (x, y, z, t) : (x, y, t) + interpolate(left, right, t)
        output_size = self.output.get_num_points()-1
        output_points = self.output.points        
        self.output_homotopy = lambda (x, y, z, t) : (x, y, z) + output_points[int(t*output_size)]

    def get_circles_and_points(self, min_input, max_input):
        input_left, input_right = [
            self.interval.number_to_point(num)
            for num in min_input, max_input
        ]
        input_circle = Circle(
            radius = np.linalg.norm(input_left-input_right)/2,
            color = WHITE
        )
        input_circle.shift((input_left+input_right)/2)

        input_points = Line(
            input_left, input_right, 
            color = self.input_color
        )
        output_points = Mobject(color = self.output_color)
        n = self.output.get_num_points()
        output_points.add_points(
            self.output.points[int(min_input*n):int(max_input*n)]
        )
        output_center = output_points.points[int(0.5*output_points.get_num_points())]
        max_distance = np.linalg.norm(output_center-output_points.points[-1])
        output_circle = Circle(
            radius = max_distance, 
            color = WHITE
        )
        output_circle.shift(output_center)
        return (
            input_circle, 
            input_points, 
            output_circle, 
            output_points
        )


    def label_spaces(self):
        input_space = TextMobject("Input Space")
        input_space.to_edge(UP)        
        input_space.shift(LEFT*SPACE_WIDTH/2)
        output_space = TextMobject("Output Space")
        output_space.to_edge(UP)
        output_space.shift(RIGHT*SPACE_WIDTH/2)
        line = Line(
            UP*SPACE_HEIGHT, DOWN*SPACE_HEIGHT, 
            color = WHITE
        )
        self.play(
            ShimmerIn(input_space),
            ShimmerIn(output_space),
            ShowCreation(line),
            ShowCreation(self.interval),
        )
        self.wait()

    def move_dot(self):
        kwargs = {
            "rate_func" : None,
            "run_time"  : 3
        }
        self.play(
            Homotopy(self.input_homotopy, self.input_dot, **kwargs),
            Homotopy(self.output_homotopy, self.output_dot, **kwargs),
            ShowCreation(self.output, **kwargs)
        )
        self.wait()

    def label_jump(self):
        jump_points = Mobject(
            Point(self.spiril1.points[-1]),
            Point(self.spiril2.points[0])
        )
        self.brace = Brace(jump_points, RIGHT)
        self.jump = TextMobject("Jump")
        self.jump.next_to(self.brace, RIGHT)
        self.play(
            GrowFromCenter(self.brace),
            ShimmerIn(self.jump)
        )
        self.wait()
        self.remove(self.brace, self.jump)


    def draw_circles(self):
        input_value = 0.45
        input_radius = 0.04
        for dot in self.input_dot, self.output_dot:
            dot.center()
        kwargs = {
            "rate_func" : lambda t : interpolate(1, input_value, smooth(t))
        }
        self.play(
            Homotopy(self.input_homotopy, self.input_dot, **kwargs),
            Homotopy(self.output_homotopy, self.output_dot, **kwargs)
        )

        A, B = map(Mobject.get_center, [self.input_dot, self.output_dot])
        A_text = TextMobject("A")
        A_text.shift(A+2*(LEFT+UP))
        A_arrow = Arrow(
            A_text, self.input_dot,
            color = self.input_color
        )
        B_text = TextMobject("B")
        B_text.shift(B+2*RIGHT+DOWN)
        B_arrow = Arrow(
            B_text, self.output_dot,
            color = self.output_color
        )
        tup = self.get_circles_and_points(
            input_value-input_radius, 
            input_value+input_radius
        )
        input_circle, input_points, output_circle, output_points = tup

        for text, arrow in [(A_text, A_arrow), (B_text, B_arrow)]:
            self.play(
                ShimmerIn(text),
                ShowCreation(arrow)
            )
            self.wait()
        self.remove(A_text, A_arrow, B_text, B_arrow)
        self.play(ShowCreation(input_circle))
        self.wait()
        self.play(ShowCreation(input_points))
        self.wait()
        input_points_copy = input_points.copy()
        self.play(
            Transform(input_points_copy, output_points),
            run_time = 2
        )
        self.wait()
        self.play(ShowCreation(output_circle))
        self.wait()
        self.wait()
        self.remove(*[
            input_circle, input_points, 
            output_circle, input_points_copy
        ])


    def vary_circle_sizes(self):
        input_value = 0.45
        radius = 0.04
        vary_circles = VaryCircles(
            self, input_value, radius, 
            run_time = 5,
        )
        self.play(vary_circles)
        self.wait()
        text = TextMobject("Function is ``Continuous at A''")
        text.shift(2*UP).to_edge(LEFT)
        arrow = Arrow(text, self.input_dot)
        self.play(
            ShimmerIn(text),
            ShowCreation(arrow)
        )
        self.wait()
        self.remove(vary_circles.mobject, text, arrow)

    def discontinuous_point(self):
        point_description = TextMobject(
            "Point where the function jumps"
        )
        point_description.shift(3*RIGHT)        
        discontinuous_at_A = TextMobject(
            "``Discontinuous at A''",
            size = "\\Large"
        )
        discontinuous_at_A.shift(2*UP).to_edge(LEFT)
        text = TextMobject("""
            Circle around ouput \\\\ 
            points can never \\\\
            be smaller than \\\\
            the jump
        """)
        text.scale(0.75)
        text.shift(3.5*RIGHT)

        input_value = 0.5
        input_radius = 0.04
        vary_circles = VaryCircles(
            self, input_value, input_radius, 
            run_time = 5,
        )
        for dot in self.input_dot, self.output_dot:
            dot.center()
        kwargs = {
            "rate_func" : lambda t : interpolate(0.45, input_value, smooth(t))
        }
        self.play(
            Homotopy(self.input_homotopy, self.input_dot, **kwargs),
            Homotopy(self.output_homotopy, self.output_dot, **kwargs)
        )
        discontinuous_arrow = Arrow(discontinuous_at_A, self.input_dot)
        arrow = Arrow(
            point_description, self.output_dot,
            buff = 0.05,
            color = self.output_color
        )
        self.play(
            ShimmerIn(point_description),
            ShowCreation(arrow)
        )
        self.wait()
        self.remove(point_description, arrow)

        tup = self.get_circles_and_points(
            input_value-input_radius, 
            input_value+input_radius
        )
        input_circle, input_points, output_circle, output_points = tup
        input_points_copy = input_points.copy()
        self.play(ShowCreation(input_circle))
        self.play(ShowCreation(input_points))
        self.play(
            Transform(input_points_copy, output_points),
            run_time = 2
        )
        self.play(ShowCreation(output_circle))
        self.wait()
        self.play(ShimmerIn(text))
        self.remove(input_circle, input_points, output_circle, input_points_copy)
        self.play(vary_circles)
        self.wait()
        self.play(
            ShimmerIn(discontinuous_at_A),
            ShowCreation(discontinuous_arrow)
        )
        self.wait(3)
        self.remove(vary_circles.mobject, discontinuous_at_A, discontinuous_arrow)

    def continuous_point(self):
        pass
Пример #20
0
    def construct(self):
        big_grid_dim = 20.
        small_grid_dim = 6.
        big_grid = Grid(64, 64, height = big_grid_dim, width = big_grid_dim)
        big_grid.to_corner(UP+RIGHT, buff = 2)
        small_grid = big_grid.copy()
        small_grid.scale(small_grid_dim/big_grid_dim)
        small_grid.center()
        pixel = MobjectFromRegion(
            region_from_polygon_vertices(*0.2*np.array([
                RIGHT+DOWN,
                RIGHT+UP,
                LEFT+UP,
                LEFT+DOWN
            ]))
        )
        pixel.set_color(WHITE)
        pixel_width = big_grid.width/big_grid.columns
        pixel.scale_to_fit_width(pixel_width)
        pixel.to_corner(UP+RIGHT, buff = 2)
        pixel.shift(5*pixel_width*(2*LEFT+DOWN))

        freq_line = get_freq_line()
        dot = Dot()
        dot.shift(freq_line.get_center() + 2*RIGHT)
        string = Line(LEFT, RIGHT, color = GREEN)
        arrow = Arrow(dot, string.get_center())
        vibration_config = {
            "overtones"      : 1,
            "spatial_period" : 2,
        }
        vibration, loud_vibration, quiet_vibration = [
            Vibrate(string.copy(), amplitude = a, **vibration_config)
            for a in [0.5, 1., 0.25]
        ]

        self.add(small_grid)
        self.dither()
        self.play(
            Transform(small_grid, big_grid)
        )
        self.play(FadeIn(pixel))
        self.dither()
        self.play(
            FadeOut(small_grid),            
            ShowCreation(freq_line)
        )
        self.remove(small_grid)
        self.play(
            Transform(pixel, dot),
        )
        self.dither()
        self.play(ShowCreation(arrow))
        self.play(loud_vibration)
        self.play(
            TransformAnimations(loud_vibration, quiet_vibration),            
            ApplyMethod(dot.fade, 0.9)
        )
        self.clear()
        self.add(freq_line, dot, arrow)
        self.play(quiet_vibration)
Пример #21
0
class FormalDefinitionOfContinuity(Scene):
    def construct(self):
        self.setup()
        self.label_spaces()
        self.move_dot()
        self.label_jump()
        self.draw_circles()
        self.vary_circle_sizes()
        self.discontinuous_point()


    def setup(self):
        self.input_color = YELLOW_C
        self.output_color = RED
        def spiril(t):
            theta = 2*np.pi*t
            return t*np.cos(theta)*RIGHT+t*np.sin(theta)*UP

        self.spiril1 = ParametricFunction(
            lambda t : 1.5*RIGHT + DOWN + 2*spiril(t),
            density = 5*DEFAULT_POINT_DENSITY_1D,
        )
        self.spiril2 = ParametricFunction(
            lambda t : 5.5*RIGHT + UP - 2*spiril(1-t),
            density = 5*DEFAULT_POINT_DENSITY_1D,
        )
        Mobject.align_data(self.spiril1, self.spiril2)
        self.output = Mobject(self.spiril1, self.spiril2)
        self.output.ingest_sub_mobjects()
        self.output.highlight(GREEN_A)

        self.interval = UnitInterval()
        self.interval.scale_to_fit_width(SPACE_WIDTH-1)
        self.interval.to_edge(LEFT)

        self.input_dot = Dot(color = self.input_color)
        self.output_dot = self.input_dot.copy().highlight(self.output_color)
        left, right = self.interval.get_left(), self.interval.get_right()
        self.input_homotopy = lambda (x, y, z, t) : (x, y, t) + interpolate(left, right, t)
        output_size = self.output.get_num_points()-1
        output_points = self.output.points        
        self.output_homotopy = lambda (x, y, z, t) : (x, y, z) + output_points[int(t*output_size)]

    def get_circles_and_points(self, min_input, max_input):
        input_left, input_right = [
            self.interval.number_to_point(num)
            for num in min_input, max_input
        ]
        input_circle = Circle(
            radius = np.linalg.norm(input_left-input_right)/2,
            color = WHITE
        )
        input_circle.shift((input_left+input_right)/2)

        input_points = Line(
            input_left, input_right, 
            color = self.input_color
        )
        output_points = Mobject(color = self.output_color)
        n = self.output.get_num_points()
        output_points.add_points(
            self.output.points[int(min_input*n):int(max_input*n)]
        )
        output_center = output_points.points[int(0.5*output_points.get_num_points())]
        max_distance = np.linalg.norm(output_center-output_points.points[-1])
        output_circle = Circle(
            radius = max_distance, 
            color = WHITE
        )
        output_circle.shift(output_center)
        return (
            input_circle, 
            input_points, 
            output_circle, 
            output_points
        )


    def label_spaces(self):
        input_space = TextMobject("Input Space")
        input_space.to_edge(UP)        
        input_space.shift(LEFT*SPACE_WIDTH/2)
        output_space = TextMobject("Output Space")
        output_space.to_edge(UP)
        output_space.shift(RIGHT*SPACE_WIDTH/2)
        line = Line(
            UP*SPACE_HEIGHT, DOWN*SPACE_HEIGHT, 
            color = WHITE
        )
        self.play(
            ShimmerIn(input_space),
            ShimmerIn(output_space),
            ShowCreation(line),
            ShowCreation(self.interval),
        )
        self.dither()

    def move_dot(self):
        kwargs = {
            "rate_func" : None,
            "run_time"  : 3
        }
        self.play(
            Homotopy(self.input_homotopy, self.input_dot, **kwargs),
            Homotopy(self.output_homotopy, self.output_dot, **kwargs),
            ShowCreation(self.output, **kwargs)
        )
        self.dither()

    def label_jump(self):
        jump_points = Mobject(
            Point(self.spiril1.points[-1]),
            Point(self.spiril2.points[0])
        )
        self.brace = Brace(jump_points, RIGHT)
        self.jump = TextMobject("Jump")
        self.jump.next_to(self.brace, RIGHT)
        self.play(
            GrowFromCenter(self.brace),
            ShimmerIn(self.jump)
        )
        self.dither()
        self.remove(self.brace, self.jump)


    def draw_circles(self):
        input_value = 0.45
        input_radius = 0.04
        for dot in self.input_dot, self.output_dot:
            dot.center()
        kwargs = {
            "rate_func" : lambda t : interpolate(1, input_value, smooth(t))
        }
        self.play(
            Homotopy(self.input_homotopy, self.input_dot, **kwargs),
            Homotopy(self.output_homotopy, self.output_dot, **kwargs)
        )

        A, B = map(Mobject.get_center, [self.input_dot, self.output_dot])
        A_text = TextMobject("A")
        A_text.shift(A+2*(LEFT+UP))
        A_arrow = Arrow(
            A_text, self.input_dot,
            color = self.input_color
        )
        B_text = TextMobject("B")
        B_text.shift(B+2*RIGHT+DOWN)
        B_arrow = Arrow(
            B_text, self.output_dot,
            color = self.output_color
        )
        tup = self.get_circles_and_points(
            input_value-input_radius, 
            input_value+input_radius
        )
        input_circle, input_points, output_circle, output_points = tup

        for text, arrow in [(A_text, A_arrow), (B_text, B_arrow)]:
            self.play(
                ShimmerIn(text),
                ShowCreation(arrow)
            )
            self.dither()
        self.remove(A_text, A_arrow, B_text, B_arrow)
        self.play(ShowCreation(input_circle))
        self.dither()
        self.play(ShowCreation(input_points))
        self.dither()
        input_points_copy = input_points.copy()
        self.play(
            Transform(input_points_copy, output_points),
            run_time = 2
        )
        self.dither()
        self.play(ShowCreation(output_circle))
        self.dither()
        self.dither()
        self.remove(*[
            input_circle, input_points, 
            output_circle, input_points_copy
        ])


    def vary_circle_sizes(self):
        input_value = 0.45
        radius = 0.04
        vary_circles = VaryCircles(
            self, input_value, radius, 
            run_time = 5,
        )
        self.play(vary_circles)
        self.dither()
        text = TextMobject("Function is ``Continuous at A''")
        text.shift(2*UP).to_edge(LEFT)
        arrow = Arrow(text, self.input_dot)
        self.play(
            ShimmerIn(text),
            ShowCreation(arrow)
        )
        self.dither()
        self.remove(vary_circles.mobject, text, arrow)

    def discontinuous_point(self):
        point_description = TextMobject(
            "Point where the function jumps"
        )
        point_description.shift(3*RIGHT)        
        discontinuous_at_A = TextMobject(
            "``Discontinuous at A''",
            size = "\\Large"
        )
        discontinuous_at_A.shift(2*UP).to_edge(LEFT)
        text = TextMobject("""
            Circle around ouput \\\\ 
            points can never \\\\
            be smaller than \\\\
            the jump
        """)
        text.scale(0.75)
        text.shift(3.5*RIGHT)

        input_value = 0.5
        input_radius = 0.04
        vary_circles = VaryCircles(
            self, input_value, input_radius, 
            run_time = 5,
        )
        for dot in self.input_dot, self.output_dot:
            dot.center()
        kwargs = {
            "rate_func" : lambda t : interpolate(0.45, input_value, smooth(t))
        }
        self.play(
            Homotopy(self.input_homotopy, self.input_dot, **kwargs),
            Homotopy(self.output_homotopy, self.output_dot, **kwargs)
        )
        discontinuous_arrow = Arrow(discontinuous_at_A, self.input_dot)
        arrow = Arrow(
            point_description, self.output_dot,
            buff = 0.05,
            color = self.output_color
        )
        self.play(
            ShimmerIn(point_description),
            ShowCreation(arrow)
        )
        self.dither()
        self.remove(point_description, arrow)

        tup = self.get_circles_and_points(
            input_value-input_radius, 
            input_value+input_radius
        )
        input_circle, input_points, output_circle, output_points = tup
        input_points_copy = input_points.copy()
        self.play(ShowCreation(input_circle))
        self.play(ShowCreation(input_points))
        self.play(
            Transform(input_points_copy, output_points),
            run_time = 2
        )
        self.play(ShowCreation(output_circle))
        self.dither()
        self.play(ShimmerIn(text))
        self.remove(input_circle, input_points, output_circle, input_points_copy)
        self.play(vary_circles)
        self.dither()
        self.play(
            ShimmerIn(discontinuous_at_A),
            ShowCreation(discontinuous_arrow)
        )
        self.dither(3)
        self.remove(vary_circles.mobject, discontinuous_at_A, discontinuous_arrow)

    def continuous_point(self):
        pass