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): 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 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.wait()
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 ))
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): 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))
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 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.wait() self.play( ShowCreation(circle), ApplyMethod(mathy.change_mode, "plain") ) self.wait()
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): 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): 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): 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 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): 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()
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()