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()
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)
def add_scaling(self, arrows, syms, arrays): s_arrows = VMobject( TexMobject("2"), Vector([1, 1]).highlight(YELLOW), TexMobject("="), Vector([2, 2]).highlight(WHITE) ) s_arrows.arrange_submobjects(RIGHT) s_arrows.scale(0.75) s_arrows.next_to(arrows, DOWN) s_arrays = VMobject( TexMobject("2"), matrix_to_mobject([3, -5]).highlight(YELLOW), TextMobject("="), matrix_to_mobject(["2(3)", "2(-5)"]) ) s_arrays.arrange_submobjects(RIGHT) s_arrays.scale(0.5) s_arrays.next_to(arrays, DOWN) s_syms = TexMobject(["2", "\\vec{\\textbf{v}}"]) s_syms.split()[-1].highlight(YELLOW) s_syms.next_to(syms, DOWN) self.play( Write(s_arrows), Write(s_arrays), Write(s_syms), run_time = 2 ) self.dither()
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()
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 )
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)
def handle_mathy(self, creatures): self.fade_all_but(creatures, 2) physy, compy, mathy = creatures v_color = YELLOW w_color = BLUE sum_color = GREEN v_arrow = Vector([1, 1]) w_arrow = Vector([2, 1]) w_arrow.shift(v_arrow.get_end()) sum_arrow = Vector(w_arrow.get_end()) arrows = VMobject(v_arrow, w_arrow, sum_arrow) arrows.scale(0.7) arrows.to_edge(LEFT, buff = 2) v_array = matrix_to_mobject([3, -5]) w_array = matrix_to_mobject([2, 1]) sum_array = matrix_to_mobject(["3+2", "-5+1"]) arrays = VMobject( v_array, TexMobject("+"), w_array, TexMobject("="), sum_array ) arrays.arrange_submobjects(RIGHT) arrays.scale(0.75) arrays.to_edge(RIGHT).shift(UP) v_sym = TexMobject("\\vec{\\textbf{v}}") w_sym = TexMobject("\\vec{\\textbf{w}}") syms = VMobject(v_sym, TexMobject("+"), w_sym) syms.arrange_submobjects(RIGHT) syms.center().shift(2*UP) statement = TextMobject("We'll ignore him \\\\ for now") statement.highlight(PINK) statement.scale_to_fit_width(arrays.get_width()) statement.next_to(arrays, DOWN, buff = 1.5) circle = Circle() circle.shift(syms.get_bottom()) VMobject(v_arrow, v_array, v_sym).highlight(v_color) VMobject(w_arrow, w_array, w_sym).highlight(w_color) VMobject(sum_arrow, sum_array).highlight(sum_color) self.play( Write(syms), Write(arrays), ShowCreation(arrows, submobject_mode = "one_at_a_time"), ApplyMethod(mathy.change_mode, "pondering"), run_time = 2 ) self.play(Blink(mathy)) self.add_scaling(arrows, syms, arrays) self.play(Write(statement)) self.play(ApplyMethod(mathy.change_mode, "sad")) self.dither() self.play( ShowCreation(circle), ApplyMethod(mathy.change_mode, "plain") ) self.dither()
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()
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)
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)
def construct(self): physy = Physicist() compy = ComputerScientist() physy.title = TextMobject("Physics student").to_corner(DOWN+LEFT) compy.title = TextMobject("CS student").to_corner(DOWN+RIGHT) for pi in physy, compy: pi.next_to(pi.title, UP) self.add(pi, pi.title) compy_speech = compy.get_bubble("speech") physy_speech = physy.get_bubble("speech") arrow = Vector([2, 1]) array = matrix_to_mobject([2, 1]) goes_to = TexMobject("\\Rightarrow") physy_statement = VMobject(arrow, goes_to, array) physy_statement.arrange_submobjects(RIGHT) compy_statement = physy_statement.copy() compy_statement.arrange_submobjects(LEFT) physy_speech.position_mobject_inside(physy_statement) compy_speech.position_mobject_inside(compy_statement) new_arrow = Vector([2, 1]) x_line = Line(ORIGIN, 2*RIGHT, color = X_COLOR) y_line = Line(2*RIGHT, 2*RIGHT+UP, color = Y_COLOR) x_mob = TexMobject("2").next_to(x_line, DOWN) y_mob = TexMobject("1").next_to(y_line, RIGHT) new_arrow.add(x_line, y_line, x_mob, y_mob) back_and_forth = VMobject( new_arrow, TexMobject("\\Leftrightarrow"), matrix_to_mobject([2, 1]) ) back_and_forth.arrange_submobjects(LEFT).center() self.dither() self.play( ApplyMethod(physy.change_mode, "speaking"), ShowCreation(physy_speech), Write(physy_statement), run_time = 1 ) self.play(Blink(compy)) self.play( ApplyMethod(physy.change_mode, "sassy"), ApplyMethod(compy.change_mode, "speaking"), FadeOut(physy_speech), ShowCreation(compy_speech), Transform(physy_statement, compy_statement, path_arc = np.pi) ) self.dither(2) self.play( ApplyMethod(physy.change_mode, "pondering"), ApplyMethod(compy.change_mode, "pondering"), Transform(compy_speech, VectorizedPoint(compy_speech.get_tip())), Transform(physy_statement, back_and_forth) ) self.dither()
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)
def construct(self): physy = Physicist() compy = ComputerScientist() physy.title = TextMobject("Physics student").to_corner(DOWN+LEFT) compy.title = TextMobject("CS student").to_corner(DOWN+RIGHT) for pi in physy, compy: pi.next_to(pi.title, UP) self.add(pi, pi.title) compy_speech = compy.get_bubble(SpeechBubble) physy_speech = physy.get_bubble(SpeechBubble) arrow = Vector([2, 1]) array = matrix_to_mobject([2, 1]) goes_to = TexMobject("\\Rightarrow") physy_statement = VMobject(arrow, goes_to, array) physy_statement.arrange_submobjects(RIGHT) compy_statement = physy_statement.copy() compy_statement.arrange_submobjects(LEFT) physy_speech.position_mobject_inside(physy_statement) compy_speech.position_mobject_inside(compy_statement) new_arrow = Vector([2, 1]) x_line = Line(ORIGIN, 2*RIGHT, color = X_COLOR) y_line = Line(2*RIGHT, 2*RIGHT+UP, color = Y_COLOR) x_mob = TexMobject("2").next_to(x_line, DOWN) y_mob = TexMobject("1").next_to(y_line, RIGHT) new_arrow.add(x_line, y_line, x_mob, y_mob) back_and_forth = VMobject( new_arrow, TexMobject("\\Leftrightarrow"), matrix_to_mobject([2, 1]) ) back_and_forth.arrange_submobjects(LEFT).center() self.wait() self.play( ApplyMethod(physy.change_mode, "speaking"), ShowCreation(physy_speech), Write(physy_statement), run_time = 1 ) self.play(Blink(compy)) self.play( ApplyMethod(physy.change_mode, "sassy"), ApplyMethod(compy.change_mode, "speaking"), FadeOut(physy_speech), ShowCreation(compy_speech), Transform(physy_statement, compy_statement, path_arc = np.pi) ) self.wait(2) self.play( ApplyMethod(physy.change_mode, "pondering"), ApplyMethod(compy.change_mode, "pondering"), Transform(compy_speech, VectorizedPoint(compy_speech.get_tip())), Transform(physy_statement, back_and_forth) ) self.wait()
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)
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)
def handle_mathy(self, creatures): self.fade_all_but(creatures, 2) physy, compy, mathy = creatures v_color = YELLOW w_color = BLUE sum_color = GREEN v_arrow = Vector([1, 1]) w_arrow = Vector([2, 1]) w_arrow.shift(v_arrow.get_end()) sum_arrow = Vector(w_arrow.get_end()) arrows = VMobject(v_arrow, w_arrow, sum_arrow) arrows.scale(0.7) arrows.to_edge(LEFT, buff=2) v_array = matrix_to_mobject([3, -5]) w_array = matrix_to_mobject([2, 1]) sum_array = matrix_to_mobject(["3+2", "-5+1"]) arrays = VMobject(v_array, TexMobject("+"), w_array, TexMobject("="), sum_array) arrays.arrange_submobjects(RIGHT) arrays.scale(0.75) arrays.to_edge(RIGHT).shift(UP) v_sym = TexMobject("\\vec{\\textbf{v}}") w_sym = TexMobject("\\vec{\\textbf{w}}") syms = VMobject(v_sym, TexMobject("+"), w_sym) syms.arrange_submobjects(RIGHT) syms.center().shift(2 * UP) statement = TextMobject("We'll ignore him \\\\ for now") statement.highlight(PINK) statement.scale_to_fit_width(arrays.get_width()) statement.next_to(arrays, DOWN, buff=1.5) circle = Circle() circle.shift(syms.get_bottom()) VMobject(v_arrow, v_array, v_sym).highlight(v_color) VMobject(w_arrow, w_array, w_sym).highlight(w_color) VMobject(sum_arrow, sum_array).highlight(sum_color) self.play(Write(syms), Write(arrays), ShowCreation(arrows, submobject_mode="one_at_a_time"), ApplyMethod(mathy.change_mode, "pondering"), run_time=2) self.play(Blink(mathy)) self.add_scaling(arrows, syms, arrays) self.play(Write(statement)) self.play(ApplyMethod(mathy.change_mode, "sad")) self.dither() self.play(ShowCreation(circle), ApplyMethod(mathy.change_mode, "plain")) self.dither()
def construct(self): v = TexMobject(self.v_str) v.highlight(YELLOW) eq = TexMobject("=") coords = Matrix(["x", "y", "z"]) eq2 = eq.copy() if self.post_transform: L, l_paren, r_paren = map(TexMobject, "L()") parens = VMobject(l_paren, r_paren) parens.scale(2) parens.stretch_to_fit_height( coords.get_height() ) VMobject(L, l_paren, coords, r_paren).arrange_submobjects(buff = 0.1) coords.submobjects = [L, l_paren] + coords.submobjects + [r_paren] lin_comb = VMobject(*map(TexMobject, [ "x", self.i_str, "+", "y", self.j_str, "+", "z", self.k_str, ])) lin_comb.arrange_submobjects( RIGHT, buff = 0.1, aligned_edge = ORIGIN if self.post_transform else DOWN ) lin_comb_parts = np.array(lin_comb.split()) new_x, new_y, new_z = lin_comb_parts[[0, 3, 6]] i, j, k = lin_comb_parts[[1, 4, 7]] plusses = lin_comb_parts[[2, 5]] i.highlight(X_COLOR) j.highlight(Y_COLOR) k.highlight(Z_COLOR) everything = VMobject(v, eq, coords, eq2, lin_comb) everything.arrange_submobjects(buff = 0.2) everything.scale_to_fit_width(2*SPACE_WIDTH - 1) everything.to_edge(DOWN) if not self.post_transform: lin_comb.shift(0.35*UP) self.play(*map(Write, [v, eq, coords])) self.dither() self.play( Transform( coords.get_entries().copy(), VMobject(new_x, new_y, new_z), path_arc = -np.pi, submobject_mode = "lagged_start" ), Write(VMobject(*[eq2, i, j, k] + list(plusses))), run_time = 3 ) self.dither()
def construct(self): title = TextMobject("Essence of Linear Algebra") title.highlight(BLUE) title.to_corner(UP+LEFT) h_line = Line(SPACE_WIDTH*LEFT, SPACE_WIDTH*RIGHT) h_line.next_to(title, DOWN) h_line.to_edge(LEFT, buff = 0) chapters = VMobject(*map(TextMobject, [ "Chapter 1: Vectors, what even are they?", "Chapter 2: Linear combinations, span and bases", "Chapter 3: Matrices as linear transformations", "Chapter 4: Matrix multiplication as composition", "Chapter 5: The determinant", "Chapter 6: Inverse matrices, column space and null space", "Chapter 7: Dot products and cross products", "Chapter 8: Change of basis", "Chapter 9: Eigenvectors and eigenvalues", "Chapter 10: Abstract vector spaces", ])) chapters.arrange_submobjects(DOWN) chapters.scale(0.7) chapters.next_to(h_line, DOWN) self.play( Write(title), ShowCreation(h_line) ) for chapter in chapters.split(): chapter.to_edge(LEFT, buff = 1) self.play(FadeIn(chapter)) self.dither(2) entry3 = chapters.split()[2] added_words = TextMobject("(Personally, I'm most excited \\\\ to do this one)") added_words.scale(0.5) added_words.highlight(YELLOW) added_words.next_to(h_line, DOWN) added_words.to_edge(RIGHT) arrow = Arrow(added_words.get_bottom(), entry3) self.play( ApplyMethod(entry3.highlight, YELLOW), ShowCreation(arrow, submobject_mode = "one_at_a_time"), Write(added_words), run_time = 1 ) self.dither() removeable = VMobject(added_words, arrow, h_line, title) self.play(FadeOut(removeable)) self.remove(removeable) self.series_of_videos(chapters)
def construct(self): icon = SVGMobject("video_icon") icon.center() icon.scale_to_fit_width(2 * SPACE_WIDTH / 12.) icon.set_stroke(color=WHITE, width=0) icon.set_fill(WHITE, opacity=1) icons = VMobject(*[icon.copy() for x in range(10)]) icons.submobject_gradient_highlight(BLUE_A, BLUE_D) icons.arrange_submobjects(RIGHT) icons.to_edge(LEFT) self.play(FadeIn(icons, submobject_mode="lagged_start"), run_time=3) self.wait()
def construct(self): title = TextMobject("Questions to ponder") title.highlight(YELLOW).to_edge(UP) self.add(title) questions = VMobject(*map(TextMobject, [ "1. Can you visualize these transformations?", "2. Can you represent them with matrices?", "3. How many rows and columns?", "4. When can you multiply these matrices?", ])) questions.arrange_submobjects(DOWN, buff = 1, aligned_edge = LEFT) questions.to_edge(LEFT) for question in questions.split(): self.play(Write(question, run_time = 1)) self.dither()
def construct(self): title = TextMobject("Questions to ponder") title.highlight(YELLOW).to_edge(UP) self.add(title) questions = VMobject(*map(TextMobject, [ "1. Can you visualize these transformations?", "2. Can you represent them with matrices?", "3. How many rows and columns?", "4. When can you multiply these matrices?", ])) questions.arrange_submobjects(DOWN, buff=1, aligned_edge=LEFT) questions.to_edge(LEFT) for question in questions.split(): self.play(Write(question, run_time=1)) self.wait()
def construct(self): matrix = Matrix(np.arange(9).reshape((3, 3))) vect = Matrix(list("xyz")) vect.scale_to_fit_height(matrix.get_height()) col1, col2, col3 = columns = [ Matrix(col) for col in matrix.copy().get_mob_matrix().transpose() ] coords = x, y, z = [m.copy() for m in vect.get_entries().split()] eq, plus1, plus2 = map(TexMobject, list("=++")) everything = VMobject(matrix, vect, eq, x, col1, plus1, y, col2, plus2, z, col3) everything.arrange_submobjects(buff=0.1) everything.scale_to_fit_width(2 * SPACE_WIDTH - 1) result = VMobject(x, col1, plus1, y, col2, plus2, z, col3) trips = [ (matrix, DOWN, "Transformation"), (vect, UP, "Input vector"), (result, DOWN, "Output vector"), ] braces = [] for mob, direction, text in trips: brace = Brace(mob, direction) words = TextMobject(text) words.next_to(brace, direction) brace.add(words) braces.append(brace) matrix_brace, vect_brace, result_brace = braces self.play(*map(Write, [matrix, vect]), run_time=2) self.play(Write(matrix_brace, run_time=1)) self.play(Write(vect_brace, run_time=1)) sexts = zip(matrix.get_mob_matrix().transpose(), columns, vect.get_entries().split(), coords, [eq, plus1, plus2], [X_COLOR, Y_COLOR, Z_COLOR]) for o_col, col, start_coord, coord, sym, color in sexts: o_col = VMobject(*o_col) self.play(start_coord.highlight, YELLOW, o_col.highlight, color) coord.highlight(YELLOW) col.highlight(color) self.play( Write(col.get_brackets()), Transform(o_col.copy(), col.get_entries(), path_arc=-np.pi), Transform(start_coord.copy(), coord, path_arc=-np.pi), Write(sym)) self.wait() self.play(Write(result_brace, run_time=1)) self.wait()
def construct(self): title = TextMobject("Essence of Linear Algebra") title.highlight(BLUE) title.to_corner(UP + LEFT) h_line = Line(SPACE_WIDTH * LEFT, SPACE_WIDTH * RIGHT) h_line.next_to(title, DOWN) h_line.to_edge(LEFT, buff=0) chapters = VMobject(*map(TextMobject, [ "Chapter 1: Vectors, what even are they?", "Chapter 2: Linear combinations, span and bases", "Chapter 3: Matrices as linear transformations", "Chapter 4: Matrix multiplication as composition", "Chapter 5: The determinant", "Chapter 6: Inverse matrices, column space and null space", "Chapter 7: Dot products and cross products", "Chapter 8: Change of basis", "Chapter 9: Eigenvectors and eigenvalues", "Chapter 10: Abstract vector spaces", ])) chapters.arrange_submobjects(DOWN) chapters.scale(0.7) chapters.next_to(h_line, DOWN) self.play(Write(title), ShowCreation(h_line)) for chapter in chapters.split(): chapter.to_edge(LEFT, buff=1) self.play(FadeIn(chapter)) self.wait(2) entry3 = chapters.split()[2] added_words = TextMobject( "(Personally, I'm most excited \\\\ to do this one)") added_words.scale(0.5) added_words.highlight(YELLOW) added_words.next_to(h_line, DOWN) added_words.to_edge(RIGHT) arrow = Arrow(added_words.get_bottom(), entry3) self.play(ApplyMethod(entry3.highlight, YELLOW), ShowCreation(arrow, submobject_mode="one_at_a_time"), Write(added_words), run_time=1) self.wait() removeable = VMobject(added_words, arrow, h_line, title) self.play(FadeOut(removeable)) self.remove(removeable) self.series_of_videos(chapters)
def construct(self): icon = SVGMobject("video_icon") icon.center() icon.scale_to_fit_width(2*SPACE_WIDTH/12.) icon.set_stroke(color = WHITE, width = 0) icon.set_fill(WHITE, opacity = 1) icons = VMobject(*[icon.copy() for x in range(10)]) icons.submobject_gradient_highlight(BLUE_A, BLUE_D) icons.arrange_submobjects(RIGHT) icons.to_edge(LEFT) self.play( FadeIn(icons, submobject_mode = "lagged_start"), run_time = 3 ) self.dither()
def construct(self): self.setup() matrix = Matrix(np.array(self.transposed_matrix).transpose()) matrix.highlight_columns(X_COLOR, Y_COLOR) matrix.next_to(ORIGIN, LEFT).to_edge(UP) matrix_background = BackgroundRectangle(matrix) self.play(ShowCreation(matrix_background), Write(matrix)) if self.show_square: self.add_unit_square(animate = True) self.add_foreground_mobject(matrix_background, matrix) self.dither() self.apply_transposed_matrix([self.transposed_matrix[0], [0, 1]]) self.apply_transposed_matrix([[1, 0], self.transposed_matrix[1]]) self.dither() if self.show_square: bottom_brace = Brace(self.i_hat, DOWN) right_brace = Brace(self.square, RIGHT) width = TexMobject(str(self.transposed_matrix[0][0])) height = TexMobject(str(self.transposed_matrix[1][1])) width.next_to(bottom_brace, DOWN) height.next_to(right_brace, RIGHT) for mob in bottom_brace, width, right_brace, height: mob.add_background_rectangle() self.play(Write(mob, run_time = 0.5)) self.dither() width_target, height_target = width.copy(), height.copy() det = np.linalg.det(self.transposed_matrix) times, eq_det = map(TexMobject, ["\\times", "=%d"%det]) words = TextMobject("New area $=$") equation = VMobject( words, width_target, times, height_target, eq_det ) equation.arrange_submobjects(RIGHT, buff = 0.2) equation.next_to(self.square, UP, aligned_edge = LEFT) equation.shift(0.5*RIGHT) background_rect = BackgroundRectangle(equation) self.play( ShowCreation(background_rect), Transform(width.copy(), width_target), Transform(height.copy(), height_target), *map(Write, [words, times, eq_det]) ) self.dither()
def construct(self): i_to = TexMobject("\\hat{\\imath} \\to").highlight(X_COLOR) j_to = TexMobject("\\hat{\\jmath} \\to").highlight(Y_COLOR) k_to = TexMobject("\\hat{k} \\to").highlight(Z_COLOR) i_array = Matrix(self.col1) j_array = Matrix(self.col2) k_array = Matrix(self.col3) everything = VMobject( i_to, i_array, TexMobject("=").highlight(BLACK), j_to, j_array, TexMobject("=").highlight(BLACK), k_to, k_array, TexMobject("=").highlight(BLACK), ) everything.arrange_submobjects(RIGHT, buff=0.1) everything.scale_to_fit_width(2 * SPACE_WIDTH - 1) everything.to_edge(DOWN) i_array.highlight(X_COLOR) j_array.highlight(Y_COLOR) k_array.highlight(Z_COLOR) arrays = [i_array, j_array, k_array] matrix = Matrix( reduce(lambda a1, a2: np.append(a1, a2, axis=1), [m.copy().get_mob_matrix() for m in arrays])) matrix.to_edge(DOWN) start_entries = reduce(op.add, map(lambda a: a.get_entries().split(), arrays)) target_entries = matrix.get_mob_matrix().transpose().flatten() start_l_bracket = i_array.get_brackets().split()[0] start_r_bracket = k_array.get_brackets().split()[1] start_brackets = VMobject(start_l_bracket, start_r_bracket) target_bracketes = matrix.get_brackets() for mob in everything.split(): self.play(Write(mob, run_time=1)) self.wait() self.play( FadeOut(everything), Transform(VMobject(*start_entries), VMobject(*target_entries)), Transform(start_brackets, target_bracketes)) self.wait()
def construct(self): i_to = TexMobject("\\hat{\\imath} \\to").highlight(X_COLOR) j_to = TexMobject("\\hat{\\jmath} \\to").highlight(Y_COLOR) k_to = TexMobject("\\hat{k} \\to").highlight(Z_COLOR) i_array = Matrix(self.col1) j_array = Matrix(self.col2) k_array = Matrix(self.col3) everything = VMobject( i_to, i_array, TexMobject("=").highlight(BLACK), j_to, j_array, TexMobject("=").highlight(BLACK), k_to, k_array, TexMobject("=").highlight(BLACK), ) everything.arrange_submobjects(RIGHT, buff = 0.1) everything.scale_to_fit_width(2*SPACE_WIDTH-1) everything.to_edge(DOWN) i_array.highlight(X_COLOR) j_array.highlight(Y_COLOR) k_array.highlight(Z_COLOR) arrays = [i_array, j_array, k_array] matrix = Matrix(reduce( lambda a1, a2 : np.append(a1, a2, axis = 1), [m.copy().get_mob_matrix() for m in arrays] )) matrix.to_edge(DOWN) start_entries = reduce(op.add, map( lambda a : a.get_entries().split(), arrays )) target_entries = matrix.get_mob_matrix().transpose().flatten() start_l_bracket = i_array.get_brackets().split()[0] start_r_bracket = k_array.get_brackets().split()[1] start_brackets = VMobject(start_l_bracket, start_r_bracket) target_bracketes = matrix.get_brackets() for mob in everything.split(): self.play(Write(mob, run_time = 1)) self.dither() self.play( FadeOut(everything), Transform(VMobject(*start_entries), VMobject(*target_entries)), Transform(start_brackets, target_bracketes) ) self.dither()
def construct(self): morty = Mortimer() morty.to_corner(DOWN+RIGHT) morty.look(DOWN+LEFT) new_morty = morty.copy().change_mode("speaking") new_morty.look(DOWN+LEFT) randys = VMobject(*[ Randolph(color = color).scale(0.8) for color in BLUE_D, BLUE_C, BLUE_E ]) randys.arrange_submobjects(RIGHT) randys.to_corner(DOWN+LEFT) randy = randys.split()[1] speech_bubble = morty.get_bubble(SpeechBubble) words = TextMobject("Think of some vector...") speech_bubble.position_mobject_inside(words) thought_bubble = randy.get_bubble() arrow = Vector([2, 1]).scale(0.7) or_word = TextMobject("or") array = Matrix([2, 1]).scale(0.5) q_mark = TextMobject("?") thought = VMobject(arrow, or_word, array, q_mark) thought.arrange_submobjects(RIGHT, buff = 0.2) thought_bubble.position_mobject_inside(thought) thought_bubble.set_fill(BLACK, opacity = 1) self.add(morty, randys) self.play( ShowCreation(speech_bubble), Transform(morty, new_morty), Write(words) ) self.wait(2) self.play( FadeOut(speech_bubble), FadeOut(words), ApplyMethod(randy.change_mode, "pondering"), ShowCreation(thought_bubble), Write(thought) ) self.wait(2)
def construct(self): morty = Mortimer() morty.to_corner(DOWN+RIGHT) morty.look(DOWN+LEFT) new_morty = morty.copy().change_mode("speaking") new_morty.look(DOWN+LEFT) randys = VMobject(*[ Randolph(color = color).scale(0.8) for color in BLUE_D, BLUE_C, BLUE_E ]) randys.arrange_submobjects(RIGHT) randys.to_corner(DOWN+LEFT) randy = randys.split()[1] speech_bubble = morty.get_bubble("speech") words = TextMobject("Think of some vector...") speech_bubble.position_mobject_inside(words) thought_bubble = randy.get_bubble() arrow = Vector([2, 1]).scale(0.7) or_word = TextMobject("or") array = Matrix([2, 1]).scale(0.5) q_mark = TextMobject("?") thought = VMobject(arrow, or_word, array, q_mark) thought.arrange_submobjects(RIGHT, buff = 0.2) thought_bubble.position_mobject_inside(thought) thought_bubble.set_fill(BLACK, opacity = 1) self.add(morty, randys) self.play( ShowCreation(speech_bubble), Transform(morty, new_morty), Write(words) ) self.dither(2) self.play( FadeOut(speech_bubble), FadeOut(words), ApplyMethod(randy.change_mode, "pondering"), ShowCreation(thought_bubble), Write(thought) ) self.dither(2)
def construct(self): icons = [VideoIcon() for x in range(10)] colors = Color(BLUE_A).range_to(BLUE_D, len(icons)) for icon, color in zip(icons, colors): icon.set_fill(color, opacity=1) icons = VMobject(*icons) icons.arrange_submobjects(RIGHT) icons.to_edge(LEFT) icons.shift(UP) icons = icons.split() def rate_func_creator(offset): return lambda a: min(max(2 * (a - offset), 0), 1) self.play(*[ FadeIn(icon, run_time=5, rate_func=rate_func_creator(offset)) for icon, offset in zip(icons, np.linspace(0, 0.5, len(icons))) ]) self.wait()
def construct(self): self.setup() matrix = Matrix(np.array(self.transposed_matrix).transpose()) matrix.highlight_columns(X_COLOR, Y_COLOR) matrix.next_to(ORIGIN, LEFT).to_edge(UP) matrix_background = BackgroundRectangle(matrix) self.play(ShowCreation(matrix_background), Write(matrix)) if self.show_square: self.add_unit_square(animate=True) self.add_foreground_mobject(matrix_background, matrix) self.wait() self.apply_transposed_matrix([self.transposed_matrix[0], [0, 1]]) self.apply_transposed_matrix([[1, 0], self.transposed_matrix[1]]) self.wait() if self.show_square: bottom_brace = Brace(self.i_hat, DOWN) right_brace = Brace(self.square, RIGHT) width = TexMobject(str(self.transposed_matrix[0][0])) height = TexMobject(str(self.transposed_matrix[1][1])) width.next_to(bottom_brace, DOWN) height.next_to(right_brace, RIGHT) for mob in bottom_brace, width, right_brace, height: mob.add_background_rectangle() self.play(Write(mob, run_time=0.5)) self.wait() width_target, height_target = width.copy(), height.copy() det = np.linalg.det(self.transposed_matrix) times, eq_det = map(TexMobject, ["\\times", "=%d" % det]) words = TextMobject("New area $=$") equation = VMobject(words, width_target, times, height_target, eq_det) equation.arrange_submobjects(RIGHT, buff=0.2) equation.next_to(self.square, UP, aligned_edge=LEFT) equation.shift(0.5 * RIGHT) background_rect = BackgroundRectangle(equation) self.play(ShowCreation(background_rect), Transform(width.copy(), width_target), Transform(height.copy(), height_target), *map(Write, [words, times, eq_det])) self.wait()
def construct(self): morty = Mortimer(mode = "speaking") morty.to_corner(DOWN + RIGHT) bubble = morty.get_bubble(SpeechBubble) bubble.write("I'm assuming you \\\\ know linear algebra\\dots") words = bubble.content bubble.clear() randys = VMobject(*[ Randolph(color = c) for c in BLUE_D, BLUE_C, BLUE_E ]) randys.arrange_submobjects(RIGHT) randys.scale(0.8) randys.to_corner(DOWN+LEFT) self.add(randys, morty) self.play(FadeIn(bubble), Write(words), run_time = 3) for randy in np.array(randys.split())[[2,0,1]]: self.play(Blink(randy)) self.dither()
def scale_basis_vectors(self, new_array): i_hat, j_hat = self.get_basis_vectors() self.add_vector(i_hat) i_hat_label = self.label_vector( i_hat, "\\hat{\\imath}", color = X_COLOR, label_scale_factor = 1 ) self.add_vector(j_hat) j_hat_label = self.label_vector( j_hat, "\\hat{\\jmath}", color = Y_COLOR, label_scale_factor = 1 ) self.dither() x, y = new_array.get_mob_matrix().flatten() for coord, v, label, factor, shift_right in [ (x, i_hat, i_hat_label, self.vector_coords[0], False), (y, j_hat, j_hat_label, self.vector_coords[1], True) ]: faded_v = v.copy().fade(0.7) scaled_v = Vector(factor*v.get_end(), color = v.get_color()) scaled_label = VMobject(coord.copy(), label.copy()) scaled_label.arrange_submobjects(RIGHT, buff = 0.1) scaled_label.move_to(label, DOWN+RIGHT) scaled_label.shift((scaled_v.get_end()-v.get_end())/2) coord_copy = coord.copy() self.play( Transform(v.copy(), faded_v), Transform(v, scaled_v), Transform(VMobject(coord_copy, label), scaled_label), ) self.dither() if shift_right: group = VMobject(v, coord_copy, label) self.play(ApplyMethod( group.shift, self.vector_coords[0]*RIGHT )) self.dither()
def show_matrix(self): for vect, char in zip([self.i_hat, self.j_hat], ["i", "j"]): vect.words = TextMobject("$\\hat\\%smath$ lands on" % char, str(int(vect.get_end()[0]))) direction = UP if vect is self.i_hat else DOWN vect.words.next_to(vect.get_end(), direction, buff=LARGE_BUFF) vect.words.highlight(vect.get_color()) matrix = Matrix([[1, 2]]) matrix_words = TextMobject("Transformation matrix: ") matrix_group = VMobject(matrix_words, matrix) matrix_group.arrange_submobjects(buff=MED_SMALL_BUFF) matrix_group.to_edge(UP) entries = matrix.get_entries() self.play(Write(matrix_words), Write(matrix.get_brackets())) for i, vect in enumerate([self.i_hat, self.j_hat]): self.play(vect.rotate, np.pi / 12, rate_func=wiggle) self.play(Write(vect.words)) self.dither() self.play(vect.words[1].copy().move_to, entries[i]) self.dither()
def construct(self): self.setup() self.plane.fade(0.3) self.add_unit_square(color = YELLOW_E, opacity = 0.5) self.add_title( ["The", "``determinant''", "of a transformation"], scale_factor = 1 ) self.title.split()[1].split()[1].highlight(YELLOW) matrix_background, matrix, det_text = self.get_matrix() self.add_foreground_mobject(matrix_background, matrix) A = TexMobject("A") area_label = VMobject(A.copy(), A.copy(), A) area_label.move_to(self.square) det = np.linalg.det(self.t_matrix) if np.round(det) == det: det = int(det) area_label_target = VMobject( TexMobject(str(det)), TexMobject("\\cdot"), A.copy() ) if det < 1 and det > 0: area_label_target.scale(det) area_label_target.arrange_submobjects(RIGHT, buff = 0.1) self.add_moving_mobject(area_label, area_label_target) self.dither() self.apply_transposed_matrix(self.t_matrix) self.dither() det_mob_copy = area_label.split()[0].copy() new_det_mob = det_mob_copy.copy().scale_to_fit_height( det_text.split()[0].get_height() ) new_det_mob.next_to(det_text, RIGHT, buff = 0.2) new_det_mob.add_background_rectangle() det_mob_copy.add_background_rectangle(opacity = 0) self.play(Write(det_text)) self.play(Transform(det_mob_copy, new_det_mob)) self.dither()
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)
def cs_conception(self, creatures): self.fade_all_but(creatures, 1) physy, compy, mathy = creatures title = TextMobject("Vectors $\\Leftrightarrow$ lists of numbers") title.to_edge(UP) vectors = VMobject(*map(matrix_to_mobject, [ [2, 1], [5, 0, 0, -3], [2.3, -7.1, 0.1], ])) vectors.arrange_submobjects(RIGHT, buff=1) vectors.to_edge(LEFT) self.play(ApplyMethod(compy.change_mode, "sassy"), Write(title, run_time=1)) self.play(Write(vectors)) self.dither() self.play(ApplyMethod(compy.change_mode, "pondering")) self.house_example(vectors, title) self.restore_creatures(creatures)
def construct(self): icons = [VideoIcon() for x in range(10)] colors = Color(BLUE_A).range_to(BLUE_D, len(icons)) for icon, color in zip(icons, colors): icon.set_fill(color, opacity = 1) icons = VMobject(*icons) icons.arrange_submobjects(RIGHT) icons.to_edge(LEFT) icons.shift(UP) icons = icons.split() def rate_func_creator(offset): return lambda a : min(max(2*(a-offset), 0), 1) self.play(*[ FadeIn( icon, run_time = 5, rate_func = rate_func_creator(offset) ) for icon, offset in zip(icons, np.linspace(0, 0.5, len(icons))) ]) self.dither()
def add_scaling(self, arrows, syms, arrays): s_arrows = VMobject(TexMobject("2"), Vector([1, 1]).highlight(YELLOW), TexMobject("="), Vector([2, 2]).highlight(WHITE)) s_arrows.arrange_submobjects(RIGHT) s_arrows.scale(0.75) s_arrows.next_to(arrows, DOWN) s_arrays = VMobject(TexMobject("2"), matrix_to_mobject([3, -5]).highlight(YELLOW), TextMobject("="), matrix_to_mobject(["2(3)", "2(-5)"])) s_arrays.arrange_submobjects(RIGHT) s_arrays.scale(0.75) s_arrays.next_to(arrays, DOWN) s_syms = TexMobject(["2", "\\vec{\\textbf{v}}"]) s_syms.split()[-1].highlight(YELLOW) s_syms.next_to(syms, DOWN) self.play(Write(s_arrows), Write(s_arrays), Write(s_syms), run_time=2) self.dither()
def scale_basis_vectors(self, new_array): i_hat, j_hat = self.get_basis_vectors() self.add_vector(i_hat) i_hat_label = self.label_vector(i_hat, "\\hat{\\imath}", color=X_COLOR, label_scale_factor=1) self.add_vector(j_hat) j_hat_label = self.label_vector(j_hat, "\\hat{\\jmath}", color=Y_COLOR, label_scale_factor=1) self.wait() x, y = new_array.get_mob_matrix().flatten() for coord, v, label, factor, shift_right in [ (x, i_hat, i_hat_label, self.vector_coords[0], False), (y, j_hat, j_hat_label, self.vector_coords[1], True) ]: faded_v = v.copy().fade(0.7) scaled_v = Vector(factor * v.get_end(), color=v.get_color()) scaled_label = VMobject(coord.copy(), label.copy()) scaled_label.arrange_submobjects(RIGHT, buff=0.1) scaled_label.move_to(label, DOWN + RIGHT) scaled_label.shift((scaled_v.get_end() - v.get_end()) / 2) coord_copy = coord.copy() self.play( Transform(v.copy(), faded_v), Transform(v, scaled_v), Transform(VMobject(coord_copy, label), scaled_label), ) self.wait() if shift_right: group = VMobject(v, coord_copy, label) self.play( ApplyMethod(group.shift, self.vector_coords[0] * RIGHT)) self.wait()
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)
def show_matrix(self): for vect, char in zip([self.i_hat, self.j_hat], ["i", "j"]): vect.words = TextMobject( "$\\hat\\%smath$ lands on"%char, str(int(vect.get_end()[0])) ) direction = UP if vect is self.i_hat else DOWN vect.words.next_to(vect.get_end(), direction, buff = LARGE_BUFF) vect.words.highlight(vect.get_color()) matrix = Matrix([[1, 2]]) matrix_words = TextMobject("Transformation matrix: ") matrix_group = VMobject(matrix_words, matrix) matrix_group.arrange_submobjects(buff = MED_SMALL_BUFF) matrix_group.to_edge(UP) entries = matrix.get_entries() self.play(Write(matrix_words), Write(matrix.get_brackets())) for i, vect in enumerate([self.i_hat, self.j_hat]): self.play(vect.rotate, np.pi/12, rate_func = wiggle) self.play(Write(vect.words)) self.dither() self.play(vect.words[1].copy().move_to, entries[i]) self.dither()
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()
def series_of_videos(self, chapters): icon = SVGMobject("video_icon") icon.center() icon.scale_to_fit_width(2*SPACE_WIDTH/12.) icon.set_stroke(color = WHITE, width = 0) icons = [icon.copy() for chapter in chapters.split()] colors = Color(BLUE_A).range_to(BLUE_D, len(icons)) for icon, color in zip(icons, colors): icon.set_fill(color, opacity = 1) icons = VMobject(*icons) icons.arrange_submobjects(RIGHT) icons.to_edge(LEFT) icons.shift(UP) randy = Randolph() randy.to_corner() bubble = randy.get_bubble() new_icons = icons.copy().scale(0.2) bubble.position_mobject_inside(new_icons) self.play(Transform( chapters, icons, path_arc = np.pi/2, )) self.clear() self.add(icons) self.play(FadeIn(randy)) self.play(Blink(randy)) self.dither() self.play( ShowCreation(bubble), Transform(icons, new_icons) ) self.remove(icons) bubble.make_green_screen() self.dither()
def construct(self): self.setup() self.plane.fade(0.3) self.add_unit_square(color=YELLOW_E, opacity=0.5) self.add_title(["The", "``determinant''", "of a transformation"], scale_factor=1) self.title.split()[1].split()[1].highlight(YELLOW) matrix_background, matrix, det_text = self.get_matrix() self.add_foreground_mobject(matrix_background, matrix) A = TexMobject("A") area_label = VMobject(A.copy(), A.copy(), A) area_label.move_to(self.square) det = np.linalg.det(self.t_matrix) if np.round(det) == det: det = int(det) area_label_target = VMobject(TexMobject(str(det)), TexMobject("\\cdot"), A.copy()) if det < 1 and det > 0: area_label_target.scale(det) area_label_target.arrange_submobjects(RIGHT, buff=0.1) self.add_moving_mobject(area_label, area_label_target) self.wait() self.apply_transposed_matrix(self.t_matrix) self.wait() det_mob_copy = area_label.split()[0].copy() new_det_mob = det_mob_copy.copy().scale_to_fit_height( det_text.split()[0].get_height()) new_det_mob.next_to(det_text, RIGHT, buff=0.2) new_det_mob.add_background_rectangle() det_mob_copy.add_background_rectangle(opacity=0) self.play(Write(det_text)) self.play(Transform(det_mob_copy, new_det_mob)) self.wait()
def cs_conception(self, creatures): self.fade_all_but(creatures, 1) physy, compy, mathy = creatures title = TextMobject("Vectors $\\Leftrightarrow$ lists of numbers") title.to_edge(UP) vectors = VMobject(*map(matrix_to_mobject, [ [2, 1], [5, 0, 0, -3], [2.3, -7.1, 0.1], ])) vectors.arrange_submobjects(RIGHT, buff = 1) vectors.to_edge(LEFT) self.play( ApplyMethod(compy.change_mode, "sassy"), Write(title, run_time = 1) ) self.play(Write(vectors)) self.dither() self.play(ApplyMethod(compy.change_mode, "pondering")) self.house_example(vectors, title) self.restore_creatures(creatures)
def construct(self): matrix = Matrix(np.arange(9).reshape((3, 3))) vect = Matrix(list("xyz")) vect.scale_to_fit_height(matrix.get_height()) col1, col2, col3 = columns = [ Matrix(col) for col in matrix.copy().get_mob_matrix().transpose() ] coords = x, y, z = [m.copy() for m in vect.get_entries().split()] eq, plus1, plus2 = map(TexMobject, list("=++")) everything = VMobject( matrix, vect, eq, x, col1, plus1, y, col2, plus2, z, col3 ) everything.arrange_submobjects(buff = 0.1) everything.scale_to_fit_width(2*SPACE_WIDTH-1) result = VMobject(x, col1, plus1, y, col2, plus2, z, col3) trips = [ (matrix, DOWN, "Transformation"), (vect, UP, "Input vector"), (result, DOWN, "Output vector"), ] braces = [] for mob, direction, text in trips: brace = Brace(mob, direction) words = TextMobject(text) words.next_to(brace, direction) brace.add(words) braces.append(brace) matrix_brace, vect_brace, result_brace = braces self.play(*map(Write, [matrix, vect]), run_time = 2) self.play(Write(matrix_brace, run_time = 1)) self.play(Write(vect_brace, run_time = 1)) sexts = zip( matrix.get_mob_matrix().transpose(), columns, vect.get_entries().split(), coords, [eq, plus1, plus2], [X_COLOR, Y_COLOR, Z_COLOR] ) for o_col, col, start_coord, coord, sym, color in sexts: o_col = VMobject(*o_col) self.play( start_coord.highlight, YELLOW, o_col.highlight, color ) coord.highlight(YELLOW) col.highlight(color) self.play( Write(col.get_brackets()), Transform( o_col.copy(), col.get_entries(), path_arc = -np.pi ), Transform( start_coord.copy(), coord, path_arc = -np.pi ), Write(sym) ) self.dither() self.play(Write(result_brace, run_time = 1)) self.dither()
class TeacherStudentsScene(Scene): def setup(self): self.teacher = Mortimer() self.teacher.to_corner(DOWN + RIGHT) self.teacher.look(DOWN+LEFT) self.students = VMobject(*[ Randolph(color = c) for c in BLUE_D, BLUE_C, BLUE_E ]) self.students.arrange_submobjects(RIGHT) self.students.scale(0.8) self.students.to_corner(DOWN+LEFT) self.students = self.students.split() for pi_creature in self.get_everyone(): pi_creature.bubble = None self.add(*self.get_everyone()) def get_teacher(self): return self.teacher def get_students(self): return self.students def get_everyone(self): return [self.get_teacher()] + self.get_students() def get_bubble_intro_animation(self, content, bubble_type, pi_creature, **bubble_kwargs): bubble = pi_creature.get_bubble(bubble_type, **bubble_kwargs) bubble.add_content(content) if pi_creature.bubble: content_intro_anims = [ Transform(pi_creature.bubble, bubble), Transform(pi_creature.bubble.content, bubble.content) ] else: content_intro_anims = [ FadeIn(bubble), Write(content), ] pi_creature.bubble = bubble return content_intro_anims def introduce_bubble(self, content, bubble_type, pi_creature, pi_creature_target_mode = None, added_anims = [], **bubble_kwargs): if all(map(lambda s : isinstance(s, str), content)): content = TextMobject(*content) elif len(content) == 1 and isinstance(content[0], TexMobject): content = content[0] else: raise Exception("Invalid content type") content_intro_anims = self.get_bubble_intro_animation( content, bubble_type, pi_creature, **bubble_kwargs ) if not pi_creature_target_mode: if bubble_type is "speech": pi_creature_target_mode = "speaking" else: pi_creature_target_mode = "pondering" for p in self.get_everyone(): if p.bubble and p is not pi_creature: added_anims += [ FadeOut(p.bubble), FadeOut(p.bubble.content) ] p.bubble = None added_anims.append(ApplyMethod(p.change_mode, "plain")) anims = added_anims + content_intro_anims + [ ApplyMethod( pi_creature.change_mode, pi_creature_target_mode, ), ] self.play(*anims) return pi_creature.bubble def teacher_says(self, *content, **kwargs): return self.introduce_bubble( content, "speech", self.get_teacher(), **kwargs ) def student_says(self, *content, **kwargs): student = self.get_students()[kwargs.get("student_index", 1)] return self.introduce_bubble(content, "speech", student, **kwargs) def teacher_thinks(self, *content, **kwargs): return self.introduce_bubble( content, "thought", self.get_teacher(), **kwargs ) def student_thinks(self, *content, **kwargs): student = self.get_students()[kwargs.get("student_index", 1)] return self.introduce_bubble(content, "thought", student, **kwargs) def random_blink(self, num_times = 1): for x in range(num_times): pi_creature = random.choice(self.get_everyone()) self.play(Blink(pi_creature)) self.dither() def change_student_modes(self, *modes): self.play(*[ ApplyMethod(pi.change_mode, mode) for pi, mode in zip(self.get_students(), modes) ]) def zoom_in_on_thought_bubble(self, radius = SPACE_HEIGHT+SPACE_WIDTH): bubble = None for pi in self.get_everyone(): if hasattr(pi, "bubble") and isinstance(pi.bubble, ThoughtBubble): bubble = pi.bubble break if bubble is None: raise Exception("No pi creatures have a thought bubble") vect = -bubble.get_bubble_center() def func(point): centered = point+vect return radius*centered/np.linalg.norm(centered) self.play(*[ ApplyPointwiseFunction(func, mob) for mob in self.get_mobjects() ])
class TeacherStudentsScene(Scene): def setup(self): self.teacher = Mortimer() self.teacher.to_corner(DOWN + RIGHT) self.teacher.look(DOWN+LEFT) self.students = VMobject(*[ Randolph(color = c) for c in BLUE_D, BLUE_C, BLUE_E ]) self.students.arrange_submobjects(RIGHT) self.students.scale(0.8) self.students.to_corner(DOWN+LEFT) for pi_creature in self.get_everyone(): pi_creature.bubble = None self.add(*self.get_everyone()) def get_teacher(self): return self.teacher def get_students(self): return self.students.split() def get_everyone(self): return [self.get_teacher()] + self.get_students() def get_bubble_intro_animation(self, content, bubble_type, pi_creature, **bubble_kwargs): bubble = pi_creature.get_bubble(bubble_type, **bubble_kwargs) bubble.add_content(content) if pi_creature.bubble: content_intro_anims = [ Transform(pi_creature.bubble, bubble), Transform(pi_creature.bubble.content, bubble.content) ] else: content_intro_anims = [ FadeIn(bubble), Write(content), ] pi_creature.bubble = bubble return content_intro_anims def introduce_bubble(self, content, bubble_type, pi_creature, pi_creature_target_mode = None, added_anims = [], **bubble_kwargs): if isinstance(content, str): content = TextMobject(content) content_intro_anims = self.get_bubble_intro_animation( content, bubble_type, pi_creature, **bubble_kwargs ) if not pi_creature_target_mode: if bubble_type is "speech": pi_creature_target_mode = "speaking" else: pi_creature_target_mode = "pondering" for p in self.get_everyone(): if p.bubble and p is not pi_creature: added_anims += [ FadeOut(p.bubble), FadeOut(p.bubble.content) ] p.bubble = None added_anims.append(ApplyMethod(p.change_mode, "plain")) anims = added_anims + content_intro_anims + [ ApplyMethod( pi_creature.change_mode, pi_creature_target_mode, ), ] self.play(*anims) return pi_creature.bubble def teacher_says(self, content = "", **kwargs): return self.introduce_bubble( content, "speech", self.get_teacher(), **kwargs ) def student_says(self, content = "", student_index = 1, **kwargs): student = self.get_students()[student_index] return self.introduce_bubble(content, "speech", student, **kwargs) def teacher_thinks(self, content = "", **kwargs): return self.introduce_bubble( content, "thought", self.get_teacher(), **kwargs ) def student_thinks(self, content = "", student_index = 1, **kwargs): student = self.get_students()[student_index] return self.introduce_bubble(content, "thought", student, **kwargs) def random_blink(self, num_times = 1): for x in range(num_times): pi_creature = random.choice(self.get_everyone()) self.play(Blink(pi_creature)) self.dither()
def organize_matrices(self, left, right, result): equals = TexMobject("=") everything = VMobject(left, right, equals, result) everything.arrange_submobjects() everything.scale_to_fit_width(2*SPACE_WIDTH-1) self.add(everything)
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.wait() 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.wait() 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.wait() self.play(Write(functions)) self.wait()
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.wait() self.play(Transform(question, first), ShowCreation(first_arrow), ShowCreation(col.circle), ApplyMethod(col.highlight, col.target_color)) self.wait() 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.wait() self.play(*map(FadeOut, [question, first_arrow])) self.play(Write(intermediate)) self.wait() self.play(Write(product)) self.wait() product_entries = product.get_entries() self.play(ApplyMethod(comp_col.highlight, BLACK), ApplyMethod(product_entries.move_to, comp_col)) self.wait() 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.wait()
def organize_matrices(self, left, right, result): equals = TexMobject("=") everything = VMobject(left, right, equals, result) everything.arrange_submobjects() everything.scale_to_fit_width(2 * SPACE_WIDTH - 1) self.add(everything)