Ejemplo n.º 1
0
    def add_polygons(self):
        a = self.i_hat.get_end()[0]*RIGHT
        b = self.j_hat.get_end()[0]*RIGHT
        c = self.i_hat.get_end()[1]*UP
        d = self.j_hat.get_end()[1]*UP

        shapes_colors_and_tex = [
            (Polygon(ORIGIN, a, a+c), TEAL, "bd/2"),
            (Polygon(ORIGIN, d+b, d), TEAL, "\\dfrac{bd}{2}"),
            (Polygon(a+c, a+b+c, a+b+c+d), MAROON, "\\dfrac{ac}{2}"),
            (Polygon(b+d, a+b+c+d, b+c+d), MAROON, "ac/2"),
            (Polygon(a, a+b, a+b+c, a+c), PINK, "bc"),
            (Polygon(d, d+b, d+b+c, d+c), PINK, "bc"),
        ]
        everyone = VMobject()
        for shape, color, tex in shapes_colors_and_tex:
            shape.set_stroke(width = 0)
            shape.set_fill(color = color, opacity = 0.7)
            tex_mob = TexMobject(tex)
            tex_mob.scale(0.7)
            tex_mob.move_to(shape.get_center_of_mass())
            everyone.add(shape, tex_mob)
        self.play(FadeIn(
            everyone, 
            submobject_mode = "lagged_start",
            run_time = 1
        ))
Ejemplo n.º 2
0
    def move_matrix_parentheses(self, morty, matrices):
        m1, m2, m3 = matrices
        parens = TexMobject(["(", ")"])
        parens.scale_to_fit_height(1.2*m1.get_height())
        lp, rp = parens.split()
        state1 = VMobject(
            VectorizedPoint(m1.get_left()),
            m1, m2, 
            VectorizedPoint(m2.get_right()),
            m3
        )
        state2 = VMobject(*[
            m.copy() for m in lp, m1, m2, rp, m3
        ])
        state3 = VMobject(*[
            m.copy() for m in m1, lp, m2, m3, rp
        ])
        for state in state2, state3:
            state.arrange_submobjects(RIGHT, buff = 0.1)
        m1, lp, m2, m3, rp = state3.split()
        state3 = VMobject(lp, m1, m2, rp, m3)

        self.play(morty.change_mode, "angry")
        for state in state2, state3:
            self.play(Transform(state1, state))
            self.dither()
        self.play(morty.change_mode, "confused")
        self.dither()
Ejemplo n.º 3
0
    def show_dependencies(self):
        linalg = TextMobject("Linear Algebra")
        subjects = map(TextMobject, [
            "Computer science",
            "Physics",
            "Electrical engineering",
            "Mechanical engineering",
            "Statistics",
            "\\vdots"
        ])
        prev = subjects[0]
        for subject in subjects[1:]:
            subject.next_to(prev, DOWN, aligned_edge = LEFT)
            prev = subject
        all_subs = VMobject(*subjects)
        linalg.to_edge(LEFT)
        all_subs.next_to(linalg, RIGHT, buff = 2)
        arrows = VMobject(*[
            Arrow(linalg, sub)
            for sub in subjects
        ])

        self.play(Write(linalg, run_time = 1))
        self.dither()
        self.play(
            ShowCreation(arrows, submobject_mode = "lagged_start"),
            FadeIn(all_subs),
            run_time = 2
        )
        self.dither()
        self.linalg = linalg
Ejemplo n.º 4
0
    def construct(self):
        t_axis = NumberLine(
            numbers_with_elongated_ticks = [],
            x_min = 0,
            x_max = 10,
            color = WHITE,
        )
        det_axis = NumberLine(
            numbers_with_elongated_ticks = [],
            x_min = -2,
            x_max = 2,
            color = WHITE
        )
        det_axis.rotate(np.pi/2)
        t_axis.next_to(ORIGIN, RIGHT, buff = 0)
        det_axis.move_to(t_axis.get_left())
        axes = VMobject(det_axis, t_axis)
        graph = FunctionGraph(np.cos, x_min = 0, x_max = np.pi)
        graph.next_to(det_axis, RIGHT, buff = 0)
        graph.highlight(YELLOW)
        det_word = TextMobject("Det")
        det_word.next_to(det_axis, RIGHT, aligned_edge = UP)
        time_word = TextMobject("time")
        time_word.next_to(t_axis, UP)
        time_word.to_edge(RIGHT)
        everything = VMobject(axes, det_word, time_word, graph)
        everything.scale(1.5)

        self.add(axes, det_word, time_word)
        self.play(ShowCreation(
            graph, rate_func = None, run_time = 10
        ))
Ejemplo n.º 5
0
    def construct(self):
        matrix = Matrix([
            [2, 0],
            [-1, 1],
            [-2, 1],
        ])
        matrix.highlight_columns(X_COLOR, Y_COLOR)

        brace = Brace(matrix)
        words = VMobject(
            TextMobject("Span", "of columns"),
            TexMobject("\\Updownarrow"),
            TextMobject("``Column space''")
        )
        words.arrange_submobjects(DOWN, buff = 0.1)
        words.next_to(brace, DOWN)
        words[0][0].highlight(PINK)
        words[2].highlight(TEAL)
        words[0].add_background_rectangle()
        words[2].add_background_rectangle()
        VMobject(matrix, brace, words).center()

        self.add(matrix)
        self.play(
            GrowFromCenter(brace),
            Write(words, run_time = 2)
        )
        self.dither()
Ejemplo n.º 6
0
    def show_overall_effect(self, matrix):
        everything = self.get_mobjects()
        everything = list_difference_update(
            everything, matrix.submobject_family()
        )
        self.play(*map(FadeOut, everything) + [Animation(matrix)])
        new_matrix = matrix.copy()
        new_matrix.center().to_edge(UP)
        self.play(Transform(matrix, new_matrix))
        self.dither()        
        self.remove(matrix)

        self.setup()
        everything = self.get_mobjects()
        self.play(*map(FadeIn, everything) + [Animation(matrix)])
        func = self.get_matrix_transformation([[1, 1], [-1, 0]])
        bases = VMobject(self.i_hat, self.j_hat)
        new_bases = VMobject(*[
            Vector(func(v.get_end()), color = v.get_color())
            for v in bases.split()
        ])
        self.play(
            ApplyPointwiseFunction(func, self.plane),
            Transform(bases, new_bases),
            Animation(matrix),
            run_time = 3
        )
        self.dither()
Ejemplo n.º 7
0
 def get_matrix_multiplication_question(self):
     why = TextMobject("Why?").highlight(BLUE) 
     mult = self.get_matrix_multiplication()
     why.next_to(mult, UP)
     result = VMobject(why, mult)
     result.get_center = lambda : mult.get_center()
     return result
Ejemplo n.º 8
0
    def show_scaled_vectors(self, vect_array, vect_coords, i_label, j_label):
        x, y = vect_array.get_entries().split()
        scaled_i_label = VMobject(x.copy(), i_label.copy())
        scaled_j_label = VMobject(y.copy(), j_label.copy())
        scaled_i = self.i_hat.copy().scale(vect_coords[0])
        scaled_j = self.j_hat.copy().scale(vect_coords[1])
        for mob in scaled_i, scaled_j:
            mob.fade(0.3)
        scaled_i_label_target = scaled_i_label.copy()
        scaled_i_label_target.arrange_submobjects(buff = 0.1)
        scaled_i_label_target.next_to(scaled_i.get_center(), DOWN)
        scaled_j_label_target = scaled_j_label.copy()
        scaled_j_label_target.arrange_submobjects(buff = 0.1)
        scaled_j_label_target.next_to(scaled_j.get_center(), LEFT)

        self.play(
            Transform(self.i_hat.copy(), scaled_i),
            Transform(scaled_i_label, scaled_i_label_target)
        )
        scaled_i = self.get_mobjects_from_last_animation()[0]
        self.play(
            Transform(self.j_hat.copy(), scaled_j),
            Transform(scaled_j_label, scaled_j_label_target)
        )
        scaled_j = self.get_mobjects_from_last_animation()[0]
        self.play(*[
            ApplyMethod(mob.shift, scaled_i.get_end())
            for mob in scaled_j, scaled_j_label
        ])
        self.dither()
        self.play(*map(FadeOut, [
            scaled_i, scaled_j, scaled_i_label, scaled_j_label,
        ]))
Ejemplo n.º 9
0
    def record_basis_coordinates(self, vect_array, vect):
        i_label = vector_coordinate_label(self.i_hat)
        i_label.highlight(X_COLOR)
        j_label = vector_coordinate_label(self.j_hat)
        j_label.highlight(Y_COLOR)
        for mob in i_label, j_label:
            mob.scale_in_place(0.8)
            background = BackgroundRectangle(mob)
            self.play(ShowCreation(background), Write(mob))

        self.dither()
        x, y = vect_array.get_entries().split()
        pre_formula = VMobject(
            x, i_label, TexMobject("+"),
            y, j_label
        )
        post_formula = pre_formula.copy()
        pre_formula.split()[2].fade(1)
        post_formula.arrange_submobjects(buff = 0.1)
        post_formula.next_to(vect, DOWN)
        background = BackgroundRectangle(post_formula)
        everything = self.get_mobjects()
        everything.remove(vect)
        self.play(*[
            ApplyMethod(m.fade) for m in everything
        ] + [
            ShowCreation(background, run_time = 2, rate_func = squish_rate_func(smooth, 0.5, 1)),
            Transform(pre_formula.copy(), post_formula, run_time = 2),
            ApplyMethod(vect.set_stroke, width = 7)
        ])
        self.dither()
Ejemplo n.º 10
0
    def describe_scalars(self, v, plane):
        axes = plane.get_axes()
        long_v = Vector(2*v.get_end())
        long_minus_v = Vector(-2*v.get_end())
        original_v = v.copy()
        scaling_word = TextMobject("``Scaling''").to_corner(UP+LEFT)
        scaling_word.shift(2*RIGHT)
        scalars = VMobject(*map(TexMobject, [
            "2,", "\\dfrac{1}{3},", "-1.8,", "\\dots"
        ]))
        scalars.arrange_submobjects(RIGHT, buff = 0.4)
        scalars.next_to(scaling_word, DOWN, aligned_edge = LEFT)
        scalars_word = TextMobject("``Scalars''")
        scalars_word.next_to(scalars, DOWN, aligned_edge = LEFT)

        self.remove(plane)
        self.add(axes)
        self.play(
            Write(scaling_word),
            Transform(v, long_v),
            run_time = 1.5
        )
        self.play(Transform(v, long_minus_v, run_time = 3))
        self.play(Write(scalars))
        self.dither()
        self.play(Write(scalars_word))
        self.play(Transform(v, original_v), run_time = 3)
        self.dither(2)
Ejemplo n.º 11
0
    def construct(self):
        physy = Physicist()
        mathy = Mathematician(mode = "pondering")        
        compy = ComputerScientist()
        creatures = [physy, compy, mathy]
        physy.title = TextMobject("Physics student").to_corner(DOWN+LEFT)
        compy.title = TextMobject("CS student").to_corner(DOWN+RIGHT)
        mathy.title = TextMobject("Mathematician").to_edge(DOWN)
        names = VMobject(physy.title, mathy.title, compy.title)
        names.arrange_submobjects(RIGHT, buff = 1)
        names.to_corner(DOWN+LEFT)
        for pi in creatures:
            pi.next_to(pi.title, UP)

        vector, symbol, coordinates = self.intro_vector()
        for pi in creatures:
            self.play(
                Write(pi.title),
                FadeIn(pi),
                run_time = 1
            )
        self.dither(2)
        self.remove(symbol, coordinates)
        self.physics_conception(creatures, vector)
        self.cs_conception(creatures)
        self.handle_mathy(creatures)
Ejemplo n.º 12
0
    def construct(self):
        matrix = Matrix([list("abc"), list("def"), list("ghi")])
        matrix.highlight_columns(X_COLOR, Y_COLOR, Z_COLOR)
        m1 = Matrix([["e", "f"], ["h", "i"]])
        m1.highlight_columns(Y_COLOR, Z_COLOR)
        m2 = Matrix([["d", "f"], ["g", "i"]])
        m2.highlight_columns(X_COLOR, Z_COLOR)
        m3 = Matrix([["d", "e"], ["g", "h"]])
        m3.highlight_columns(X_COLOR, Y_COLOR)

        for m in matrix, m1, m2, m3:
            m.add(get_det_text(m))
        a, b, c = matrix.get_entries().split()[:3]
        parts = it.starmap(VMobject, [
            [matrix], 
            [TexMobject("="), a.copy(), m1], 
            [TexMobject("-"), b.copy(), m2],
            [TexMobject("+"), c.copy(), m3],
        ])
        parts = list(parts)
        for part in parts:
            part.arrange_submobjects(RIGHT, buff = 0.2)
        parts[1].next_to(parts[0], RIGHT)
        parts[2].next_to(parts[1], DOWN, aligned_edge = LEFT)
        parts[3].next_to(parts[2], DOWN, aligned_edge = LEFT)
        everyone = VMobject(*parts)
        everyone.center().to_edge(UP)
        for part in parts:
            self.play(Write(part))
        self.dither(2)
Ejemplo n.º 13
0
 def construct(self):
     self.setup()
     blob = Blob(
         height = self.blob_height, 
         random_seed = 5,
         random_nudge_size = 0.2,
     )
     blob.next_to(ORIGIN, UP+RIGHT)
     self.add_transformable_mobject(blob)
     arange = np.arange(
         0, self.blob_height + self.square_size, 
         self.square_size
     )
     square = Square(side_length = self.square_size)
     square.set_stroke(YELLOW, width = 2)
     square.set_fill(YELLOW, opacity = 0.3)
     squares = VMobject()
     for x, y in it.product(*[arange]*2):
         point = x*RIGHT + y*UP
         if blob.probably_contains(point):
             squares.add(square.copy().shift(point))
     self.play(ShowCreation(
         squares, submobject_mode = "lagged_start",
         run_time = 2,
     ))
     self.add_transformable_mobject(squares)
     self.dither()
     self.apply_transposed_matrix([[1, -1], [0.5, 1]])
     self.dither()
Ejemplo n.º 14
0
    def construct(self):
        self.setup()
        self.add_unit_square()
        matrix = Matrix(np.array(self.t_matrix).transpose())
        matrix.next_to(ORIGIN, LEFT)
        matrix.to_edge(UP)
        matrix.highlight_columns(X_COLOR, Y_COLOR)

        det_text = get_det_text(
            matrix, determinant = np.linalg.det(self.t_matrix)
        )
        three = VMobject(*det_text.split()[-1].split()[1:])
        for mob in det_text.split():
            if isinstance(mob, TexMobject):
                mob.add_background_rectangle()
        matrix_background = BackgroundRectangle(matrix)
        self.play(
            ShowCreation(matrix_background),
            Write(matrix),
            Write(det_text),
        )
        self.add_foreground_mobject(matrix_background, matrix, det_text)
        self.dither()
        self.apply_transposed_matrix(self.t_matrix)

        self.play(three.copy().move_to, self.square)
        self.dither()
Ejemplo n.º 15
0
    def construct(self):
        line = NumberLine()
        self.add(line, *self.get_mobjects())
        offset = LEFT+DOWN
        vect = 2*RIGHT+UP
        dots = VMobject(*[
             Dot(offset + a*vect, radius = 0.075)
             for a in np.linspace(-2, 3, 18)
        ])
        dots.submobject_gradient_highlight(YELLOW_B, YELLOW_C)
        func = self.get_matrix_transformation(self.t_matrix)
        new_dots = VMobject(*[
            Dot(
                func(dot.get_center()), 
                color = dot.get_color(),
                radius = dot.radius
            )
            for dot in dots
        ])
        words = TextMobject(
            "Line of dots remains evenly spaced"
        )
        words.next_to(line, UP, buff = MED_SMALL_BUFF)

        self.play(Write(dots))
        self.apply_transposed_matrix(
            self.t_matrix,
            added_anims = [Transform(dots, new_dots)]
        )
        self.play(Write(words))
        self.dither()
Ejemplo n.º 16
0
    def add_braces(self):
        a = self.i_hat.get_end()[0]*RIGHT
        b = self.j_hat.get_end()[0]*RIGHT
        c = self.i_hat.get_end()[1]*UP
        d = self.j_hat.get_end()[1]*UP

        quads = [
            (ORIGIN, a, DOWN, "a"),
            (a, a+b, DOWN, "b"),
            (a+b, a+b+c, RIGHT, "c"),
            (a+b+c, a+b+c+d, RIGHT, "d"),
            (a+b+c+d, a+c+d, UP, "a"),
            (a+c+d, d+c, UP, "b"),
            (d+c, d, LEFT, "c"),
            (d, ORIGIN, LEFT, "d"),
        ]
        everyone = VMobject()
        for p1, p2, direction, char in quads:
            line = Line(p1, p2)
            brace = Brace(line, direction, buff = 0)
            text = brace.get_text(char)
            text.add_background_rectangle()
            if char in ["a", "c"]:
                text.highlight(X_COLOR)
            else:
                text.highlight(Y_COLOR)
            everyone.add(brace, text)
        self.play(Write(everyone), run_time = 1)
Ejemplo n.º 17
0
class Arrow(Line):
    CONFIG = {
        "color"      : YELLOW_C,
        "tip_length" : 0.25,
        "tip_angle"  : np.pi/6,
        "buff"       : MED_SMALL_BUFF,
        "propogate_style_to_family" : False,
        "preserve_tip_size_when_scaling" : True,
    }
    def __init__(self, *args, **kwargs):
        points = map(self.pointify, args)
        if len(args) == 1:
            args = (points[0]+UP+LEFT, points[0])
        Line.__init__(self, *args, **kwargs)
        self.add_tip()

    def add_tip(self, add_at_end = True):
        vect = self.tip_length*RIGHT
        vect = rotate_vector(vect, self.get_angle()+np.pi)
        start, end = self.get_start_and_end()
        if not add_at_end:
            start, end = end, start
            vect = -vect
        tip_points = [
            end+rotate_vector(vect, u*self.tip_angle)
            for u in 1, -1
        ]
        self.tip = VMobject(
            close_new_points = True,
            mark_paths_closed = True,
            fill_color = self.color,
            fill_opacity = 1,
            stroke_color = self.color,
        )
        self.tip.set_anchor_points(
            [tip_points[0], end, tip_points[1]],
            mode = "corners"
        )
        self.set_points_as_corners(
            [start, center_of_mass(tip_points)]
        )
        self.add(self.tip)
        self.init_colors()

    def get_end(self):
        if hasattr(self, "tip"):
            return self.tip.get_anchors()[1]
        else:
            return Line.get_end(self)

    def get_tip(self):
        return self.tip

    def scale(self, scale_factor, **kwargs):
        Line.scale(self, scale_factor, **kwargs)
        if self.preserve_tip_size_when_scaling:
            self.remove(self.tip)
            self.add_tip()
        return self
Ejemplo n.º 18
0
 def construct(self):
     mob = VMobject(
         TextMobject("Computer graphics"),
         TextMobject("Robotics")
     )
     mob.arrange_submobjects(DOWN, buff = 1)
     self.play(Write(mob, run_time = 1))
     self.dither()
Ejemplo n.º 19
0
 def __init__(self, **kwargs):
     hand = SVGMobject("RightHandOutline")
     self.inlines = VMobject(*hand.split()[:-4])
     self.outline = VMobject(*hand.split()[-4:])
     self.outline.set_stroke(color = WHITE, width = 5)
     self.inlines.set_stroke(color = DARK_GREY, width = 3)
     VMobject.__init__(self, self.outline, self.inlines)
     self.center().scale_to_fit_height(3)
Ejemplo n.º 20
0
 def construct(self):
     arrays = VMobject(*map(matrix_to_mobject, [
         [-2, 3], [1, 2], [2, -1], [4, 0]
     ]))
     arrays.arrange_submobjects(buff = 0.4)
     arrays.scale(2)
     self.play(Write(arrays))
     self.dither(2)
Ejemplo n.º 21
0
 def init_colors(self):
     VMobject.init_colors(self)
     self.axes.set_stroke(self.axes_color, self.stroke_width)
     self.main_lines.set_stroke(self.color, self.stroke_width)
     self.secondary_lines.set_stroke(
         self.secondary_color, self.secondary_stroke_width
     )
     return self
Ejemplo n.º 22
0
    def introduce_coordinate_plane(self):
        plane = NumberPlane()
        x_axis, y_axis = plane.get_axes().copy().split()
        x_label, y_label = plane.get_axis_labels().split()
        number_line = NumberLine(tick_frequency = 1)
        x_tick_marks = number_line.get_tick_marks()
        y_tick_marks = x_tick_marks.copy().rotate(np.pi/2)
        tick_marks = VMobject(x_tick_marks, y_tick_marks)
        tick_marks.highlight(WHITE)
        plane_lines = filter(
            lambda m : isinstance(m, Line),
            plane.submobject_family()
        )
        origin_words = TextMobject("Origin")
        origin_words.shift(2*UP+2*LEFT)
        dot = Dot(radius = 0.1).highlight(RED)
        line = Line(origin_words.get_bottom(), dot.get_corner(UP+LEFT))

        unit_brace = Brace(Line(RIGHT, 2*RIGHT))
        one = TexMobject("1").next_to(unit_brace, DOWN)

        self.add(x_axis, x_label)
        self.dither()
        self.play(ShowCreation(y_axis))
        self.play(Write(y_label, run_time = 1))
        self.dither(2)
        self.play(
            Write(origin_words),
            GrowFromCenter(dot),
            ShowCreation(line),
            run_time = 1
        )
        self.dither(2)
        self.play(
            FadeOut(VMobject(origin_words, dot, line))
        )
        self.remove(origin_words, dot, line)
        self.dither()
        self.play(
            ShowCreation(tick_marks, submobject_mode = "one_at_a_time")
        )
        self.play(
            GrowFromCenter(unit_brace),
            Write(one, run_time = 1)            
        )
        self.dither(2)
        self.remove(unit_brace, one)
        self.play(
            *map(GrowFromCenter, plane_lines) + [
            Animation(x_axis), Animation(y_axis)
        ])
        self.dither()
        self.play(
            FadeOut(plane),
            Animation(VMobject(x_axis, y_axis, tick_marks))
        )
        self.remove(plane)
        self.add(tick_marks)
Ejemplo n.º 23
0
 def construct(self):
     arrow = Vector(2*UP+RIGHT)
     vs = TextMobject("vs.")
     array = Matrix([1, 2])
     array.highlight(TEAL)
     everyone = VMobject(arrow, vs, array)
     everyone.arrange_submobjects(RIGHT, buff = 0.5)
     everyone.scale_to_fit_height(4)
     self.add(everyone)
Ejemplo n.º 24
0
 def add_symbols(self):
     v = matrix_to_mobject(self.v_coords).highlight(self.v_color)
     w = matrix_to_mobject(self.w_coords).highlight(self.w_color)
     v.add_background_rectangle()
     w.add_background_rectangle()
     dot = TexMobject("\\cdot")
     eq = VMobject(v, dot, w)
     eq.arrange_submobjects(RIGHT, buff = SMALL_BUFF)
     eq.to_corner(UP+LEFT)
     self.play(Write(eq), run_time = 1)
Ejemplo n.º 25
0
 def get_cross_product_question(self):
     cross = TexMobject("\\vec{v} \\times \\vec{w}")
     left_right_arrow = DoubleArrow(Point(LEFT), Point(RIGHT))
     det = TextMobject("Det")
     q_mark = TextMobject("?")
     left_right_arrow.next_to(cross)
     det.next_to(left_right_arrow)
     q_mark.next_to(left_right_arrow, UP)
     cross_question = VMobject(cross, left_right_arrow, q_mark, det)
     cross_question.get_center = lambda : left_right_arrow.get_center()
     return cross_question
Ejemplo n.º 26
0
    def animate_product(self, left, right, result):
        l_matrix = left.get_mob_matrix()
        r_matrix = right.get_mob_matrix()
        result_matrix = result.get_mob_matrix()
        circle = Circle(
            radius = l_matrix[0][0].get_height(),
            color = GREEN
        )
        circles = VMobject(*[
            entry.get_point_mobject()
            for entry in l_matrix[0][0], r_matrix[0][0]
        ])
        (m, k), n = l_matrix.shape, r_matrix.shape[1]
        for mob in result_matrix.flatten():
            mob.highlight(BLACK)
        lagging_anims = []
        for a in range(m):
            for b in range(n):
                for c in range(k):
                    l_matrix[a][c].highlight(YELLOW)
                    r_matrix[c][b].highlight(YELLOW)
                for c in range(k):
                    start_parts = VMobject(
                        l_matrix[a][c].copy(),
                        r_matrix[c][b].copy()
                    )
                    result_entry = result_matrix[a][b].split()[c]

                    new_circles = VMobject(*[
                        circle.copy().shift(part.get_center())
                        for part in start_parts.split()
                    ])
                    self.play(Transform(circles, new_circles))
                    self.play(
                        Transform(
                            start_parts, 
                            result_entry.copy().highlight(YELLOW), 
                            path_arc = -np.pi/2,
                            submobject_mode = "all_at_once",
                        ),
                        *lagging_anims
                    )
                    result_entry.highlight(YELLOW)
                    self.remove(start_parts)
                    lagging_anims = [
                        ApplyMethod(result_entry.highlight, WHITE)
                    ]

                for c in range(k):
                    l_matrix[a][c].highlight(WHITE)
                    r_matrix[c][b].highlight(WHITE)
        self.play(FadeOut(circles), *lagging_anims)
        self.dither()
Ejemplo n.º 27
0
 def init_colors(self):
     VMobject.init_colors(self)
     internal_pis = [
         pi
         for pi in self.submobject_family()
         if isinstance(pi, PiCreature)
     ]
     random.seed(self.random_seed)
     for pi in reversed(internal_pis):
         color = random.choice(self.colors)
         pi.highlight(color)
         pi.set_stroke(color, width = 0)
Ejemplo n.º 28
0
 def construct(self):
     self.lock_in_faded_grid()
     vectors = VMobject(*[
         Vector([x, y])
         for x in np.arange(-int(SPACE_WIDTH)+0.5, int(SPACE_WIDTH)+0.5)
         for y in np.arange(-int(SPACE_HEIGHT)+0.5, int(SPACE_HEIGHT)+0.5)
     ])
     vectors.submobject_gradient_highlight(PINK, BLUE_E)
     words = TextMobject("Span")
     words.scale(3)
     words.to_edge(UP)
     words.add_background_rectangle()
     self.add(vectors, words)
Ejemplo n.º 29
0
    def construct(self):
        words = map(TextMobject, [
            "Just brushing up",
            "Has yet to take the course",
            "Supplementing course concurrently",
        ])
        students = VMobject(*[
            Randolph(color = c)
            for c in BLUE_D, BLUE_C, BLUE_E
        ])
        modes = ["pondering", "speaking_looking_left", "sassy"]
        students.arrange_submobjects(RIGHT)
        students.scale(0.8)
        students.center().to_edge(DOWN)

        last_word, last_arrow = None, None
        for word, student, mode in zip(words, students.split(), modes):
            word.shift(2*UP)
            arrow = Arrow(word, student)
            if last_word:
                word_anim = Transform(last_word, word)
                arrow_anim = Transform(last_arrow, arrow)
            else:
                word_anim = Write(word, run_time = 1)
                arrow_anim = ShowCreation(arrow, submobject_mode = "one_at_a_time")
                last_word = word
                last_arrow = arrow
            self.play(
                word_anim, arrow_anim,
                ApplyMethod(student.change_mode, mode)
            )
            self.play(Blink(student))
            self.dither()
        self.dither()
Ejemplo n.º 30
0
 def name_parts(self):
     self.mouth = self.submobjects[MOUTH_INDEX]
     self.body = self.submobjects[BODY_INDEX]
     self.pupils = VMobject(*[
         self.submobjects[LEFT_PUPIL_INDEX],
         self.submobjects[RIGHT_PUPIL_INDEX]
     ])
     self.eyes = VMobject(*[
         self.submobjects[LEFT_EYE_INDEX],
         self.submobjects[RIGHT_EYE_INDEX]
     ])
     self.submobjects = []
     self.add(self.body, self.mouth, self.eyes, self.pupils)
     self.parts_named = True
Ejemplo n.º 31
0
 def __init__(self, angle, **kwargs):
     digest_locals(self)
     VMobject.__init__(self, **kwargs)
Ejemplo n.º 32
0
 def fade_all_but(self, creatures, index):
     self.play(*[
         FadeOut(VMobject(pi, pi.title))
         for pi in creatures[:index] + creatures[index + 1:]
     ])
Ejemplo n.º 33
0
    def construct(self):
        m1_mob, m2_mob, comp_matrix = self.get_matrices()
        self.add(m1_mob, m2_mob, m1_mob.label, m2_mob.label, comp_matrix)
        result = self.get_result()

        col1, col2 = [
            VMobject(*m1_mob.split()[1].get_mob_matrix()[:, i]) for i in 0, 1
        ]
        col1.target_color = X_COLOR
        col2.target_color = Y_COLOR
        for col in col1, col2:
            circle = Circle()
            circle.stretch_to_fit_height(m1_mob.get_height())
            circle.stretch_to_fit_width(m1_mob.get_width() / 2.5)
            circle.highlight(col.target_color)
            circle.move_to(col)
            col.circle = circle

        triplets = [
            (col1, "i", X_COLOR),
            (col2, "j", Y_COLOR),
        ]
        for i, (col, char, color) in enumerate(triplets):
            self.add(col)
            start_state = self.get_mobjects()
            question = TextMobject("Where does $\\hat{\\%smath}$ go?" % char)
            question.split()[-4].highlight(color)
            question.split()[-5].highlight(color)
            question.scale(1.2)
            question.shift(DOWN)
            first = TextMobject("First here")
            first.highlight(color)
            first.shift(DOWN + LEFT)
            first_arrow = Arrow(first, col.circle.get_bottom(), color=color)
            second = TextMobject("Then to whatever this is")
            second.highlight(color)
            second.to_edge(RIGHT).shift(DOWN)

            m2_copy = m2_mob.copy()
            m2_target = m2_mob.copy()
            m2_target.next_to(m2_mob, DOWN, buff=1)
            col_vect = Matrix(col.copy().split())
            col_vect.highlight(color)
            col_vect.next_to(m2_target, RIGHT, buff=0.1)
            second_arrow = Arrow(second, col_vect, color=color)

            new_m2_copy = m2_mob.copy().split()[1]
            intermediate = VMobject(TexMobject("="),
                                    col_vect.copy().get_entries().split()[0],
                                    Matrix(new_m2_copy.get_mob_matrix()[:, 0]),
                                    TexMobject("+"),
                                    col_vect.copy().get_entries().split()[1],
                                    Matrix(new_m2_copy.get_mob_matrix()[:, 1]),
                                    TexMobject("="))
            intermediate.arrange_submobjects(buff=0.1)
            intermediate.next_to(col_vect, RIGHT)

            product = Matrix(result[:, i])
            product.next_to(intermediate, RIGHT)

            comp_col = VMobject(*comp_matrix.split()[1].get_mob_matrix()[:, i])

            self.play(Write(question, run_time=1))
            self.dither()
            self.play(Transform(question, first), ShowCreation(first_arrow),
                      ShowCreation(col.circle),
                      ApplyMethod(col.highlight, col.target_color))
            self.dither()
            self.play(
                Transform(m2_copy, m2_target, run_time=2),
                ApplyMethod(col.copy().move_to, col_vect, run_time=2),
                Write(col_vect.get_brackets()),
                Transform(first_arrow, second_arrow),
                Transform(question, second),
            )
            self.dither()
            self.play(*map(FadeOut, [question, first_arrow]))
            self.play(Write(intermediate))
            self.dither()
            self.play(Write(product))
            self.dither()
            product_entries = product.get_entries()
            self.play(ApplyMethod(comp_col.highlight, BLACK),
                      ApplyMethod(product_entries.move_to, comp_col))
            self.dither()

            start_state.append(product_entries)
            self.play(*[
                FadeOut(mob)
                for mob in self.get_mobjects() if mob not in start_state
            ] + [Animation(product_entries)])
            self.dither()
Ejemplo n.º 34
0
    def construct(self):
        randy = Randolph(color = PINK)
        randy.look(LEFT)
        randy.to_corner()
        matrix = Matrix([
            [3, 1],
            [4, 1],
            [5, 9],
        ])
        matrix.next_to(randy, RIGHT, buff = LARGE_BUFF, aligned_edge = DOWN)
        bubble = randy.get_bubble(height = 4)
        bubble.make_green_screen()
        VMobject(randy, bubble, matrix).to_corner(UP+LEFT, buff = MED_SMALL_BUFF)

        self.add(randy)
        self.play(Write(matrix))
        self.play(randy.look, RIGHT, run_time = 0.5)
        self.play(randy.change_mode, "sassy")
        self.play(Blink(randy))
        self.play(
            ShowCreation(bubble),
            randy.change_mode, "pondering"
        )
        # self.play(matrix.highlight_columns, X_COLOR, Y_COLOR)
        self.wait()
        for x in range(3):
            self.play(Blink(randy))
            self.wait(2)
        new_matrix = Matrix([[3, 1, 4], [1, 5, 9]])
        new_matrix.move_to(matrix, aligned_edge = UP+LEFT)
        self.play(
            Transform(matrix, new_matrix),
            FadeOut(bubble)
        )
        self.remove(matrix)
        matrix = new_matrix
        self.add(matrix)
        self.play(randy.look, DOWN+RIGHT, run_time = 0.5)
        self.play(randy.change_mode, "confused")
        self.wait()
        self.play(Blink(randy))
        self.wait()

        top_brace = Brace(matrix, UP)
        top_words = top_brace.get_text("3 basis vectors")
        top_words.submobject_gradient_highlight(GREEN, RED, BLUE)
        side_brace = Brace(matrix, RIGHT)
        side_words = side_brace.get_text("""
            2 coordinates for
            each landing spots
        """)
        side_words.highlight(YELLOW)

        self.play(
            GrowFromCenter(top_brace),
            Write(top_words),
            matrix.highlight_columns, X_COLOR, Y_COLOR, Z_COLOR
        )
        self.play(randy.change_mode, "happy")
        self.play(
            GrowFromCenter(side_brace),
            Write(side_words, run_time = 2)
        )
        self.play(Blink(randy))
        self.wait()
Ejemplo n.º 35
0
 def get_piece_movement(self, pieces):
     start = VMobject(*pieces)
     target = VMobject(*[mob.target for mob in pieces])
     if self.leave_ghost_vectors:
         self.add(start.copy().fade(0.7))
     return Transform(start, target, submobject_mode="all_at_once")
Ejemplo n.º 36
0
 def __init__(self, mobject, **kwargs):
     VMobject.__init__(self, **kwargs)
     self.mobject = mobject
     self.submobjects = self.get_eyes().submobjects
Ejemplo n.º 37
0
 def init_colors(self):
     VMobject.init_colors(self)
     self.gradient_highlight(*self.colors)
Ejemplo n.º 38
0
 def clear(self):
     self.add_content(VMobject())
     return self
Ejemplo n.º 39
0
 def get_center(self):
     result = VMobject.get_center(self)
     if hasattr(self, "center_offset"):
         result -= self.center_offset
     return result
Ejemplo n.º 40
0
 def __init__(self, rows, columns, **kwargs):
     digest_config(self, kwargs, locals())
     VMobject.__init__(self, **kwargs)
Ejemplo n.º 41
0
 def __init__(self, *vertices, **kwargs):
     assert len(vertices) > 1
     digest_locals(self)
     VMobject.__init__(self, **kwargs)
Ejemplo n.º 42
0
 def __init__(self, points, **kwargs):
     VMobject.__init__(self, **kwargs)
     self.set_points(points)
Ejemplo n.º 43
0
 def __init__(self, start, end, **kwargs):
     digest_config(self, kwargs)
     self.set_start_and_end(start, end)
     VMobject.__init__(self, **kwargs)
Ejemplo n.º 44
0
 def __init__(self, **kwargs):
     digest_config(self, kwargs)
     if self.leftmost_tick is None:
         self.leftmost_tick = np.ceil(self.x_min)
     VMobject.__init__(self, **kwargs)
Ejemplo n.º 45
0
 def shift_brace(self, obj, **kwargs):
     if isinstance(obj, list): obj = VMobject(*obj)
     self.brace = Brace(obj, self.brace_direction, **kwargs)
     self.brace.put_at_tip(self.desc)
     self.submobjects[0] = self.brace
     return self
Ejemplo n.º 46
0
class NumberPlane(VMobject):
    CONFIG = {
        "color" : BLUE_D,
        "secondary_color" : BLUE_E,
        "axes_color" : WHITE,
        "secondary_stroke_width" : 1,
        "x_radius": None,
        "y_radius": None,
        "x_unit_size" : 1,
        "y_unit_size" : 1,
        "center_point" : ORIGIN,
        "x_line_frequency" : 1,
        "y_line_frequency" : 1,
        "secondary_line_ratio" : 1,
        "written_coordinate_height" : 0.2,
        "propogate_style_to_family" : False,
    }
    
    def generate_points(self):
        if self.x_radius is None:
            center_to_edge = (SPACE_WIDTH + abs(self.center_point[0])) 
            self.x_radius = center_to_edge / self.x_unit_size
        if self.y_radius is None:
            center_to_edge = (SPACE_HEIGHT + abs(self.center_point[1])) 
            self.y_radius = center_to_edge / self.y_unit_size
        self.axes = VMobject()
        self.main_lines = VMobject()
        self.secondary_lines = VMobject()
        tuples = [
            (
                self.x_radius, 
                self.x_line_frequency, 
                self.y_radius*DOWN, 
                self.y_radius*UP,
                RIGHT
            ),
            (
                self.y_radius, 
                self.y_line_frequency, 
                self.x_radius*LEFT, 
                self.x_radius*RIGHT,
                UP,
            ),
        ]
        for radius, freq, start, end, unit in tuples:
            main_range = np.arange(0, radius, freq)
            step = freq/float(freq + self.secondary_line_ratio)
            for v in np.arange(0, radius, step):
                line1 = Line(start+v*unit, end+v*unit)
                line2 = Line(start-v*unit, end-v*unit)                
                if v == 0:
                    self.axes.add(line1)
                elif v in main_range:
                    self.main_lines.add(line1, line2)
                else:
                    self.secondary_lines.add(line1, line2)
        self.add(self.secondary_lines, self.main_lines, self.axes)
        self.stretch(self.x_unit_size, 0)
        self.stretch(self.y_unit_size, 1)
        self.shift(self.center_point)
        #Put x_axis before y_axis
        y_axis, x_axis = self.axes.split()
        self.axes = VMobject(x_axis, y_axis)

    def init_colors(self):
        VMobject.init_colors(self)
        self.axes.set_stroke(self.axes_color, self.stroke_width)
        self.main_lines.set_stroke(self.color, self.stroke_width)
        self.secondary_lines.set_stroke(
            self.secondary_color, self.secondary_stroke_width
        )
        return self

    def get_center_point(self):
        return self.coords_to_point(0, 0)

    def coords_to_point(self, x, y):
        x, y = np.array([x, y])
        result = self.axes.get_center()
        result += x*self.get_x_unit_size()*RIGHT
        result += y*self.get_y_unit_size()*UP
        return result

    def point_to_coords(self, point):
        new_point = point - self.axes.get_center()
        x = new_point[0]/self.get_x_unit_size()
        y = new_point[1]/self.get_y_unit_size()
        return x, y

    def get_x_unit_size(self):
        return self.axes.get_width() / (2.0*self.x_radius)

    def get_y_unit_size(self):
        return self.axes.get_height() / (2.0*self.y_radius)

    def get_coordinate_labels(self, x_vals = None, y_vals = None):
        result = []
        if x_vals == None and y_vals == None:
            x_vals = range(-int(self.x_radius), int(self.x_radius))
            y_vals = range(-int(self.y_radius), int(self.y_radius))
        for index, vals in enumerate([x_vals, y_vals]):
            num_pair = [0, 0]
            for val in vals:
                if val == 0:
                    continue
                num_pair[index] = val
                point = self.coords_to_point(*num_pair)
                num = TexMobject(str(val))
                num.add_background_rectangle()
                num.scale_to_fit_height(
                    self.written_coordinate_height
                )
                vect = DOWN if index == 0 else LEFT
                num.next_to(point, vect, buff = SMALL_BUFF)
                result.append(num)
        return result

    def get_axes(self):
        return self.axes

    def get_axis_labels(self, x_label = "x", y_label = "y"):
        x_axis, y_axis = self.get_axes().split()
        quads = [
            (x_axis, x_label, UP, RIGHT),
            (y_axis, y_label, RIGHT, UP),
        ]
        labels = VGroup()
        for axis, tex, vect, edge in quads:
            label = TexMobject(tex)
            label.add_background_rectangle()
            label.next_to(axis, vect)
            label.to_edge(edge)
            labels.add(label)
        self.axis_labels = labels
        return labels

    def add_coordinates(self, x_vals = None, y_vals = None):
        self.add(*self.get_coordinate_labels(x_vals, y_vals))
        return self

    def get_vector(self, coords, **kwargs):
        point = coords[0]*RIGHT + coords[1]*UP
        arrow = Arrow(ORIGIN, coords, **kwargs)
        return arrow

    def prepare_for_nonlinear_transform(self, num_inserted_anchor_points = 50):
        for mob in self.family_members_with_points():
            num_anchors = mob.get_num_anchor_points()
            if num_inserted_anchor_points > num_anchors:
                mob.insert_n_anchor_points(num_inserted_anchor_points-num_anchors)
                mob.make_smooth()
        return self

    def apply_function(self, function, maintain_smoothness = True):
        SVGMobject.apply_function(self, function, maintain_smoothness = maintain_smoothness)
Ejemplo n.º 47
0
 def init_colors(self):
     VMobject.init_colors(self)
     self.gradient_highlight(*self.colors)
     for order in sorted(self.order_to_stroke_width_map.keys()):
         if self.order >= order:
             self.set_stroke(width=self.order_to_stroke_width_map[order])
Ejemplo n.º 48
0
class NumberLine(VMobject):
    CONFIG = {
        "color": BLUE,
        "x_min": -SPACE_WIDTH,
        "x_max": SPACE_WIDTH,
        "space_unit_to_num": 1,
        "tick_size": 0.1,
        "tick_frequency": 1,
        "leftmost_tick": None,  #Defaults to ceil(x_min)
        "numbers_with_elongated_ticks": [0],
        "longer_tick_multiple": 2,
        "number_at_center": 0,
        "propogate_style_to_family": True
    }

    def __init__(self, **kwargs):
        digest_config(self, kwargs)
        if self.leftmost_tick is None:
            self.leftmost_tick = np.ceil(self.x_min)
        VMobject.__init__(self, **kwargs)

    def generate_points(self):
        self.main_line = Line(self.x_min * RIGHT, self.x_max * RIGHT)
        self.tick_marks = VMobject()
        self.add(self.main_line, self.tick_marks)
        for x in self.get_tick_numbers():
            self.add_tick(x, self.tick_size)
        for x in self.numbers_with_elongated_ticks:
            self.add_tick(x, self.longer_tick_multiple * self.tick_size)
        self.stretch(self.space_unit_to_num, 0)
        self.shift(-self.number_to_point(self.number_at_center))

    def add_tick(self, x, size):
        self.tick_marks.add(
            Line(
                x * RIGHT + size * DOWN,
                x * RIGHT + size * UP,
            ))
        return self

    def get_tick_marks(self):
        return self.tick_marks

    def get_tick_numbers(self):
        return np.arange(self.leftmost_tick, self.x_max, self.tick_frequency)

    def number_to_point(self, number):
        return interpolate(
            self.main_line.get_left(), self.main_line.get_right(),
            float(number - self.x_min) / (self.x_max - self.x_min))

    def point_to_number(self, point):
        dist_from_left = (point[0] - self.main_line.get_left()[0])
        num_dist_from_left = num_dist_from_left / self.space_unit_to_num
        return self.x_min + dist_from_left

    def default_numbers_to_display(self):
        return np.arange(self.leftmost_tick, self.x_max, 1)

    def get_vertical_number_offset(self, direction=DOWN):
        return 4 * direction * self.tick_size

    def get_number_mobjects(self, *numbers, **kwargs):
        #TODO, handle decimals
        if len(numbers) == 0:
            numbers = self.default_numbers_to_display()
        result = VGroup()
        for number in numbers:
            mob = TexMobject(str(int(number)))
            mob.scale_to_fit_height(3 * self.tick_size)
            mob.shift(self.number_to_point(number),
                      self.get_vertical_number_offset(**kwargs))
            result.add(mob)
        return result

    def add_numbers(self, *numbers, **kwargs):
        self.numbers = self.get_number_mobjects(*numbers, **kwargs)
        self.add(*self.numbers)
        return self
Ejemplo n.º 49
0
class PiCreature(SVGMobject):
    CONFIG = {
        "color": BLUE_E,
        "stroke_width": 0,
        "fill_opacity": 1.0,
        "initial_scale_factor": 0.01,
        "corner_scale_factor": 0.75,
        "flip_at_start": False,
    }

    def __init__(self, mode="plain", **kwargs):
        self.parts_named = False
        svg_file = os.path.join(PI_CREATURE_DIR, "PiCreatures_%s.svg" % mode)
        digest_config(self, kwargs, locals())
        SVGMobject.__init__(self, svg_file, **kwargs)
        self.init_colors()
        if self.flip_at_start:
            self.flip()

    def name_parts(self):
        self.mouth = self.submobjects[MOUTH_INDEX]
        self.body = self.submobjects[BODY_INDEX]
        self.pupils = VMobject(*[
            self.submobjects[LEFT_PUPIL_INDEX],
            self.submobjects[RIGHT_PUPIL_INDEX]
        ])
        self.eyes = VMobject(*[
            self.submobjects[LEFT_EYE_INDEX], self.submobjects[RIGHT_EYE_INDEX]
        ])
        self.submobjects = []
        self.add(self.body, self.mouth, self.eyes, self.pupils)
        self.parts_named = True

    def init_colors(self):
        self.set_stroke(color=BLACK, width=self.stroke_width)
        if not self.parts_named:
            self.name_parts()
        self.mouth.set_fill(BLACK, opacity=1)
        self.body.set_fill(self.color, opacity=1)
        self.pupils.set_fill(BLACK, opacity=1)
        self.eyes.set_fill(WHITE, opacity=1)
        return self

    def highlight(self, color):
        self.body.set_fill(color)
        return self

    def move_to(self, destination):
        self.shift(destination - self.get_bottom())
        return self

    def change_mode(self, mode):
        curr_center = self.get_center()
        curr_height = self.get_height()
        looking_direction = None
        looking_direction = self.get_looking_direction()
        should_be_flipped = self.is_flipped()
        self.__init__(mode)
        self.scale_to_fit_height(curr_height)
        self.shift(curr_center)
        self.look(looking_direction)
        if should_be_flipped ^ self.is_flipped():
            self.flip()
        return self

    def look(self, direction):
        x, y = direction[:2]
        for pupil, eye in zip(self.pupils.split(), self.eyes.split()):
            pupil.move_to(eye, aligned_edge=direction)
            #Some hacky nudging is required here
            if y > 0 and x != 0:  # Look up and to a side
                nudge_size = pupil.get_height() / 4.
                if x > 0:
                    nudge = nudge_size * (DOWN + LEFT)
                else:
                    nudge = nudge_size * (DOWN + RIGHT)
                pupil.shift(nudge)
            elif y < 0:
                nudge_size = pupil.get_height() / 8.
                pupil.shift(nudge_size * UP)
        return self

    def get_looking_direction(self):
        return np.sign(
            np.round(self.pupils.get_center() - self.eyes.get_center(),
                     decimals=1))

    def is_flipped(self):
        return self.eyes.submobjects[0].get_center()[0] > \
               self.eyes.submobjects[1].get_center()[0]

    def blink(self):
        eye_bottom_y = self.eyes.get_bottom()[1]
        for mob in self.eyes, self.pupils:
            mob.apply_function(lambda p: [p[0], eye_bottom_y, p[2]])
        return self

    def to_corner(self, vect=None):
        if vect is not None:
            SVGMobject.to_corner(self, vect)
        else:
            self.scale(self.corner_scale_factor)
            self.to_corner(DOWN + LEFT)
        return self

    def get_bubble(self, bubble_type="thought", **kwargs):
        if bubble_type == "thought":
            bubble = ThoughtBubble(**kwargs)
        elif bubble_type == "speech":
            bubble = SpeechBubble(**kwargs)
        else:
            raise Exception("%s is an invalid bubble type" % bubble_type)
        bubble.pin_to(self)
        return bubble
Ejemplo n.º 50
0
class NumberPlane(VMobject):
    CONFIG = {
        "color": BLUE_D,
        "secondary_color": BLUE_E,
        "axes_color": WHITE,
        "secondary_stroke_width": 1,
        "x_radius": SPACE_WIDTH,
        "y_radius": SPACE_HEIGHT,
        "space_unit_to_x_unit": 1,
        "space_unit_to_y_unit": 1,
        "x_line_frequency": 1,
        "y_line_frequency": 1,
        "secondary_line_ratio": 1,
        "written_coordinate_height": 0.2,
        "written_coordinate_nudge": 0.1 * (DOWN + RIGHT),
        "num_pair_at_center": (0, 0),
        "propogate_style_to_family": False,
    }

    def generate_points(self):
        self.axes = VMobject()
        self.main_lines = VMobject()
        self.secondary_lines = VMobject()
        tuples = [
            (self.x_radius, self.x_line_frequency, self.y_radius * DOWN,
             self.y_radius * UP, RIGHT),
            (
                self.y_radius,
                self.y_line_frequency,
                self.x_radius * LEFT,
                self.x_radius * RIGHT,
                UP,
            ),
        ]
        for radius, freq, start, end, unit in tuples:
            main_range = np.arange(0, radius, freq)
            step = freq / float(freq + self.secondary_line_ratio)
            for v in np.arange(0, radius, step):
                line1 = Line(start + v * unit, end + v * unit)
                line2 = Line(start - v * unit, end - v * unit)
                if v == 0:
                    self.axes.add(line1)
                elif v in main_range:
                    self.main_lines.add(line1, line2)
                else:
                    self.secondary_lines.add(line1, line2)
        self.add(self.axes, self.main_lines, self.secondary_lines)
        self.stretch(self.space_unit_to_x_unit, 0)
        self.stretch(self.space_unit_to_y_unit, 1)
        #Put x_axis before y_axis
        y_axis, x_axis = self.axes.split()
        self.axes = VMobject(x_axis, y_axis)

    def init_colors(self):
        VMobject.init_colors(self)
        self.axes.set_stroke(self.axes_color, self.stroke_width)
        self.main_lines.set_stroke(self.color, self.stroke_width)
        self.secondary_lines.set_stroke(self.secondary_color,
                                        self.secondary_stroke_width)
        return self

    def get_center_point(self):
        return self.num_pair_to_point(self.num_pair_at_center)

    def num_pair_to_point(self, pair):
        pair = np.array(pair) + self.num_pair_at_center
        result = self.get_center()
        result[0] += pair[0] * self.space_unit_to_x_unit
        result[1] += pair[1] * self.space_unit_to_y_unit
        return result

    def point_to_num_pair(self, point):
        new_point = point - self.get_center()
        center_x, center_y = self.num_pair_at_center
        x = center_x + point[0] / self.space_unit_to_x_unit
        y = center_y + point[1] / self.space_unit_to_y_unit
        return x, y

    def get_coordinate_labels(self, x_vals=None, y_vals=None):
        result = []
        if x_vals == None and y_vals == None:
            x_vals = range(-int(self.x_radius), int(self.x_radius))
            y_vals = range(-int(self.y_radius), int(self.y_radius))
        for index, vals in enumerate([x_vals, y_vals]):
            num_pair = [0, 0]
            for val in vals:
                num_pair[index] = val
                point = self.num_pair_to_point(num_pair)
                num = TexMobject(str(val))
                num.scale_to_fit_height(self.written_coordinate_height)
                num.shift(point - num.get_corner(UP + LEFT),
                          self.written_coordinate_nudge)
                result.append(num)
        return result

    def get_axes(self):
        return self.axes

    def get_axis_labels(self, x_label="x", y_label="y"):
        x_axis, y_axis = self.get_axes().split()
        x_label_mob = TexMobject(x_label)
        y_label_mob = TexMobject(y_label)
        x_label_mob.next_to(x_axis, DOWN)
        x_label_mob.to_edge(RIGHT)
        y_label_mob.next_to(y_axis, RIGHT)
        y_label_mob.to_edge(UP)
        return VMobject(x_label_mob, y_label_mob)

    def add_coordinates(self, x_vals=None, y_vals=None):
        self.add(*self.get_coordinate_labels(x_vals, y_vals))
        return self

    def get_vector(self, coords, **kwargs):
        point = coords[0] * RIGHT + coords[1] * UP
        arrow = Arrow(ORIGIN, coords, **kwargs)
        return arrow

    def prepare_for_nonlinear_transform(self, num_inserted_anchor_points=50):
        for mob in self.family_members_with_points():
            mob.insert_n_anchor_points(num_inserted_anchor_points)
            mob.make_smooth()
        return self
Ejemplo n.º 51
0
 def __init__(self, **kwargs):
     VMobject.__init__(self, **kwargs)
     for submobject in self.submobject_family():
         submobject.part_of_three_d_mobject = True
Ejemplo n.º 52
0
class NumberPlane(VMobject):
    CONFIG = {
        "color": BLUE_D,
        "secondary_color": BLUE_E,
        "axes_color": WHITE,
        "secondary_stroke_width": 1,
        # TODO: Allow coordinate center of NumberPlane to not be at (0, 0)
        "x_radius": None,
        "y_radius": None,
        "x_unit_size": 1,
        "y_unit_size": 1,
        "center_point": ORIGIN,
        "x_line_frequency": 1,
        "y_line_frequency": 1,
        "secondary_line_ratio": 1,
        "written_coordinate_height": 0.2,
        "propagate_style_to_family": False,
        "make_smooth_after_applying_functions": True,
    }

    def generate_points(self):
        if self.x_radius is None:
            center_to_edge = (SPACE_WIDTH + abs(self.center_point[0]))
            self.x_radius = center_to_edge / self.x_unit_size
        if self.y_radius is None:
            center_to_edge = (SPACE_HEIGHT + abs(self.center_point[1]))
            self.y_radius = center_to_edge / self.y_unit_size
        self.axes = VMobject()
        self.main_lines = VMobject()
        self.secondary_lines = VMobject()
        tuples = [
            (self.x_radius, self.x_line_frequency, self.y_radius * DOWN,
             self.y_radius * UP, RIGHT),
            (
                self.y_radius,
                self.y_line_frequency,
                self.x_radius * LEFT,
                self.x_radius * RIGHT,
                UP,
            ),
        ]
        for radius, freq, start, end, unit in tuples:
            main_range = np.arange(0, radius, freq)
            step = freq / float(freq + self.secondary_line_ratio)
            for v in np.arange(0, radius, step):
                line1 = Line(start + v * unit, end + v * unit)
                line2 = Line(start - v * unit, end - v * unit)
                if v == 0:
                    self.axes.add(line1)
                elif v in main_range:
                    self.main_lines.add(line1, line2)
                else:
                    self.secondary_lines.add(line1, line2)
        self.add(self.secondary_lines, self.main_lines, self.axes)
        self.stretch(self.x_unit_size, 0)
        self.stretch(self.y_unit_size, 1)
        self.shift(self.center_point)
        #Put x_axis before y_axis
        y_axis, x_axis = self.axes.split()
        self.axes = VMobject(x_axis, y_axis)

    def init_colors(self):
        VMobject.init_colors(self)
        self.axes.set_stroke(self.axes_color, self.stroke_width)
        self.main_lines.set_stroke(self.color, self.stroke_width)
        self.secondary_lines.set_stroke(self.secondary_color,
                                        self.secondary_stroke_width)
        return self

    def get_center_point(self):
        return self.coords_to_point(0, 0)

    def coords_to_point(self, x, y):
        x, y = np.array([x, y])
        result = self.axes.get_center()
        result += x * self.get_x_unit_size() * RIGHT
        result += y * self.get_y_unit_size() * UP
        return result

    def point_to_coords(self, point):
        new_point = point - self.axes.get_center()
        x = new_point[0] / self.get_x_unit_size()
        y = new_point[1] / self.get_y_unit_size()
        return x, y

    # Does not recompute center, unit_sizes for each call; useful for
    # iterating over large lists of points, but does assume these
    # attributes are kept accurate. (Could alternatively have a method
    # which returns a function dynamically created after a single
    # call to each of get_center(), get_x_unit_size(), etc.)
    def point_to_coords_cheap(self, point):
        new_point = point - self.center_point
        x = new_point[0] / self.x_unit_size
        y = new_point[1] / self.y_unit_size
        return x, y

    def get_x_unit_size(self):
        return self.axes.get_width() / (2.0 * self.x_radius)

    def get_y_unit_size(self):
        return self.axes.get_height() / (2.0 * self.y_radius)

    def get_coordinate_labels(self, x_vals=None, y_vals=None):
        coordinate_labels = VGroup()
        if x_vals == None:
            x_vals = range(-int(self.x_radius), int(self.x_radius) + 1)
        if y_vals == None:
            y_vals = range(-int(self.y_radius), int(self.y_radius) + 1)
        for index, vals in enumerate([x_vals, y_vals]):
            num_pair = [0, 0]
            for val in vals:
                if val == 0:
                    continue
                num_pair[index] = val
                point = self.coords_to_point(*num_pair)
                num = TexMobject(str(val))
                num.add_background_rectangle()
                num.scale_to_fit_height(self.written_coordinate_height)
                num.next_to(point, DOWN + LEFT, buff=SMALL_BUFF)
                coordinate_labels.add(num)
        self.coordinate_labels = coordinate_labels
        return coordinate_labels

    def get_axes(self):
        return self.axes

    def get_axis_labels(self, x_label="x", y_label="y"):
        x_axis, y_axis = self.get_axes().split()
        quads = [
            (x_axis, x_label, UP, RIGHT),
            (y_axis, y_label, RIGHT, UP),
        ]
        labels = VGroup()
        for axis, tex, vect, edge in quads:
            label = TexMobject(tex)
            label.add_background_rectangle()
            label.next_to(axis, vect)
            label.to_edge(edge)
            labels.add(label)
        self.axis_labels = labels
        return labels

    def add_coordinates(self, x_vals=None, y_vals=None):
        self.add(*self.get_coordinate_labels(x_vals, y_vals))
        return self

    def get_vector(self, coords, **kwargs):
        point = coords[0] * RIGHT + coords[1] * UP
        arrow = Arrow(ORIGIN, coords, **kwargs)
        return arrow

    def prepare_for_nonlinear_transform(self, num_inserted_anchor_points=50):
        for mob in self.family_members_with_points():
            num_anchors = mob.get_num_anchor_points()
            if num_inserted_anchor_points > num_anchors:
                mob.insert_n_anchor_points(num_inserted_anchor_points -
                                           num_anchors)
                mob.make_smooth()
        return self
Ejemplo n.º 53
0
 def __init__(self, function, **kwargs):
     self.function = function
     VMobject.__init__(self, **kwargs)
Ejemplo n.º 54
0
    def construct(self):
        plus = TexMobject("+")
        equals = TexMobject("=")
        randy = Randolph()
        randy.scale_to_fit_height(1)
        randy.shift(-randy.get_bottom())

        axes = self.add_axes()
        x_axis, y_axis = axes.split()

        v1 = self.add_vector([1, 2])
        coords1, x_line1, y_line1 = self.vector_to_coords(v1, clean_up=False)
        self.play(
            ApplyFunction(lambda m: m.next_to(y_axis, RIGHT).to_edge(UP),
                          coords1))
        plus.next_to(coords1, RIGHT)

        v2 = self.add_vector([3, -1], color=MAROON_B)
        coords2, x_line2, y_line2 = self.vector_to_coords(v2, clean_up=False)
        self.dither()
        self.play(
            ApplyMethod(coords2.next_to, plus, RIGHT), Write(plus, run_time=1),
            *[
                ApplyMethod(mob.shift, v1.get_end())
                for mob in v2, x_line2, y_line2
            ])
        equals.next_to(coords2, RIGHT)
        self.dither()

        self.play(FadeIn(randy))
        for step in [RIGHT, 2 * UP, 3 * RIGHT, DOWN]:
            self.play(ApplyMethod(randy.shift, step, run_time=1.5))
        self.dither()
        self.play(ApplyMethod(randy.shift, -randy.get_bottom()))

        self.play(ApplyMethod(x_line2.shift, 2 * DOWN))
        self.play(ApplyMethod(y_line1.shift, 3 * RIGHT))
        for step in [4 * RIGHT, 2 * UP, DOWN]:
            self.play(ApplyMethod(randy.shift, step))
        self.play(FadeOut(randy))
        self.remove(randy)
        one_brace = Brace(x_line1)
        three_brace = Brace(x_line2)
        one = TexMobject("1").next_to(one_brace, DOWN)
        three = TexMobject("3").next_to(three_brace, DOWN)
        self.play(GrowFromCenter(one_brace),
                  GrowFromCenter(three_brace),
                  Write(one),
                  Write(three),
                  run_time=1)
        self.dither()

        two_brace = Brace(y_line1, RIGHT)
        two = TexMobject("2").next_to(two_brace, RIGHT)
        new_y_line = Line(4 * RIGHT, 4 * RIGHT + UP, color=Y_COLOR)
        two_minus_one_brace = Brace(new_y_line, RIGHT)
        two_minus_one = TexMobject("2+(-1)").next_to(two_minus_one_brace,
                                                     RIGHT)
        self.play(GrowFromCenter(two_brace), Write(two, run_time=1))
        self.dither()
        self.play(Transform(two_brace, two_minus_one_brace),
                  Transform(two,
                            two_minus_one), Transform(y_line1, new_y_line),
                  Transform(y_line2, new_y_line))
        self.dither()
        self.add_vector(v2.get_end(), color=PINK)

        sum_coords = Matrix(["1+3", "2+(-1)"])
        sum_coords.scale_to_fit_height(coords1.get_height())
        sum_coords.next_to(equals, RIGHT)
        brackets = sum_coords.get_brackets()
        x1, y1 = coords1.get_mob_matrix().flatten()
        x2, y2 = coords2.get_mob_matrix().flatten()
        sum_x, sum_y = sum_coords.get_mob_matrix().flatten()
        sum_x_start = VMobject(x1, x2).copy()
        sum_y_start = VMobject(y1, y2).copy()
        self.play(Write(brackets),
                  Write(equals),
                  Transform(sum_x_start, sum_x),
                  run_time=1)
        self.play(Transform(sum_y_start, sum_y))
        self.dither(2)

        starters = [x1, y1, x2, y2, sum_x_start, sum_y_start]
        variables = map(TexMobject,
                        ["x_1", "y_1", "x_2", "y_2", "x_1+y_1", "x_2+y_2"])
        for i, (var, starter) in enumerate(zip(variables, starters)):
            if i % 2 == 0:
                var.highlight(X_COLOR)
            else:
                var.highlight(Y_COLOR)
            var.scale(VECTOR_LABEL_SCALE_FACTOR)
            var.move_to(starter)
        self.play(Transform(VMobject(*starters[:4]), VMobject(*variables[:4])),
                  FadeOut(sum_x_start), FadeOut(sum_y_start))
        sum_x_end, sum_y_end = variables[-2:]
        self.dither(2)
        self.play(Transform(VMobject(x1, x2).copy(), sum_x_end))
        self.play(Transform(VMobject(y1, y2).copy(), sum_y_end))
        self.dither(3)
Ejemplo n.º 55
0
    def construct(self):
        vect = Matrix(["x", "y"])
        vect.get_entries().highlight(YELLOW)

        rot_matrix = Matrix([[0, -1], [1, 0]])
        rot_matrix.highlight(TEAL)
        shear_matrix = Matrix([[1, 1], [0, 1]])
        shear_matrix.highlight(PINK)
        l_paren, r_paren = map(TexMobject, ["\\Big(", "\\Big)"])
        for p in l_paren, r_paren:
            p.scale_to_fit_height(1.4 * vect.get_height())
        long_way = VMobject(shear_matrix, l_paren, rot_matrix, vect, r_paren)
        long_way.arrange_submobjects(buff=0.1)
        long_way.to_edge(LEFT).shift(UP)

        equals = TexMobject("=").next_to(long_way, RIGHT)

        comp_matrix = Matrix([[1, -1], [1, 0]])
        comp_matrix.highlight_columns(X_COLOR, Y_COLOR)
        vect_copy = vect.copy()
        short_way = VMobject(comp_matrix, vect_copy)
        short_way.arrange_submobjects(buff=0.1)
        short_way.next_to(equals, RIGHT)

        pairs = [
            (rot_matrix, "Rotation"),
            (shear_matrix, "Shear"),
            (comp_matrix, "Composition"),
        ]
        for matrix, word in pairs:
            brace = Brace(matrix)
            text = TextMobject(word).next_to(brace, DOWN)
            brace.highlight(matrix.get_color())
            text.highlight(matrix.get_color())
            matrix.add(brace, text)
        comp_matrix.split()[-1].submobject_gradient_highlight(TEAL, PINK)

        self.add(vect)
        groups = [
            [rot_matrix],
            [l_paren, r_paren, shear_matrix],
            [equals, comp_matrix, vect_copy],
        ]
        for group in groups:
            self.play(*map(Write, group))
            self.dither()
        self.play(*map(FadeOut, [l_paren, r_paren, vect, vect_copy]))
        comp_matrix.add(equals)
        matrices = VMobject(shear_matrix, rot_matrix, comp_matrix)
        self.play(
            ApplyMethod(matrices.arrange_submobjects,
                        buff=0.1,
                        aligned_edge=UP))
        self.dither()

        arrow = Arrow(rot_matrix.get_right(), shear_matrix.get_left())
        arrow.shift((rot_matrix.get_top()[1] + 0.2) * UP)
        words = TextMobject("Read right to left")
        words.submobjects.reverse()
        words.next_to(arrow, UP)
        functions = TexMobject("f(g(x))")
        functions.next_to(words, UP)

        self.play(ShowCreation(arrow))
        self.play(Write(words))
        self.dither()
        self.play(Write(functions))
        self.dither()
Ejemplo n.º 56
0
 def __init__(self, *args, **kwargs):
     VMobject.__init__(self, *args, **kwargs)
     shade_in_3d(self)
Ejemplo n.º 57
0
    def construct(self):
        v_sum = VMobject(
            Vector([1, 1], color=YELLOW),
            Vector([3, 1], color=BLUE).shift(RIGHT + UP),
            Vector([4, 2], color=GREEN),
        )
        scalar_multiplication = VMobject(TexMobject("2 \\cdot "),
                                         Vector([1, 1]), TexMobject("="),
                                         Vector([2, 2], color=WHITE))
        scalar_multiplication.arrange_submobjects(RIGHT)
        both = VMobject(v_sum, scalar_multiplication)
        both.arrange_submobjects(RIGHT, buff=1)
        both.shift(2 * DOWN)
        self.add(both)

        UpcomingSeriesOfVidoes.construct(self)
        last_video = self.mobjects[-1]
        self.play(ApplyMethod(last_video.highlight, YELLOW))
        self.dither()
        everything = VMobject(*self.mobjects)
        everything.remove(last_video)
        big_last_video = last_video.copy()
        big_last_video.center()
        big_last_video.scale_to_fit_height(2.5 * SPACE_HEIGHT)
        big_last_video.set_fill(opacity=0)
        self.play(ApplyMethod(everything.shift, 2 * SPACE_WIDTH * LEFT),
                  Transform(last_video, big_last_video),
                  run_time=2)
Ejemplo n.º 58
0
 def apply_function(self, function, maintain_smoothness=True):
     VMobject.apply_function(self,
                             function,
                             maintain_smoothness=maintain_smoothness)
Ejemplo n.º 59
0
 def __init__(self, angle, **kwargs):
     self.angle = angle
     VMobject.__init__(self, **kwargs)
Ejemplo n.º 60
0
class NumberLine(VMobject):
    CONFIG = {
        "color" : BLUE,
        "x_min" : -SPACE_WIDTH,
        "x_max" : SPACE_WIDTH,
        "unit_size" : 1,
        "tick_size" : 0.1,
        "tick_frequency" : 1,
        "leftmost_tick" : None, #Defaults to ceil(x_min)
        "numbers_with_elongated_ticks" : [0],
        "numbers_to_show" : None,
        "longer_tick_multiple" : 2,
        "number_at_center" : 0,
        "propogate_style_to_family" : True
    }
    def __init__(self, **kwargs):
        digest_config(self, kwargs)
        if self.leftmost_tick is None:
            self.leftmost_tick = np.ceil(self.x_min)
        VMobject.__init__(self, **kwargs)

    def generate_points(self):
        self.main_line = Line(self.x_min*RIGHT, self.x_max*RIGHT)
        self.tick_marks = VMobject()
        self.add(self.main_line, self.tick_marks)
        for x in self.get_tick_numbers():
            self.add_tick(x, self.tick_size)
        for x in self.numbers_with_elongated_ticks:
            self.add_tick(x, self.longer_tick_multiple*self.tick_size)
        self.stretch(self.unit_size, 0)
        self.shift(-self.number_to_point(self.number_at_center))

    def add_tick(self, x, size):
        self.tick_marks.add(Line(
            x*RIGHT+size*DOWN,
            x*RIGHT+size*UP,
        ))
        return self

    def get_tick_marks(self):
        return self.tick_marks

    def get_tick_numbers(self):
        epsilon = 0.001
        return np.arange(
            self.leftmost_tick, self.x_max+epsilon,
            self.tick_frequency
        )

    def number_to_point(self, number):
        alpha = float(number-self.x_min)/(self.x_max - self.x_min)
        return interpolate(
            self.main_line.get_start(),
            self.main_line.get_end(),
            alpha
        )

    def point_to_number(self, point):
        left_point, right_point = self.main_line.get_start_and_end()
        full_vect = right_point-left_point
        def distance_from_left(p):
            return np.dot(p-left_point, full_vect)/np.linalg.norm(full_vect)

        return interpolate(
            self.x_min, self.x_max, 
            distance_from_left(point)/distance_from_left(right_point)
        )

    def default_numbers_to_display(self):
        if self.numbers_to_show is not None:
            return self.numbers_to_show
        return np.arange(self.leftmost_tick, self.x_max, 1)

    def get_vertical_number_offset(self, direction = DOWN):
        return 4*direction*self.tick_size

    def get_number_mobjects(self, *numbers, **kwargs):
        #TODO, handle decimals
        if len(numbers) == 0:
            numbers = self.default_numbers_to_display()
        if "force_integers" in kwargs and kwargs["force_integers"]:
            numbers = map(int, numbers)
        result = VGroup()
        for number in numbers:
            mob = TexMobject(str(number))
            mob.scale_to_fit_height(3*self.tick_size)
            mob.shift(
                self.number_to_point(number),
                self.get_vertical_number_offset(**kwargs)
            )
            result.add(mob)
        return result

    def add_numbers(self, *numbers, **kwargs):
        self.numbers = self.get_number_mobjects(
            *numbers, **kwargs
        )
        self.add(*self.numbers)
        return self