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 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.wait() 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.wait() brace = Brace(d_sqrt, DOWN) constant = TextMobject("Constant") constant.next_to(brace, DOWN) self.play( GrowFromCenter(brace), ShimmerIn(constant) )
def get_expression(self, base): expression = TexMobject( "{d(", "%d^"%base, "t", ")", "\\over \\,", "dt}", "=", "%d^"%base, "t", "(%.4f\\dots)"%np.log(base), ) expression.highlight_by_tex("t", YELLOW) expression.highlight_by_tex("dt", GREEN) expression.highlight_by_tex("\\dots", BLUE) brace = Brace(expression.get_part_by_tex("\\dots"), UP) brace_text = brace.get_text("$\\ln(%d)$"%base) for mob in brace, brace_text: mob.set_fill(opacity = 0) expression.add(brace, brace_text) return expression
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 get_expression(self, base): expression = TexMobject( "{d(", "%d^" % base, "t", ")", "\\over \\,", "dt}", "=", "%d^" % base, "t", "(%.4f\\dots)" % np.log(base), ) expression.highlight_by_tex("t", YELLOW) expression.highlight_by_tex("dt", GREEN) expression.highlight_by_tex("\\dots", BLUE) brace = Brace(expression.get_part_by_tex("\\dots"), UP) brace_text = brace.get_text("$\\ln(%d)$" % base) for mob in brace, brace_text: mob.set_fill(opacity=0) expression.add(brace, brace_text) return expression
def construct(self): scale_factor = 0.7 sick = "\\text{sick}" positive = "\\text{positive}" formula = TexMobject("P(", sick, "\\,|\\,", positive, ")", "=", "{\\quad P(", sick, "\\text{ and }", positive, ") \\quad", "\\over", "P(", positive, ")}", "=", "{1/1{,}000", "\\over", "1/1{,}000", "+", "(999/1{,}000)(0.01)}") formula.scale(scale_factor) formula.next_to(self.pi_creatures, UP, LARGE_BUFF) formula.shift_onto_screen(buff=MED_LARGE_BUFF) equals_group = formula.get_parts_by_tex("=") equals_indices = [ formula.index_of_part(equals) for equals in equals_group ] lhs = VGroup(*formula[:equals_indices[0]]) initial_formula = VGroup(*formula[:equals_indices[1]]) initial_formula.save_state() initial_formula.shift(3 * RIGHT) over = formula.get_part_by_tex("\\over") num_start_index = equals_indices[0] + 1 num_end_index = formula.index_of_part(over) numerator = VGroup(*formula[num_start_index:num_end_index]) numerator_rect = SurroundingRectangle(numerator) alt_numerator = TexMobject("P(", sick, ")", "P(", positive, "\\,|\\,", sick, ")") alt_numerator.scale(scale_factor) alt_numerator.move_to(numerator) number_fraction = VGroup(*formula[equals_indices[-1]:]) rhs = TexMobject("\\approx 0.09") rhs.scale(scale_factor) rhs.move_to(equals_group[-1], LEFT) rhs.highlight(YELLOW) for mob in formula, alt_numerator: mob.highlight_by_tex(sick, SICKLY_GREEN) mob.highlight_by_tex(positive, YELLOW) #Ask question self.student_says("What does the \\\\ formula look like here?") self.play(self.teacher.change, "happy") self.dither() self.play( Write(lhs), RemovePiCreatureBubble( self.students[1], target_mode="pondering", ), self.teacher.change, "raise_right_hand", self.students[0].change, "pondering", self.students[2].change, "pondering", ) self.dither() #Show initial formula lhs_copy = lhs.copy() self.play( LaggedStart(FadeIn, initial_formula, lag_ratio=0.7), Animation(lhs_copy, remover=True), ) self.dither(2) self.play(ShowCreation(numerator_rect)) self.play(FadeOut(numerator_rect)) self.dither() self.play(Transform(numerator, alt_numerator)) initial_formula.add(*numerator) formula.add(*numerator) self.dither(3) #Show number_fraction self.play(initial_formula.move_to, initial_formula.saved_state, FadeIn(VGroup(*number_fraction[:3]))) self.dither(2) self.play( LaggedStart(FadeIn, VGroup(*number_fraction[3:]), run_time=3, lag_ratio=0.7)) self.dither(2) #Show rhs self.play(formula.shift, UP) self.play(Write(rhs)) self.change_student_modes(*["happy"] * 3) self.look_at(rhs) self.dither(2)
class IntroScene(PiCreatureScene): CONFIG = { "rect_height": 0.2, "duration": 1.0, "eq_spacing": 3 * MED_LARGE_BUFF } def construct(self): randy = self.get_primary_pi_creature() randy.scale(0.7).to_corner(DOWN + RIGHT) self.build_up_euler_sum() self.build_up_sum_on_number_line() self.show_pi_answer() self.other_pi_formulas() self.refocus_on_euler_sum() def build_up_euler_sum(self): self.euler_sum = TexMobject("1", "+", "{1 \\over 4}", "+", "{1 \\over 9}", "+", "{1 \\over 16}", "+", "{1 \\over 25}", "+", "\\cdots", "=", arg_separator=" \\, ") self.euler_sum.to_edge(UP) self.euler_sum.shift(2 * LEFT) terms = [1. / n**2 for n in range(1, 6)] partial_results_values = np.cumsum(terms) self.play(FadeIn(self.euler_sum[0], run_time=self.duration)) equals_sign = self.euler_sum.get_part_by_tex("=") self.partial_sum_decimal = DecimalNumber(partial_results_values[1], num_decimal_points=2) self.partial_sum_decimal.next_to(equals_sign, RIGHT) for i in range(4): FadeIn(self.partial_sum_decimal, run_time=self.duration) if i == 0: self.play( FadeIn(self.euler_sum[1], run_time=self.duration), FadeIn(self.euler_sum[2], run_time=self.duration), FadeIn(equals_sign, run_time=self.duration), FadeIn(self.partial_sum_decimal, run_time=self.duration)) else: self.play( FadeIn(self.euler_sum[2 * i + 1], run_time=self.duration), FadeIn(self.euler_sum[2 * i + 2], run_time=self.duration), ChangeDecimalToValue(self.partial_sum_decimal, partial_results_values[i + 1], run_time=self.duration, num_decimal_points=6, show_ellipsis=True, position_update_func=lambda m: m. next_to(equals_sign, RIGHT))) self.wait() self.q_marks = TextMobject("???").highlight(LIGHT_COLOR) self.q_marks.move_to(self.partial_sum_decimal) self.play( FadeIn(self.euler_sum[-3], run_time=self.duration), # + FadeIn(self.euler_sum[-2], run_time=self.duration), # ... ReplacementTransform(self.partial_sum_decimal, self.q_marks)) def build_up_sum_on_number_line(self): self.number_line = NumberLine( x_min=0, color=WHITE, number_at_center=1, stroke_width=1, numbers_with_elongated_ticks=[0, 1, 2, 3], numbers_to_show=np.arange(0, 5), unit_size=5, tick_frequency=0.2, line_to_number_buff=MED_LARGE_BUFF) self.number_line_labels = self.number_line.get_number_mobjects() self.add(self.number_line, self.number_line_labels) self.wait() # create slabs for series terms max_n = 10 terms = [0] + [1. / (n**2) for n in range(1, max_n + 1)] series_terms = np.cumsum(terms) lines = VGroup() self.rects = VGroup() slab_colors = [YELLOW, BLUE] * (max_n / 2) for t1, t2, color in zip(series_terms, series_terms[1:], slab_colors): line = Line(*map(self.number_line.number_to_point, [t1, t2])) rect = Rectangle() rect.stroke_width = 0 rect.fill_opacity = 1 rect.highlight(color) rect.stretch_to_fit_height(self.rect_height, ) rect.stretch_to_fit_width(line.get_width()) rect.move_to(line) self.rects.add(rect) lines.add(line) #self.rects.radial_gradient_highlight(ORIGIN, 5, YELLOW, BLUE) for i in range(5): self.play( GrowFromPoint(self.rects[i], self.euler_sum[2 * i].get_center(), run_time=self.duration)) for i in range(5, max_n): self.play( GrowFromPoint(self.rects[i], self.euler_sum[10].get_center(), run_time=self.duration)) def show_pi_answer(self): self.pi_answer = TexMobject("{\\pi^2 \\over 6}").highlight(YELLOW) self.pi_answer.move_to(self.partial_sum_decimal) self.pi_answer.next_to(self.euler_sum[-1], RIGHT, submobject_to_align=self.pi_answer[-2]) self.play(ReplacementTransform(self.q_marks, self.pi_answer)) def other_pi_formulas(self): self.play(FadeOut(self.rects), FadeOut(self.number_line_labels), FadeOut(self.number_line)) self.leibniz_sum = TexMobject( "1-{1\\over 3}+{1\\over 5}-{1\\over 7}+{1\\over 9}-\\cdots", "=", "{\\pi \\over 4}") self.wallis_product = TexMobject( "{2\\over 1} \\cdot {2\\over 3} \\cdot {4\\over 3} \\cdot {4\\over 5}" + "\\cdot {6\\over 5} \\cdot {6\\over 7} \\cdots", "=", "{\\pi \\over 2}") self.leibniz_sum.next_to( self.euler_sum.get_part_by_tex("="), DOWN, buff=self.eq_spacing, submobject_to_align=self.leibniz_sum.get_part_by_tex("=")) self.wallis_product.next_to( self.leibniz_sum.get_part_by_tex("="), DOWN, buff=self.eq_spacing, submobject_to_align=self.wallis_product.get_part_by_tex("=")) self.play(Write(self.leibniz_sum)) self.play(Write(self.wallis_product)) def refocus_on_euler_sum(self): self.euler_sum.add(self.pi_answer) self.play( FadeOut(self.leibniz_sum), FadeOut(self.wallis_product), ApplyMethod(self.euler_sum.shift, ORIGIN + 2 * UP - self.euler_sum.get_center())) # focus on pi squared pi_squared = self.euler_sum.get_part_by_tex("\\pi")[-3] self.play(ScaleInPlace(pi_squared, 2, rate_func=wiggle)) # Morty thinks of a circle q_circle = Circle(stroke_color=YELLOW, fill_color=YELLOW, fill_opacity=0.5, radius=0.4, stroke_width=10.0) q_mark = TexMobject("?") q_mark.next_to(q_circle) thought = Group(q_circle, q_mark) q_mark.scale_to_fit_height(0.8 * q_circle.get_height()) self.pi_creature_thinks(thought, target_mode="confused", bubble_kwargs={ "height": 2, "width": 3 }) self.wait()