def construct(self): two_dot = TexMobject("2\\cdot") equals = TexMobject("=") self.add_axes() v = self.add_vector([3, 1]) v_coords, vx_line, vy_line = self.vector_to_coords(v, cleanup = False) self.play(ApplyMethod(v_coords.to_edge, UP)) two_dot.next_to(v_coords, LEFT) equals.next_to(v_coords, RIGHT) two_v = self.add_vector([6, 2], animate = False) self.remove(two_v) self.play( Transform(v.copy(), two_v), Write(two_dot, run_time = 1) ) two_v_coords, two_v_x_line, two_v_y_line = self.vector_to_coords( two_v, cleanup = False ) self.play( ApplyMethod(two_v_coords.next_to, equals, RIGHT), Write(equals, run_time = 1) ) self.dither(2) x, y = v_coords.get_mob_matrix().flatten() two_v_elems = two_v_coords.get_mob_matrix().flatten() x_sym, y_sym = map(TexMobject, ["x", "y"]) two_x_sym, two_y_sym = map(TexMobject, ["2x", "2y"]) VMobject(x_sym, two_x_sym).highlight(X_COLOR) VMobject(y_sym, two_y_sym).highlight(Y_COLOR) syms = [x_sym, y_sym, two_x_sym, two_y_sym] VMobject(*syms).scale(VECTOR_LABEL_SCALE_VAL) for sym, num in zip(syms, [x, y] + list(two_v_elems)): sym.move_to(num) self.play( Transform(x, x_sym), Transform(y, y_sym), FadeOut(VMobject(*two_v_elems)) ) self.dither() self.play( Transform( VMobject(two_dot.copy(), x.copy()), two_x_sym ), Transform( VMobject(two_dot.copy(), y.copy() ), two_y_sym ) ) self.dither(2)
def construct(self): v_mob = TexMobject(get_vect_tex("v")) v_mob.highlight(V_COLOR) matrix = Matrix([self.vect_coords]) vector = Matrix(self.vect_coords) matrix.highlight_columns(X_COLOR, Y_COLOR) vector.highlight_columns(YELLOW) _input = Matrix(["x", "y"]) _input.get_entries().gradient_highlight(X_COLOR, Y_COLOR) left_input, right_input = [_input.copy() for x in range(2)] dot, equals = map(TexMobject, ["\\cdot", "="]) equation = Group( vector, dot, left_input, equals, matrix, right_input ) equation.arrange_submobjects() left_brace = Brace(Group(vector, left_input)) right_brace = Brace(matrix, UP) left_words = left_brace.get_text("Dot product") right_words = right_brace.get_text("Transform") right_words.scale_to_fit_width(right_brace.get_width()) right_v_brace = Brace(right_input, UP) right_v_mob = v_mob.copy() right_v_brace.put_at_tip(right_v_mob) right_input.add(right_v_brace, right_v_mob) left_v_brace = Brace(left_input, UP) left_v_mob = v_mob.copy() left_v_brace.put_at_tip(left_v_mob) left_input.add(left_v_brace, left_v_mob) self.add(matrix, right_input) self.play( GrowFromCenter(right_brace), Write(right_words, run_time = 1) ) self.dither() self.play( Write(equals), Write(dot), Transform(matrix.copy(), vector), Transform(right_input.copy(), left_input) ) self.play( GrowFromCenter(left_brace), Write(left_words, run_time = 1) ) self.dither()
def construct(self): l_m1, l_m2, eq, r_m2, r_m1 = TexMobject([ "M_1", "M_2", "=", "M_2", "M_1" ]).scale(1.5).split() VMobject(l_m1, r_m1).highlight(YELLOW) VMobject(l_m2, r_m2).highlight(PINK) q_marks = TextMobject("???") q_marks.highlight(TEAL) q_marks.next_to(eq, UP) neq = TexMobject("\\neq") neq.move_to(eq) self.play(*map(Write, [l_m1, l_m2, eq])) self.play( Transform(l_m1.copy(), r_m1), Transform(l_m2.copy(), r_m2), path_arc = -np.pi, run_time = 2 ) self.play(Write(q_marks)) self.dither() self.play(Transform( VMobject(eq, q_marks), VMobject(neq), submobject_mode = "lagged_start" )) self.dither()
def show_snells(self, index, frame): left_text, right_text = [ "\\dfrac{\\sin(\\theta_%d)}{\\phantom{\\sqrt{y_1}}}"%x for x in index, index+1 ] left, equals, right = TexMobject( [left_text, "=", right_text] ).split() vs = [] sqrt_ys = [] for x, numerator in [(index, left), (index+1, right)]: v, sqrt_y = [ TexMobject( text, size = "\\Large" ).next_to(numerator, DOWN) for text in "v_%d"%x, "\\sqrt{y_%d}"%x ] vs.append(v) sqrt_ys.append(sqrt_y) start, end = [ Mobject( left.copy(), mobs[0], equals.copy(), right.copy(), mobs[1] ).replace(frame) for mobs in vs, sqrt_ys ] self.add(start) self.dither(2) self.play(Transform( start, end, path_func = counterclockwise_path() )) self.dither(2) self.remove(start, end)
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 rearrange(self): sqrt_nudge = 0.2*LEFT y, equals = self.y_equals.split() d, sin, squared, theta = self.y_expression.split() y_sqrt = TexMobject("\\sqrt{\\phantom{y}}") d_sqrt = y_sqrt.copy() y_sqrt.shift(y.get_center()+sqrt_nudge) d_sqrt.shift(d.get_center()+sqrt_nudge) self.play( ShimmerIn(y_sqrt), ShimmerIn(d_sqrt), ApplyMethod(squared.shift, 4*UP), ApplyMethod(theta.shift, 1.5* squared.get_width()*LEFT) ) self.dither() y_sqrt.add(y) d_sqrt.add(d) sin.add(theta) sin_over = TexMobject("\\dfrac{\\phantom{\\sin(\\theta)}}{\\quad}") sin_over.next_to(sin, DOWN, 0.15) new_eq = equals.copy() new_eq.next_to(sin_over, LEFT) one_over = TexMobject("\\dfrac{1}{\\quad}") one_over.next_to(new_eq, LEFT) one_over.shift( (sin_over.get_bottom()[1]-one_over.get_bottom()[1])*UP ) self.play( Transform(equals, new_eq), ShimmerIn(sin_over), ShimmerIn(one_over), ApplyMethod( d_sqrt.next_to, one_over, DOWN, path_func = path_along_arc(-np.pi) ), ApplyMethod( y_sqrt.next_to, sin_over, DOWN, path_func = path_along_arc(-np.pi) ), run_time = 2 ) self.dither() brace = Brace(d_sqrt, DOWN) constant = TextMobject("Constant") constant.next_to(brace, DOWN) self.play( GrowFromCenter(brace), ShimmerIn(constant) )
def generate_sea_of_zeros(self): zero = TexMobject("0") self.sea_of_zeros = [] for n in range(self.nrows): for a in range((self.nrows - n)/2 + 1): for k in (n + a + 1, -a -1): self.coords.append((n, k)) mob = zero.copy() mob.shift(self.coords_to_center(n, k)) self.coords_to_mobs[n][k] = mob self.add(mob) return self
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): 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 get_log_anim(self, center): O_log_n = TexMobject(["O(", "\\log(n)", ")"]) O_log_n.shift(center) log_n = O_log_n.split()[1] #super hacky g = log_n.split()[2] for mob in g.submobjects: mob.is_subpath = False mob.set_fill(BLACK, 1.0) log_n.add(mob) g.submobjects = [] #end hack top = TOP(2, None, "n", radius = 0.75) top.scale_to_fit_width(log_n.get_width()) top.shift(log_n.get_center()) new_O_log_n = O_log_n.copy() new_O_log_n.submobjects[1] = top return Transform(O_log_n, new_O_log_n)
def take_third_derivative_of_cubic(self): polynomial = self.polynomial plus_cubic_term = TexMobject("+\\,", "c_3", "x^3") plus_cubic_term.next_to(polynomial, RIGHT) plus_cubic_term.to_edge(RIGHT, buff = LARGE_BUFF) plus_cubic_term.highlight_by_tex("c_3", self.colors[3]) plus_cubic_copy = plus_cubic_term.copy() polynomial.generate_target() polynomial.target.next_to(plus_cubic_term, LEFT) self.play(FocusOn(polynomial)) self.play( MoveToTarget(polynomial), GrowFromCenter(plus_cubic_term) ) self.dither() brace = Brace(polynomial.quadratic_part, DOWN) third_derivative = TexMobject( "\\frac{d^3 P}{dx^3}(x) = ", "0" ) third_derivative.shift( brace.get_bottom() + MED_SMALL_BUFF*DOWN -\ third_derivative.get_part_by_tex("0").get_top() ) self.play(Write(third_derivative[0])) self.play(GrowFromCenter(brace)) self.play(ReplacementTransform( polynomial.quadratic_part.copy(), VGroup(third_derivative[1]) )) self.dither(2) self.play(plus_cubic_copy.next_to, third_derivative, RIGHT) derivative_term = self.take_derivatives_of_monomial( VGroup(*plus_cubic_copy[1:]) ) third_derivative.add(derivative_term) self.polynomial_third_derivative = third_derivative
def write_old_style_rules(self): start = TexMobject("a^x a^y = a^{x+y}") end = TexMobject("\\log_a(xy) = \\log_a(x) + \\log_a(y)") start.shift(UP) end.shift(DOWN) a1, x1, a2, y1, eq1, a3, p1, x2, y2 = start.split() a4, x3, y3, eq2, a5, x4, p2, a6, y4 = np.array(end.split())[ [3, 5, 6, 8, 12, 14, 16, 20, 22] ] start_copy = start.copy() self.play(Write(start_copy)) self.wait() self.play(Transform( VMobject(a1, x1, a2, y1, eq1, a3, p1, x2, a3.copy(), y2), VMobject(a4, x3, a4.copy(), y3, eq2, a5, p2, x4, a6, y4) )) self.play(Write(end)) self.clear() self.add(start_copy, end) self.wait() return start_copy, end
def write_old_style_rules(self): start = TexMobject("a^x a^y = a^{x+y}") end = TexMobject("\\log_a(xy) = \\log_a(x) + \\log_a(y)") start.shift(UP) end.shift(DOWN) a1, x1, a2, y1, eq1, a3, p1, x2, y2 = start.split() a4, x3, y3, eq2, a5, x4, p2, a6, y4 = np.array(end.split())[ [3, 5, 6, 8, 12, 14, 16, 20, 22] ] start_copy = start.copy() self.play(Write(start_copy)) self.dither() self.play(Transform( VMobject(a1, x1, a2, y1, eq1, a3, p1, x2, a3.copy(), y2), VMobject(a4, x3, a4.copy(), y3, eq2, a5, p2, x4, a6, y4) )) self.play(Write(end)) self.clear() self.add(start_copy, end) self.dither() return start_copy, end
def construct(self): CycloidScene.construct(self) equation = TexMobject([ "\\dfrac{\\sin(\\theta)}{\\sqrt{y}}", "= \\text{constant}" ]) sin_sqrt, const = equation.split() new_eq = equation.copy() new_eq.to_edge(UP, buff = 1.3) cycloid_word = TextMobject("Cycloid") arrow = Arrow(2*UP, cycloid_word) arrow.reverse_points() q_mark = TextMobject("?") self.play(*map(ShimmerIn, equation.split())) self.dither() self.play( ApplyMethod(equation.shift, 2.2*UP), ShowCreation(arrow) ) q_mark.next_to(sin_sqrt) self.play(ShimmerIn(cycloid_word)) self.dither() self.grow_parts() self.draw_cycloid() self.dither() extra_terms = [const, arrow, cycloid_word] self.play(*[ Transform(mob, q_mark) for mob in extra_terms ]) self.remove(*extra_terms) self.roll_back() q_marks, arrows = self.get_q_marks_and_arrows(sin_sqrt) self.draw_cycloid(3, ShowCreation(q_marks), ShowCreation(arrows) ) self.dither()
def construct(self): CycloidScene.construct(self) equation = TexMobject([ "\\dfrac{\\sin(\\theta)}{\\sqrt{y}}", "= \\text{constant}" ]) sin_sqrt, const = equation.split() new_eq = equation.copy() new_eq.to_edge(UP, buff = 1.3) cycloid_word = TextMobject("Cycloid") arrow = Arrow(2*UP, cycloid_word) arrow.reverse_points() q_mark = TextMobject("?") self.play(*map(ShimmerIn, equation.split())) self.wait() self.play( ApplyMethod(equation.shift, 2.2*UP), ShowCreation(arrow) ) q_mark.next_to(sin_sqrt) self.play(ShimmerIn(cycloid_word)) self.wait() self.grow_parts() self.draw_cycloid() self.wait() extra_terms = [const, arrow, cycloid_word] self.play(*[ Transform(mob, q_mark) for mob in extra_terms ]) self.remove(*extra_terms) self.roll_back() q_marks, arrows = self.get_q_marks_and_arrows(sin_sqrt) self.draw_cycloid(3, ShowCreation(q_marks), ShowCreation(arrows) ) self.wait()
def construct(self): l_m1, l_m2, eq, r_m2, r_m1 = TexMobject( ["M_1", "M_2", "=", "M_2", "M_1"]).scale(1.5).split() VMobject(l_m1, r_m1).highlight(YELLOW) VMobject(l_m2, r_m2).highlight(PINK) q_marks = TextMobject("???") q_marks.highlight(TEAL) q_marks.next_to(eq, UP) neq = TexMobject("\\neq") neq.move_to(eq) self.play(*map(Write, [l_m1, l_m2, eq])) self.play(Transform(l_m1.copy(), r_m1), Transform(l_m2.copy(), r_m2), path_arc=-np.pi, run_time=2) self.play(Write(q_marks)) self.wait() self.play( Transform(VMobject(eq, q_marks), VMobject(neq), submobject_mode="lagged_start")) self.wait()
def show_layer_variables(self): layer_top_pairs = zip( self.layer_tops[:self.num_variables], self.layer_tops[1:] ) v_equations = [] start_ys = [] end_ys = [] center_paths = [] braces = [] for (top1, top2), x in zip(layer_top_pairs, it.count(1)): eq_mob = TexMobject( ["v_%d"%x, "=", "\sqrt{\phantom{y_1}}"], size = "\\Large" ) midpoint = UP*(top1+top2)/2 eq_mob.shift(midpoint) v_eq = eq_mob.split() center_paths.append(Line( midpoint+SPACE_WIDTH*LEFT, midpoint+SPACE_WIDTH*RIGHT )) brace_endpoints = Mobject( Point(self.top*UP+x*RIGHT), Point(top2*UP+x*RIGHT) ) brace = Brace(brace_endpoints, RIGHT) start_y = TexMobject("y_%d"%x, size = "\\Large") end_y = start_y.copy() start_y.next_to(brace, RIGHT) end_y.shift(v_eq[-1].get_center()) end_y.shift(0.2*RIGHT) v_equations.append(v_eq) start_ys.append(start_y) end_ys.append(end_y) braces.append(brace) for v_eq, path, time in zip(v_equations, center_paths, [2, 1, 0.5]): photon_run = self.photon_run_along_path( path, rate_func = None ) self.play( ShimmerIn(v_eq[0]), photon_run, run_time = time ) self.wait() for start_y, brace in zip(start_ys, braces): self.add(start_y) self.play(GrowFromCenter(brace)) self.wait() quads = zip(v_equations, start_ys, end_ys, braces) self.equations = [] for v_eq, start_y, end_y, brace in quads: self.remove(brace) self.play( ShowCreation(v_eq[1]), ShowCreation(v_eq[2]), Transform(start_y, end_y) ) v_eq.append(start_y) self.equations.append(Mobject(*v_eq))
def contrast_big_and_small_concavity(self): colors = color_gradient([GREEN, WHITE], 3) x0, y0 = 4, 2 graphs = [ self.get_graph(func, color = color) for color, func in zip(colors, [ lambda x : 5*(x - x0)**2 + y0, lambda x : 0.2*(x - x0)**2 + y0, lambda x : (x-x0) + y0, ]) ] arg_rhs_list = [ TexMobject("(", str(x0), ")", "=", str(rhs)) for rhs in 10, 0.4, 0 ] for graph, arg_rhs in zip(graphs, arg_rhs_list): graph.ss_group = self.get_secant_slope_group( x0-1, graph, dx = 0.001, secant_line_color = YELLOW ) arg_rhs.move_to(self.second_deriv.get_center(), LEFT) graph.arg_rhs = arg_rhs graph = graphs[0] v_line = DashedLine(*[ self.coords_to_point(x0, 0), self.coords_to_point(x0, y0), ]) input_label = TexMobject(str(x0)) input_label.next_to(v_line, DOWN) self.play(ShowCreation(graph, run_time = 2)) self.play( Write(input_label), ShowCreation(v_line) ) self.play( ReplacementTransform( input_label.copy(), graph.arg_rhs.get_part_by_tex(str(x0)) ), self.second_deriv.next_to, graph.arg_rhs.copy(), LEFT, SMALL_BUFF, Write(VGroup(*[ submob for submob in graph.arg_rhs if submob is not graph.arg_rhs.get_part_by_tex(str(x0)) ])) ) self.dither() self.play(FadeIn(graph.ss_group)) self.animate_secant_slope_group_change( graph.ss_group, target_x = x0 + 1, run_time = 3, ) self.play(FadeOut(graph.ss_group)) self.dither() for new_graph in graphs[1:]: self.play(Transform(graph, new_graph)) self.play(Transform( graph.arg_rhs, new_graph.arg_rhs, )) self.play(FadeIn(new_graph.ss_group)) self.animate_secant_slope_group_change( new_graph.ss_group, target_x = x0 + 1, run_time = 3, ) self.play(FadeOut(new_graph.ss_group))
def construct(self): title = TextMobject("Russellův paradox").to_edge(UP) self.add(title) set_inside = TextMobject("Množiny, které neobsahují samu sebe") set_rect = SurroundingRectangle(set_inside, buff = 0.8, color = RED) self.play(FadeIn(set_inside), ShowCreation(set_rect)) X_label = TexMobject('X').next_to(set_rect, UP, aligned_edge = LEFT) self.wait_to(5.5) self.play(Write(X_label)) bubble_q = ChatBubble("Obsahuje $X$ samu sebe?", True) bubble_q.save_state() bubble_q.stretch_about_point(0,1,SPACE_HEIGHT*DOWN) bubble_q.highlight(BLACK) self.wait_to(7.5) self.play(ApplyMethod(bubble_q.restore, rate_func = rush_from)) self.wait_to(13.5) bubble_a = ChatBubble("Že by neobsahuje?", False) bubble_a.save_state() bubble_a.stretch_about_point(0,1,SPACE_HEIGHT*DOWN) bubble_a.highlight(BLACK) self.play(ApplyMethod(bubble_a.restore, rate_func = rush_from)) self.wait_to(17) X_label2 = X_label.copy() X_label2.shift( set_rect.get_corner(UP+RIGHT) - X_label2.get_corner(UP+RIGHT) ) X_label2.shift(0.2*(DOWN+LEFT)) X_label2.save_state() X_label2.shift(UP) X_label2.set_fill(opacity = 0) self.play(X_label2.restore) self.wait_to(25) self.play(FadeOut(bubble_a)) bubble_a = ChatBubble("Tak obsahuje?", False) bubble_a.save_state() bubble_a.stretch_about_point(0,1,SPACE_HEIGHT*DOWN) bubble_a.highlight(BLACK) self.play(ApplyMethod(bubble_a.restore, rate_func = rush_from)) self.wait_to(27.5) X_label2.save_state() X_label2.shift(UP) X_label2.set_fill(opacity = 0) self.play(MoveFromSaved(X_label2, remover = True)) self.wait_to(61.5) self.play(FadeOut(VGroup( bubble_q, bubble_a, title, X_label, set_rect, set_inside, )))
class Notation(Scene): def construct(self): self.introduce_notation() self.shift_to_good_and_back() self.shift_to_visuals() self.swipe_left() def introduce_notation(self): notation = TextMobject("Notation") notation.to_edge(UP) self.sum1 = TexMobject("\\sum_{n=1}^\\infty \\dfrac{1}{n}") self.prod1 = TexMobject("\\prod_{p\\text{ prime}}\\left(1-p^{-s}\\right)") self.trigs1 = TexMobject([ ["\\sin", "(x)"], ["\\cos", "(x)"], ["\\tan", "(x)"], ], next_to_direction = DOWN) self.func1 = TexMobject("f(x) = y") symbols = [self.sum1, self.prod1, self.trigs1, self.func1] for sym, vect in zip(symbols, compass_directions(4, UP+LEFT)): sym.scale(0.5) vect[0] *= 2 sym.shift(vect) self.symbols = VMobject(*symbols) self.play(Write(notation)) self.play(Write(self.symbols)) self.dither() self.add(notation, self.symbols) def shift_to_good_and_back(self): sum2 = self.sum1.copy() sigma = sum2.submobjects[1] plus = TexMobject("+").replace(sigma) sum2.submobjects[1] = plus prod2 = self.prod1.copy() pi = prod2.submobjects[0] times = TexMobject("\\times").replace(pi) prod2.submobjects[0] = times new_sin, new_cos, new_tan = [ VMobject().set_anchor_points( corners, mode = "corners" ).replace(trig_part.split()[0]) for corners, trig_part in zip( [ [RIGHT, RIGHT+UP, LEFT], [RIGHT+UP, LEFT, RIGHT], [RIGHT+UP, RIGHT, LEFT], ], self.trigs1.split() ) ] x1, x2, x3 = [ trig_part.split()[1] for trig_part in self.trigs1.split() ] trigs2 = VMobject( VMobject(new_sin, x1), VMobject(new_cos, x2), VMobject(new_tan, x3), ) x, arrow, y = TexMobject("x \\rightarrow y").split() f = TexMobject("f") f.next_to(arrow, UP) func2 = VMobject(f, VMobject(), x, VMobject(), arrow, y) func2.scale(0.5) func2.shift(self.func1.get_center()) good_symbols = VMobject(sum2, prod2, trigs2, func2) bad_symbols = self.symbols.copy() self.play(Transform( self.symbols, good_symbols, path_arc = np.pi )) self.dither(3) self.play(Transform( self.symbols, bad_symbols, path_arc = np.pi )) self.dither() def shift_to_visuals(self): sigma, prod, trig, func = self.symbols.split() new_trig = trig.copy() sin, cos, tan = [ trig_part.split()[0] for trig_part in new_trig.split() ] trig_anim = TrigAnimation() sin.highlight(trig_anim.sin_color) cos.highlight(trig_anim.cos_color) tan.highlight(trig_anim.tan_color) new_trig.to_corner(UP+RIGHT) sum_lines = self.get_harmonic_sum_lines() self.play( Transform(trig, new_trig), *it.starmap(ApplyMethod, [ (sigma.to_corner, UP+LEFT), (prod.shift, 15*LEFT), (func.shift, 5*UP), ]) ) sum_lines.next_to(sigma, DOWN) self.remove(prod, func) self.play( trig_anim, Write(sum_lines) ) self.play(trig_anim) self.dither() def get_harmonic_sum_lines(self): result = VMobject() for n in range(1, 8): big_line = NumberLine( x_min = 0, x_max = 1.01, tick_frequency = 1./n, numbers_with_elongated_ticks = [], color = WHITE ) little_line = Line( big_line.number_to_point(0), big_line.number_to_point(1./n), color = RED ) big_line.add(little_line) big_line.shift(0.5*n*DOWN) result.add(big_line) return result def swipe_left(self): everyone = VMobject(*self.mobjects) self.play(ApplyMethod(everyone.shift, 20*LEFT))
def construct(self): title = TextMobject("``Linearly dependent'' ") title.highlight(YELLOW) title.scale(2) title.to_edge(UP) self.add(title) equation1 = TexMobject([ "\\vec{\\textbf{w}}", "=", "a", "\\vec{\\textbf{v}}", ]) w, eq, a, v = equation1.split() w.highlight(BLUE) v.highlight(MAROON_C) equation1.scale(2) eq1_copy = equation1.copy() low_words1 = TextMobject("For some value of $a$") low_words1.scale(2) low_words1.to_edge(DOWN) arrow = Arrow(low_words1, a) arrow_copy = arrow.copy() equation2 = TexMobject([ "\\vec{\\textbf{u}}", "=", "a", "\\vec{\\textbf{v}}", "+", "b", "\\vec{\\textbf{w}}", ]) u, eq, a, v, plus, b, w = equation2.split() u.highlight(RED) w.highlight(BLUE) v.highlight(MAROON_C) equation2.scale(2) eq2_copy = equation2.copy() low_words2 = TextMobject("For some values of a and b") low_words2.scale(2) low_words2.to_edge(DOWN) arrows = VMobject(*[Arrow(low_words2, var) for var in a, b]) self.play(Write(equation1)) self.play(ShowCreation(arrow), Write(low_words1)) self.wait() self.play(Transform(equation1, equation2), Transform(low_words1, low_words2), Transform(arrow, arrows)) self.wait(2) new_title = TextMobject("``Linearly independent'' ") new_title.highlight(GREEN) new_title.replace(title) for eq_copy in eq1_copy, eq2_copy: neq = TexMobject("\\neq") neq.replace(eq_copy.submobjects[1]) eq_copy.submobjects[1] = neq new_low_words1 = TextMobject(["For", "all", "values of a"]) new_low_words2 = TextMobject(["For", "all", "values of a and b"]) for low_words in new_low_words1, new_low_words2: low_words.split()[1].highlight(GREEN) low_words.scale(2) low_words.to_edge(DOWN) self.play(Transform(title, new_title), Transform(equation1, eq1_copy), Transform(arrow, arrow_copy), Transform(low_words1, new_low_words1)) self.wait() self.play(Transform(equation1, eq2_copy), Transform(arrow, arrows), Transform(low_words1, new_low_words2)) self.wait()
def show_layer_variables(self): layer_top_pairs = zip( self.layer_tops[:self.num_variables], self.layer_tops[1:] ) v_equations = [] start_ys = [] end_ys = [] center_paths = [] braces = [] for (top1, top2), x in zip(layer_top_pairs, it.count(1)): eq_mob = TexMobject( ["v_%d"%x, "=", "\sqrt{\phantom{y_1}}"], size = "\\Large" ) midpoint = UP*(top1+top2)/2 eq_mob.shift(midpoint) v_eq = eq_mob.split() center_paths.append(Line( midpoint+SPACE_WIDTH*LEFT, midpoint+SPACE_WIDTH*RIGHT )) brace_endpoints = Mobject( Point(self.top*UP+x*RIGHT), Point(top2*UP+x*RIGHT) ) brace = Brace(brace_endpoints, RIGHT) start_y = TexMobject("y_%d"%x, size = "\\Large") end_y = start_y.copy() start_y.next_to(brace, RIGHT) end_y.shift(v_eq[-1].get_center()) end_y.shift(0.2*RIGHT) v_equations.append(v_eq) start_ys.append(start_y) end_ys.append(end_y) braces.append(brace) for v_eq, path, time in zip(v_equations, center_paths, [2, 1, 0.5]): photon_run = self.photon_run_along_path( path, rate_func = None ) self.play( ShimmerIn(v_eq[0]), photon_run, run_time = time ) self.dither() for start_y, brace in zip(start_ys, braces): self.add(start_y) self.play(GrowFromCenter(brace)) self.dither() quads = zip(v_equations, start_ys, end_ys, braces) self.equations = [] for v_eq, start_y, end_y, brace in quads: self.remove(brace) self.play( ShowCreation(v_eq[1]), ShowCreation(v_eq[2]), Transform(start_y, end_y) ) v_eq.append(start_y) self.equations.append(Mobject(*v_eq))
def construct(self): self.add_layers() v_equations = [] start_ys = [] end_ys = [] center_paths = [] braces = [] for layer, x in zip(self.layers[:3], it.count(1)): eq_mob = TexMobject( ["v_%d"%x, "=", "\sqrt{\phantom{y_1}}"], size = "\\Large" ) eq_mob.shift(layer.get_center()+2*LEFT) v_eq = eq_mob.split() v_eq[0].highlight(layer.get_color()) path = Line(SPACE_WIDTH*LEFT, SPACE_WIDTH*RIGHT) path.shift(layer.get_center()) brace_endpoints = Mobject( Point(self.top), Point(layer.get_bottom()) ) brace = Brace(brace_endpoints, RIGHT) brace.shift(x*RIGHT) start_y = TexMobject("y_%d"%x, size = "\\Large") end_y = start_y.copy() start_y.next_to(brace, RIGHT) end_y.shift(v_eq[-1].get_center()) nudge = 0.2*RIGHT end_y.shift(nudge) v_equations.append(v_eq) start_ys.append(start_y) end_ys.append(end_y) center_paths.append(path) braces.append(brace) for v_eq, path, time in zip(v_equations, center_paths, [2, 1, 0.5]): photon_run = self.photon_run_along_path( path, rate_func = None ) self.play( FadeToColor(v_eq[0], WHITE), photon_run, run_time = time ) self.dither() starts = [0, 0.3, 0.6] self.play(*it.chain(*[ [ GrowFromCenter( mob, rate_func=squish_rate_func(smooth, start, 1) ) for mob, start in zip(mobs, starts) ] for mobs in start_ys, braces ])) self.dither() triplets = zip(v_equations, start_ys, end_ys) anims = [] for v_eq, start_y, end_y in triplets: anims += [ ShowCreation(v_eq[1]), ShowCreation(v_eq[2]), Transform(start_y.copy(), end_y) ] self.play(*anims) self.dither()
def construct(self): title = TextMobject("Russell's paradox").to_edge(UP) self.add(title) set_inside = TextMobject("Sets that does not contain themselves") set_rect = SurroundingRectangle(set_inside, buff=0.8, color=RED) self.play(FadeIn(set_inside), ShowCreation(set_rect)) X_label = TexMobject('X').next_to(set_rect, UP, aligned_edge=LEFT) #self.wait_to(5.5) self.play(Write(X_label)) bubble_q = ChatBubble("Does $X$ contain itself?", True) bubble_q.save_state() bubble_q.stretch_about_point(0, 1, SPACE_HEIGHT * DOWN) bubble_q.highlight(BLACK) #self.wait_to(7.5) self.play(ApplyMethod(bubble_q.restore, rate_func=rush_from)) self.dither(2) #self.wait_to(13.5) bubble_a = ChatBubble("No?", False) bubble_a.save_state() bubble_a.stretch_about_point(0, 1, SPACE_HEIGHT * DOWN) bubble_a.highlight(BLACK) self.play(ApplyMethod(bubble_a.restore, rate_func=rush_from)) #self.wait_to(17) X_label2 = X_label.copy() X_label2.shift( set_rect.get_corner(UP + RIGHT) - X_label2.get_corner(UP + RIGHT)) X_label2.shift(0.2 * (DOWN + LEFT)) X_label2.save_state() X_label2.shift(UP) X_label2.set_fill(opacity=0) self.play(X_label2.restore) #self.wait_to(25) self.dither(2) self.play(FadeOut(bubble_a)) bubble_a = ChatBubble("Or yes...", False) bubble_a.save_state() bubble_a.stretch_about_point(0, 1, SPACE_HEIGHT * DOWN) bubble_a.highlight(BLACK) self.play(ApplyMethod(bubble_a.restore, rate_func=rush_from)) #self.wait_to(27.5) X_label2.save_state() X_label2.shift(UP) X_label2.set_fill(opacity=0) self.play(MoveFromSaved(X_label2, remover=True)) #self.wait_to(61.5) self.dither(2) self.play( FadeOut( VGroup( bubble_q, bubble_a, title, X_label, set_rect, set_inside, )))
def solveEquation(self): leftBrace = TexMobject("[") rightBrace = TexMobject("]") xBraces = Group(leftBrace, rightBrace) xBraces.stretch(2, 0) downBrace = TexMobject("[") upBrace = TexMobject("]") yBraces = Group(downBrace, upBrace) yBraces.stretch(2, 0) yBraces.rotate(TAU / 4) lowerX = self.initial_lower_x lowerY = self.func(lowerX) upperX = self.initial_upper_x upperY = self.func(upperX) leftBrace.move_to(self.coords_to_point(lowerX, 0), aligned_edge=LEFT) leftBraceLabel = DecimalNumber(lowerX) leftBraceLabel.next_to(leftBrace, DOWN + LEFT, buff=SMALL_BUFF) leftBraceLabelAnimation = ContinualChangingDecimal( leftBraceLabel, lambda alpha: self.point_to_coords(leftBrace.get_center())[0], tracked_mobject=leftBrace) self.add(leftBraceLabelAnimation) rightBrace.move_to(self.coords_to_point(upperX, 0), aligned_edge=RIGHT) rightBraceLabel = DecimalNumber(upperX) rightBraceLabel.next_to(rightBrace, DOWN + RIGHT, buff=SMALL_BUFF) rightBraceLabelAnimation = ContinualChangingDecimal( rightBraceLabel, lambda alpha: self.point_to_coords(rightBrace.get_center())[0], tracked_mobject=rightBrace) self.add(rightBraceLabelAnimation) downBrace.move_to(self.coords_to_point(0, lowerY), aligned_edge=DOWN) downBraceLabel = DecimalNumber(lowerY) downBraceLabel.next_to(downBrace, LEFT + DOWN, buff=SMALL_BUFF) downBraceLabelAnimation = ContinualChangingDecimal( downBraceLabel, lambda alpha: self.point_to_coords(downBrace.get_center())[1], tracked_mobject=downBrace) self.add(downBraceLabelAnimation) upBrace.move_to(self.coords_to_point(0, upperY), aligned_edge=UP) upBraceLabel = DecimalNumber(upperY) upBraceLabel.next_to(upBrace, LEFT + UP, buff=SMALL_BUFF) upBraceLabelAnimation = ContinualChangingDecimal( upBraceLabel, lambda alpha: self.point_to_coords(upBrace.get_center())[1], tracked_mobject=upBrace) self.add(upBraceLabelAnimation) lowerDotPoint = self.input_to_graph_point(lowerX, self.graph) lowerDotXPoint = self.coords_to_point(lowerX, 0) lowerDotYPoint = self.coords_to_point(0, self.func(lowerX)) lowerDot = Dot(lowerDotPoint) upperDotPoint = self.input_to_graph_point(upperX, self.graph) upperDot = Dot(upperDotPoint) upperDotXPoint = self.coords_to_point(upperX, 0) upperDotYPoint = self.coords_to_point(0, self.func(upperX)) lowerXLine = Line(lowerDotXPoint, lowerDotPoint, stroke_width=1, color=YELLOW) upperXLine = Line(upperDotXPoint, upperDotPoint, stroke_width=1, color=YELLOW) lowerYLine = Line(lowerDotYPoint, lowerDotPoint, stroke_width=1, color=YELLOW) upperYLine = Line(upperDotYPoint, upperDotPoint, stroke_width=1, color=YELLOW) self.add(lowerXLine, upperXLine, lowerYLine, upperYLine) self.add(xBraces, yBraces, lowerDot, upperDot) for i in range(self.num_iterations): if i == self.iteration_at_which_to_start_zoom: self.activate_zooming() self.little_rectangle.move_to( self.coords_to_point(self.targetX, self.targetY)) inverseZoomFactor = 1 / float(self.zoom_factor) self.play(lowerDot.scale_in_place, inverseZoomFactor, upperDot.scale_in_place, inverseZoomFactor) def makeUpdater(xAtStart): def updater(group, alpha): dot, xBrace, yBrace, xLine, yLine = group newX = interpolate(xAtStart, midX, alpha) newY = self.func(newX) graphPoint = self.input_to_graph_point(newX, self.graph) dot.move_to(graphPoint) xAxisPoint = self.coords_to_point(newX, 0) xBrace.move_to(xAxisPoint) yAxisPoint = self.coords_to_point(0, newY) yBrace.move_to(yAxisPoint) xLine.put_start_and_end_on(xAxisPoint, graphPoint) yLine.put_start_and_end_on(yAxisPoint, graphPoint) return group return updater midX = (lowerX + upperX) / float(2) midY = self.func(midX) midCoords = self.coords_to_point(midX, midY) midColor = RED midXPoint = Dot(self.coords_to_point(midX, 0), color=midColor) self.play(ReplacementTransform(leftBrace.copy(), midXPoint), ReplacementTransform(rightBrace.copy(), midXPoint)) midXLine = Line(self.coords_to_point(midX, 0), midCoords, color=midColor) self.play(ShowCreation(midXLine)) midDot = Dot(midCoords, color=midColor) if (self.iteration_at_which_to_start_zoom != None and i >= self.iteration_at_which_to_start_zoom): midDot.scale_in_place(inverseZoomFactor) self.add(midDot) midYLine = Line(midCoords, self.coords_to_point(0, midY), color=midColor) self.play(ShowCreation(midYLine)) if midY < self.targetY: movingGroup = Group(lowerDot, leftBrace, downBrace, lowerXLine, lowerYLine) self.play(UpdateFromAlphaFunc(movingGroup, makeUpdater(lowerX))) lowerX = midX lowerY = midY else: movingGroup = Group(upperDot, rightBrace, upBrace, upperXLine, upperYLine) self.play(UpdateFromAlphaFunc(movingGroup, makeUpdater(upperX))) upperX = midX upperY = midY self.remove(midXLine, midDot, midYLine) self.wait()
def construct(self): title = TextMobject("``Linearly dependent'' ") title.highlight(YELLOW) title.scale(2) title.to_edge(UP) self.add(title) equation1 = TexMobject([ "\\vec{\\textbf{w}}", "=", "a", "\\vec{\\textbf{v}}", ]) w, eq, a, v = equation1.split() w.highlight(BLUE) v.highlight(MAROON_C) equation1.scale(2) eq1_copy = equation1.copy() low_words1 = TextMobject("For some value of $a$") low_words1.scale(2) low_words1.to_edge(DOWN) arrow = Arrow(low_words1, a) arrow_copy = arrow.copy() equation2 = TexMobject([ "\\vec{\\textbf{u}}", "=", "a", "\\vec{\\textbf{v}}", "+", "b", "\\vec{\\textbf{w}}", ]) u, eq, a, v, plus, b, w = equation2.split() u.highlight(RED) w.highlight(BLUE) v.highlight(MAROON_C) equation2.scale(2) eq2_copy = equation2.copy() low_words2 = TextMobject("For some values of a and b") low_words2.scale(2) low_words2.to_edge(DOWN) arrows = VMobject(*[ Arrow(low_words2, var) for var in a, b ]) self.play(Write(equation1)) self.play( ShowCreation(arrow), Write(low_words1) ) self.dither() self.play( Transform(equation1, equation2), Transform(low_words1, low_words2), Transform(arrow, arrows) ) self.dither(2) new_title = TextMobject("``Linearly independent'' ") new_title.highlight(GREEN) new_title.replace(title) for eq_copy in eq1_copy, eq2_copy: neq = TexMobject("\\neq") neq.replace(eq_copy.submobjects[1]) eq_copy.submobjects[1] = neq new_low_words1 = TextMobject(["For", "all", "values of a"]) new_low_words2 = TextMobject(["For", "all", "values of a and b"]) for low_words in new_low_words1, new_low_words2: low_words.split()[1].highlight(GREEN) low_words.scale(2) low_words.to_edge(DOWN) self.play( Transform(title, new_title), Transform(equation1, eq1_copy), Transform(arrow, arrow_copy), Transform(low_words1, new_low_words1) ) self.dither() self.play( Transform(equation1, eq2_copy), Transform(arrow, arrows), Transform(low_words1, new_low_words2) ) self.dither()
def contrast_big_and_small_concavity(self): colors = color_gradient([GREEN, WHITE], 3) x0, y0 = 4, 2 graphs = [ self.get_graph(func, color = color) for color, func in zip(colors, [ lambda x : 5*(x - x0)**2 + y0, lambda x : 0.2*(x - x0)**2 + y0, lambda x : (x-x0) + y0, ]) ] arg_rhs_list = [ TexMobject("(", str(x0), ")", "=", str(rhs)) for rhs in 10, 0.4, 0 ] for graph, arg_rhs in zip(graphs, arg_rhs_list): graph.ss_group = self.get_secant_slope_group( x0-1, graph, dx = 0.001, secant_line_color = YELLOW ) arg_rhs.move_to(self.second_deriv.get_center(), LEFT) graph.arg_rhs = arg_rhs graph = graphs[0] v_line = DashedLine(*[ self.coords_to_point(x0, 0), self.coords_to_point(x0, y0), ]) input_label = TexMobject(str(x0)) input_label.next_to(v_line, DOWN) self.play(ShowCreation(graph, run_time = 2)) self.play( Write(input_label), ShowCreation(v_line) ) self.play( ReplacementTransform( input_label.copy(), graph.arg_rhs.get_part_by_tex(str(x0)) ), self.second_deriv.next_to, graph.arg_rhs.copy(), LEFT, SMALL_BUFF, Write(VGroup(*[ submob for submob in graph.arg_rhs if submob is not graph.arg_rhs.get_part_by_tex(str(x0)) ])) ) self.wait() self.play(FadeIn(graph.ss_group)) self.animate_secant_slope_group_change( graph.ss_group, target_x = x0 + 1, run_time = 3, ) self.play(FadeOut(graph.ss_group)) self.wait() for new_graph in graphs[1:]: self.play(Transform(graph, new_graph)) self.play(Transform( graph.arg_rhs, new_graph.arg_rhs, )) self.play(FadeIn(new_graph.ss_group)) self.animate_secant_slope_group_change( new_graph.ss_group, target_x = x0 + 1, run_time = 3, ) self.play(FadeOut(new_graph.ss_group))
class Notation(Scene): def construct(self): self.introduce_notation() self.shift_to_good_and_back() self.shift_to_visuals() self.swipe_left() def introduce_notation(self): notation = TextMobject("Notation") notation.to_edge(UP) self.sum1 = TexMobject("\\sum_{n=1}^\\infty \\dfrac{1}{n}") self.prod1 = TexMobject( "\\prod_{p\\text{ prime}}\\left(1-p^{-s}\\right)") self.trigs1 = TexMobject([ ["\\sin", "(x)"], ["\\cos", "(x)"], ["\\tan", "(x)"], ], next_to_direction=DOWN) self.func1 = TexMobject("f(x) = y") symbols = [self.sum1, self.prod1, self.trigs1, self.func1] for sym, vect in zip(symbols, compass_directions(4, UP + LEFT)): sym.scale(0.5) vect[0] *= 2 sym.shift(vect) self.symbols = VMobject(*symbols) self.play(Write(notation)) self.play(Write(self.symbols)) self.wait() self.add(notation, self.symbols) def shift_to_good_and_back(self): sum2 = self.sum1.copy() sigma = sum2.submobjects[1] plus = TexMobject("+").replace(sigma) sum2.submobjects[1] = plus prod2 = self.prod1.copy() pi = prod2.submobjects[0] times = TexMobject("\\times").replace(pi) prod2.submobjects[0] = times new_sin, new_cos, new_tan = [ VMobject().set_anchor_points(corners, mode="corners").replace( trig_part.split()[0]) for corners, trig_part in zip([ [RIGHT, RIGHT + UP, LEFT], [RIGHT + UP, LEFT, RIGHT], [RIGHT + UP, RIGHT, LEFT], ], self.trigs1.split()) ] x1, x2, x3 = [ trig_part.split()[1] for trig_part in self.trigs1.split() ] trigs2 = VMobject( VMobject(new_sin, x1), VMobject(new_cos, x2), VMobject(new_tan, x3), ) x, arrow, y = TexMobject("x \\rightarrow y").split() f = TexMobject("f") f.next_to(arrow, UP) func2 = VMobject(f, VMobject(), x, VMobject(), arrow, y) func2.scale(0.5) func2.shift(self.func1.get_center()) good_symbols = VMobject(sum2, prod2, trigs2, func2) bad_symbols = self.symbols.copy() self.play(Transform(self.symbols, good_symbols, path_arc=np.pi)) self.wait(3) self.play(Transform(self.symbols, bad_symbols, path_arc=np.pi)) self.wait() def shift_to_visuals(self): sigma, prod, trig, func = self.symbols.split() new_trig = trig.copy() sin, cos, tan = [ trig_part.split()[0] for trig_part in new_trig.split() ] trig_anim = TrigAnimation() sin.highlight(trig_anim.sin_color) cos.highlight(trig_anim.cos_color) tan.highlight(trig_anim.tan_color) new_trig.to_corner(UP + RIGHT) sum_lines = self.get_harmonic_sum_lines() self.play( Transform(trig, new_trig), *it.starmap(ApplyMethod, [ (sigma.to_corner, UP + LEFT), (prod.shift, 15 * LEFT), (func.shift, 5 * UP), ])) sum_lines.next_to(sigma, DOWN) self.remove(prod, func) self.play(trig_anim, Write(sum_lines)) self.play(trig_anim) self.wait() def get_harmonic_sum_lines(self): result = VMobject() for n in range(1, 8): big_line = NumberLine(x_min=0, x_max=1.01, tick_frequency=1. / n, numbers_with_elongated_ticks=[], color=WHITE) little_line = Line(big_line.number_to_point(0), big_line.number_to_point(1. / n), color=RED) big_line.add(little_line) big_line.shift(0.5 * n * DOWN) result.add(big_line) return result def swipe_left(self): everyone = VMobject(*self.mobjects) self.play(ApplyMethod(everyone.shift, 20 * LEFT))
def show_equation(self): equation = TexMobject([ "\\left(\\dfrac{1}{\\phantom{v_air}}\\right)", "\\sin(\\theta_1)", "=", "\\left(\\dfrac{1}{\\phantom{v_water}}\\right)", "\\sin(\\theta_2)" ]) equation.to_corner(UP+RIGHT) frac1, sin1, equals, frac2, sin2 = equation.split() v_air, v_water = [ TexMobject("v_{\\text{%s}}"%s, size = "\\Large") for s in "air", "water" ] v_air.next_to(Point(frac1.get_center()), DOWN) v_water.next_to(Point(frac2.get_center()), DOWN) frac1.add(v_air) frac2.add(v_water) f1, f2 = [ TexMobject("F_%d"%d, size = "\\Large") for d in 1, 2 ] f1.next_to(sin1, LEFT) f2.next_to(equals, RIGHT) sin2_start = sin2.copy().next_to(f2, RIGHT) bar1 = TexMobject("\\dfrac{\\qquad}{\\qquad}") bar2 = bar1.copy() bar1.next_to(sin1, DOWN) bar2.next_to(sin2, DOWN) v_air_copy = v_air.copy().next_to(bar1, DOWN) v_water_copy = v_water.copy().next_to(bar2, DOWN) bars = Mobject(bar1, bar2) new_eq = equals.copy().center().shift(bars.get_center()) snells = TextMobject("Snell's Law") snells.highlight(YELLOW) snells.shift(new_eq.get_center()[0]*RIGHT) snells.shift(UP) anims = [] for mob in f1, sin1, equals, f2, sin2_start: anims.append(ShimmerIn(mob)) self.play(*anims) self.wait() for f, frac in (f1, frac1), (f2, frac2): target = frac.copy().ingest_submobjects() also = [] if f is f2: also.append(Transform(sin2_start, sin2)) sin2 = sin2_start self.play(Transform(f, target), *also) self.remove(f) self.add(frac) self.wait() self.play( FadeOut(frac1), FadeOut(frac2), Transform(v_air, v_air_copy), Transform(v_water, v_water_copy), ShowCreation(bars), Transform(equals, new_eq) ) self.wait() frac1 = Mobject(sin1, bar1, v_air) frac2 = Mobject(sin2, bar2, v_water) for frac, vect in (frac1, LEFT), (frac2, RIGHT): self.play(ApplyMethod( frac.next_to, equals, vect )) self.wait() self.play(ShimmerIn(snells)) self.wait()
def construct(self): pws_col = BLUE h = 1.4 * SPACE_HEIGHT w1 = 1 w2 = 1.6 * SPACE_WIDTH set_A = Rectangle(width=w1, height=h).to_edge(LEFT).highlight(YELLOW) set_PA = Rectangle(width=w2, height=h).to_edge(RIGHT).highlight(pws_col) set_A_label = TexMobject('A').highlight(YELLOW).to_corner(UP + LEFT) set_PA_label = TexMobject('\\mathcal P(A)').highlight( pws_col).to_corner(UP + RIGHT) dots_num = 10 p0 = set_A.get_edge_center(UP) + set_A.get_width() / 2 * DOWN p1 = set_A.get_edge_center(DOWN) + set_A.get_width() / 2 * UP vdots = VGroup([ Dot(interpolate(p0, p1, alpha)) for alpha in np.linspace(0, 1, dots_num) ]) subset = Rectangle(width=w2 - 1, height=0.7).move_to(set_PA) subset.save_state() p0 = subset.get_edge_center(LEFT) + RIGHT p1 = subset.get_edge_center(RIGHT) + LEFT hdots = VGroup([ Dot(interpolate(p0, p1, alpha)) for alpha in np.linspace(0, 1, dots_num) ]) for i, dot in enumerate(vdots): dot.index = i dot.set_color(random.choice([RED, GREEN])) green_dots = filter(lambda dot: dot.color == Color(GREEN), vdots) red_dots = filter(lambda dot: dot.color == Color(RED), vdots) self.add(set_A, set_PA, set_A_label, set_PA_label) dots_to_show = VGroup(vdots.submobjects) cur_dot = green_dots[2] dots_to_show.remove(cur_dot) subset.move_to(cur_dot, coor_mask=Y_MASK) x_var = TexMobject('x').move_to(cur_dot) line = Line(x_var, subset, buff=0.2) #self.wait_to(6) self.play(GrowFromCenter(x_var)) #self.wait_to(9) self.play(ShowCreation(line), FadeIn(subset)) x_inside = x_var.copy().move_to(hdots[cur_dot.index]) x_inside.move_to(subset, coor_mask=Y_MASK) x_inside.save_state() x_inside.shift(UP) x_inside.set_fill(opacity=0) #self.wait_to(11) self.play(x_inside.restore) #self.wait_to(14) self.dither() self.play(FadeOut(VGroup(line, subset, x_inside))) self.play(ReplacementTransform(x_var, cur_dot)) cur_dot = red_dots[2] dots_to_show.remove(cur_dot) subset.move_to(cur_dot, coor_mask=Y_MASK) x_var = TexMobject('x').move_to(cur_dot) line = Line(x_var, subset, buff=0.2) self.play(GrowFromCenter(x_var)) self.play(ShowCreation(line), FadeIn(subset)) x_inside = x_var.copy().move_to(hdots[cur_dot.index]) x_inside.move_to(subset, coor_mask=Y_MASK) x_inside.shift(UP) x_inside.save_state() x_inside.shift(DOWN) x_inside.set_fill(opacity=0) self.play(x_inside.restore) #self.wait_to(20) self.dither() self.play(FadeOut(VGroup(line, subset, x_inside))) self.play(ReplacementTransform(x_var, cur_dot)) self.play(ShowCreation(dots_to_show)) subset.restore() red_hdots = VGroup([hdots[dot.index] for dot in red_dots]).highlight(RED) #self.wait_to(24) self.dither() self.play( ReplacementTransform(VGroup(list(red_dots)).copy(), red_hdots), ) self.play(ShowCreation(subset)) #self.wait_to(32.5) subset_g = VGroup(subset, hdots) visible_g = VGroup(subset, red_hdots) cur_dot = green_dots[2] visible_g.save_state() subset_g.move_to(cur_dot, coor_mask=Y_MASK) line = Line(cur_dot, subset, buff=0.2) self.play( MoveFromSaved(visible_g), ShowCreation(line), ) cur_hdot = hdots[cur_dot.index] cur_hdot.highlight(GREEN) self.dither() self.add(cur_hdot) self.dither(0.3) self.remove(cur_hdot) self.dither(0.2) self.add(cur_hdot) self.dither() self.remove(cur_hdot) ori_line = line cur_dot = red_dots[2] visible_g.save_state() subset_g.move_to(cur_dot, coor_mask=Y_MASK) line = Line(cur_dot, subset, buff=0.2) #self.wait_to(36) self.dither(2) self.play( FadeOut(ori_line), MoveFromSaved(visible_g), ShowCreation(line), ) cur_hdot = hdots[cur_dot.index] cur_hdot.highlight(YELLOW) self.dither(0.3) cur_hdot.highlight(RED) self.dither(0.2) cur_hdot.highlight(YELLOW) self.dither() #self.wait_to(39.5) cur_hdot.highlight(RED) visible_g.save_state() subset_g.move_to(ORIGIN, coor_mask=Y_MASK) self.play(FadeOut(line), MoveFromSaved(visible_g)) #self.wait_to(53.7) cur_dot = vdots[-3] subset2 = subset.copy().move_to(cur_dot, coor_mask=Y_MASK) line = Line(cur_dot, subset2, buff=0.2) self.play(ShowCreation(line)) self.dither() #self.wait_to(57) self.play(Uncreate(line)) #self.wait_to(59.5) self.play(ReplacementTransform(cur_dot.copy(), subset2)) #self.wait_to(60+11) title = TextMobject("Russell's paradox").next_to(subset, UP) self.play(FadeIn(title, submobject_mode="lagged_start")) #self.wait_to(60+20) self.dither(2) title.save_state() title.center() title.to_edge(UP) self.play( FadeOut( VGroup( set_A, set_A_label, set_PA, set_PA_label, vdots, visible_g, subset2, )), MoveFromSaved(title), )
def house_example(self, starter_mobject, title): house = SVGMobject("house") house.set_stroke(width = 0) house.set_fill(BLUE_C, opacity = 1) house.scale_to_fit_height(3) house.center() square_footage_words = TextMobject("Square footage:") price_words = TextMobject("Price: ") square_footage = TexMobject("2{,}600\\text{ ft}^2") price = TextMobject("\\$300{,}000") house.to_edge(LEFT).shift(UP) square_footage_words.next_to(house, RIGHT) square_footage_words.shift(0.5*UP) square_footage_words.highlight(RED) price_words.next_to(square_footage_words, DOWN, aligned_edge = LEFT) price_words.highlight(GREEN) square_footage.next_to(square_footage_words) square_footage.highlight(RED) price.next_to(price_words) price.highlight(GREEN) vector = Matrix([square_footage.copy(), price.copy()]) vector.next_to(house, RIGHT).shift(0.25*UP) new_square_footage, new_price = vector.get_mob_matrix().flatten() not_equals = TexMobject("\\ne") not_equals.next_to(vector) alt_vector = Matrix([ TextMobject("300{,}000\\text{ ft}^2").highlight(RED), TextMobject("\\$2{,}600").highlight(GREEN) ]) alt_vector.next_to(not_equals) brace = Brace(vector, RIGHT) two_dimensional = TextMobject("2 dimensional") two_dimensional.next_to(brace) brackets = vector.get_brackets() self.play(Transform(starter_mobject, house)) self.remove(starter_mobject) self.add(house) self.add(square_footage_words) self.play(Write(square_footage, run_time = 2)) self.add(price_words) self.play(Write(price, run_time = 2)) self.dither() self.play( FadeOut(square_footage_words), FadeOut(price_words), Transform(square_footage, new_square_footage), Transform(price, new_price), Write(brackets), run_time = 1 ) self.remove(square_footage_words, price_words) self.dither() self.play( Write(not_equals), Write(alt_vector), run_time = 1 ) self.dither() self.play(FadeOut(not_equals), FadeOut(alt_vector)) self.remove(not_equals, alt_vector) self.dither() self.play( GrowFromCenter(brace), Write(two_dimensional), run_time = 1 ) self.dither() everything = VMobject( house, square_footage, price, brackets, brace, two_dimensional, title ) self.play(ApplyMethod(everything.shift, 2*SPACE_WIDTH*LEFT)) self.remove(everything)
def house_example(self, starter_mobject, title): house = SVGMobject("house") house.set_stroke(width=0) house.set_fill(BLUE_C, opacity=1) house.scale_to_fit_height(3) house.center() square_footage_words = TextMobject("Square footage:") price_words = TextMobject("Price: ") square_footage = TexMobject("2{,}600\\text{ ft}^2") price = TextMobject("\\$300{,}000") house.to_edge(LEFT).shift(UP) square_footage_words.next_to(house, RIGHT) square_footage_words.shift(0.5 * UP) square_footage_words.highlight(RED) price_words.next_to(square_footage_words, DOWN, aligned_edge=LEFT) price_words.highlight(GREEN) square_footage.next_to(square_footage_words) square_footage.highlight(RED) price.next_to(price_words) price.highlight(GREEN) vector = Matrix([square_footage.copy(), price.copy()]) vector.next_to(house, RIGHT).shift(0.25 * UP) new_square_footage, new_price = vector.get_mob_matrix().flatten() not_equals = TexMobject("\\ne") not_equals.next_to(vector) alt_vector = Matrix([ TextMobject("300{,}000\\text{ ft}^2").highlight(RED), TextMobject("\\$2{,}600").highlight(GREEN) ]) alt_vector.next_to(not_equals) brace = Brace(vector, RIGHT) two_dimensional = TextMobject("2 dimensional") two_dimensional.next_to(brace) brackets = vector.get_brackets() self.play(Transform(starter_mobject, house)) self.remove(starter_mobject) self.add(house) self.add(square_footage_words) self.play(Write(square_footage, run_time=2)) self.add(price_words) self.play(Write(price, run_time=2)) self.dither() self.play(FadeOut(square_footage_words), FadeOut(price_words), Transform(square_footage, new_square_footage), Transform(price, new_price), Write(brackets), run_time=1) self.remove(square_footage_words, price_words) self.dither() self.play(Write(not_equals), Write(alt_vector), run_time=1) self.dither() self.play(FadeOut(not_equals), FadeOut(alt_vector)) self.remove(not_equals, alt_vector) self.dither() self.play(GrowFromCenter(brace), Write(two_dimensional), run_time=1) self.dither() everything = VMobject(house, square_footage, price, brackets, brace, two_dimensional, title) self.play(ApplyMethod(everything.shift, 2 * SPACE_WIDTH * LEFT)) self.remove(everything)
def work_out_square_algebraically(self): rect = Rectangle(height=3.5, width=6.5, stroke_width=0, fill_color=BLACK, fill_opacity=0.8) rect.to_corner(UP + LEFT, buff=0) top_line = TexMobject("(2+i)", "(2+i)") top_line.next_to(rect.get_top(), DOWN) second_line = TexMobject("2^2 + 2i + 2i + i^2") second_line.next_to(top_line, DOWN, MED_LARGE_BUFF) final_line = TexMobject("3 + 4i") final_line.next_to(second_line, DOWN, MED_LARGE_BUFF) result_dot = Dot(self.plane.coords_to_point(3, 4), color=MAROON_B, radius=self.dot_radius) self.play(FadeIn(rect), ReplacementTransform(VGroup(self.example_label[1].copy()), top_line), run_time=2) self.dither() #From top line to second line index_alignment_lists = [ [(0, 1, 0), (1, 1, 1)], [(0, 2, 2), (0, 1, 3), (1, 3, 4)], [(0, 2, 5), (1, 1, 6), (0, 3, 7)], [(0, 2, 8), (0, 3, 9), (1, 3, 10)], ] for index_alignment in index_alignment_lists: self.play(*[ ReplacementTransform( top_line[i][j].copy(), second_line[k], ) for i, j, k in index_alignment ]) self.dither(2) #From second line to final line index_alignment_lists = [ [(0, 0), (1, 0), (9, 0), (10, 0)], [(2, 1), (3, 2), (4, 3), (6, 2), (7, 3)], ] for index_alignment in index_alignment_lists: self.play(*[ ReplacementTransform( second_line[i].copy(), final_line[j], run_time=1.5) for i, j in index_alignment ]) self.dither() #Move result to appropriate place result_label = final_line.copy() result_label.add_background_rectangle() self.play( result_label.next_to, result_dot, UP + RIGHT, SMALL_BUFF, Animation(final_line), run_time=2, ) self.play( DrawBorderThenFill(result_dot, stroke_width=4, stroke_color=PINK)) self.dither(2)
def show_equation(self): equation = TexMobject([ "\\left(\\dfrac{1}{\\phantom{v_air}}\\right)", "\\sin(\\theta_1)", "=", "\\left(\\dfrac{1}{\\phantom{v_water}}\\right)", "\\sin(\\theta_2)" ]) equation.to_corner(UP+RIGHT) frac1, sin1, equals, frac2, sin2 = equation.split() v_air, v_water = [ TexMobject("v_{\\text{%s}}"%s, size = "\\Large") for s in "air", "water" ] v_air.next_to(Point(frac1.get_center()), DOWN) v_water.next_to(Point(frac2.get_center()), DOWN) frac1.add(v_air) frac2.add(v_water) f1, f2 = [ TexMobject("F_%d"%d, size = "\\Large") for d in 1, 2 ] f1.next_to(sin1, LEFT) f2.next_to(equals, RIGHT) sin2_start = sin2.copy().next_to(f2, RIGHT) bar1 = TexMobject("\\dfrac{\\qquad}{\\qquad}") bar2 = bar1.copy() bar1.next_to(sin1, DOWN) bar2.next_to(sin2, DOWN) v_air_copy = v_air.copy().next_to(bar1, DOWN) v_water_copy = v_water.copy().next_to(bar2, DOWN) bars = Mobject(bar1, bar2) new_eq = equals.copy().center().shift(bars.get_center()) snells = TextMobject("Snell's Law") snells.highlight(YELLOW) snells.shift(new_eq.get_center()[0]*RIGHT) snells.shift(UP) anims = [] for mob in f1, sin1, equals, f2, sin2_start: anims.append(ShimmerIn(mob)) self.play(*anims) self.dither() for f, frac in (f1, frac1), (f2, frac2): target = frac.copy().ingest_submobjects() also = [] if f is f2: also.append(Transform(sin2_start, sin2)) sin2 = sin2_start self.play(Transform(f, target), *also) self.remove(f) self.add(frac) self.dither() self.play( FadeOut(frac1), FadeOut(frac2), Transform(v_air, v_air_copy), Transform(v_water, v_water_copy), ShowCreation(bars), Transform(equals, new_eq) ) self.dither() frac1 = Mobject(sin1, bar1, v_air) frac2 = Mobject(sin2, bar2, v_water) for frac, vect in (frac1, LEFT), (frac2, RIGHT): self.play(ApplyMethod( frac.next_to, equals, vect )) self.dither() self.play(ShimmerIn(snells)) self.dither()