Changes to basel, and replication of the file

This commit is contained in:
Grant Sanderson 2018-02-26 16:13:28 -08:00
parent 99783d77a0
commit 671b6e6fe8
2 changed files with 3299 additions and 89 deletions

View file

@ -247,9 +247,10 @@ class ThinkAboutPondScene(PiCreatureScene):
class IntroScene(PiCreatureScene): class IntroScene(PiCreatureScene):
CONFIG = { CONFIG = {
"rect_height" : 0.2, "rect_height" : 0.1,
"duration" : 1.0, "duration" : 1.0,
"eq_spacing" : 3 * MED_LARGE_BUFF "eq_spacing" : 3 * MED_LARGE_BUFF,
"n_rects_to_show" : 30,
} }
def construct(self): def construct(self):
@ -257,12 +258,12 @@ class IntroScene(PiCreatureScene):
randy.scale(0.7).to_corner(DOWN+RIGHT) randy.scale(0.7).to_corner(DOWN+RIGHT)
self.build_up_euler_sum() self.build_up_euler_sum()
self.show_pi_answer() self.show_history()
self.other_pi_formulas() # self.other_pi_formulas()
self.refocus_on_euler_sum() # self.refocus_on_euler_sum()
def build_up_euler_sum(self): def build_up_euler_sum(self):
morty = self.pi_creature
euler_sum = self.euler_sum = TexMobject( euler_sum = self.euler_sum = TexMobject(
"1", "+", "1", "+",
"{1 \\over 4}", "+", "{1 \\over 4}", "+",
@ -273,24 +274,26 @@ class IntroScene(PiCreatureScene):
arg_separator = " \\, " arg_separator = " \\, "
) )
equals_sign = euler_sum.get_part_by_tex("=") equals_sign = euler_sum.get_part_by_tex("=")
plusses = euler_sum.get_parts_by_tex("+")
term_mobjects = euler_sum.get_parts_by_tex("1")
self.euler_sum.to_edge(UP) self.euler_sum.to_edge(UP)
self.euler_sum.shift(2*LEFT) self.euler_sum.shift(2*LEFT)
terms = [1./n**2 for n in range(1,100)] max_n = self.n_rects_to_show
partial_results_values = np.cumsum(terms) terms = [1./(n**2) for n in range(1, max_n + 1)]
series_terms = list(np.cumsum(terms))
series_terms.append(np.pi**2/6) ##Just force this up there
self.play(FadeIn(euler_sum[0])) partial_sum_decimal = self.partial_sum_decimal = DecimalNumber(
series_terms[1],
equals_sign = self.euler_sum.get_part_by_tex("=") num_decimal_points = 2
)
self.partial_sum_decimal = DecimalNumber(partial_results_values[1], partial_sum_decimal.next_to(equals_sign, RIGHT)
num_decimal_points = 2)
self.partial_sum_decimal.next_to(equals_sign, RIGHT)
## Number line ## Number line
self.number_line = NumberLine( number_line = self.number_line = NumberLine(
x_min = 0, x_min = 0,
color = WHITE, color = WHITE,
number_at_center = 1, number_at_center = 1,
@ -301,105 +304,214 @@ class IntroScene(PiCreatureScene):
tick_frequency = 0.2, tick_frequency = 0.2,
line_to_number_buff = MED_LARGE_BUFF line_to_number_buff = MED_LARGE_BUFF
) )
number_line.add_numbers()
self.number_line_labels = self.number_line.get_number_mobjects() number_line.to_edge(LEFT)
self.add(self.number_line,self.number_line_labels) number_line.shift(MED_LARGE_BUFF*UP)
self.wait()
# create slabs for series terms # 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() lines = VGroup()
self.rects = VGroup() rects = self.rects = VGroup()
slab_colors = [YELLOW, BLUE] * (max_n / 2) rect_labels = VGroup()
slab_colors = it.cycle([YELLOW, BLUE])
rect_anims = []
rect_label_anims = []
for t1, t2, color in zip(series_terms, series_terms[1:], slab_colors): for i, t1, t2 in zip(it.count(1), [0]+series_terms, series_terms):
line = Line(*map(self.number_line.number_to_point, [t1, t2])) color = slab_colors.next()
rect = Rectangle() line = Line(*map(number_line.number_to_point, [t1, t2]))
rect.stroke_width = 0 rect = Rectangle(
rect.fill_opacity = 1 stroke_width = 0,
rect.highlight(color) fill_opacity = 1,
rect.stretch_to_fit_height( fill_color = color
self.rect_height,
) )
rect.stretch_to_fit_width(line.get_width()) rect.match_width(line)
rect.stretch_to_fit_height(self.rect_height)
rect.move_to(line) rect.move_to(line)
self.rects.add(rect) if i <= 5:
lines.add(line) if i == 1:
rect_label = TexMobject("1")
else:
rect_label = TexMobject("\\frac{1}{%d}"%(i**2))
rect_label.scale(0.75)
max_width = 0.7*rect.get_width()
if rect_label.get_width() > max_width:
rect_label.scale_to_fit_width(max_width)
rect_label.next_to(rect, UP, MED_SMALL_BUFF/(i+1))
#self.rects.radial_gradient_highlight(ORIGIN, 5, YELLOW, BLUE) term_mobject = term_mobjects[i-1]
rect_anim = GrowFromPoint(rect, term_mobject.get_center())
for i in range(5): rect_label_anim = ReplacementTransform(
self.play( term_mobject.copy(), rect_label
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)
)
##
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: else:
self.play( rect_label = VectorizedPoint()
FadeIn(self.euler_sum[2*i+1], run_time = self.duration), rect_anim = GrowFromPoint(rect, rect.get_left())
FadeIn(self.euler_sum[2*i+2], run_time = self.duration), rect_label_anim = FadeIn(rect_label)
rects.add(rect)
rect_labels.add(rect_label)
rect_anims.append(rect_anim)
rect_label_anims.append(rect_label_anim)
lines.add(line)
dots = TexMobject("\\dots").scale(0.5)
last_rect = rect_anims[-1].target_mobject
dots.scale_to_fit_width(0.9*last_rect.get_width())
dots.move_to(last_rect, UP+RIGHT)
rects.submobjects[-1] = dots
rect_anims[-1] = FadeIn(dots)
self.add(number_line)
self.play(FadeIn(euler_sum[0]))
self.play(
rect_anims[0],
rect_label_anims[0]
)
for i in range(4):
self.play(
FadeIn(term_mobjects[i+1]),
FadeIn(plusses[i]),
)
anims = [
rect_anims[i+1],
rect_label_anims[i+1],
]
if i == 0:
anims += [
FadeIn(equals_sign),
FadeIn(partial_sum_decimal)
]
elif i <= 5:
anims += [
ChangeDecimalToValue( ChangeDecimalToValue(
self.partial_sum_decimal, partial_sum_decimal,
partial_results_values[i+1], series_terms[i+1],
run_time = self.duration, run_time = 1,
num_decimal_points = 6, num_decimal_points = 6,
show_ellipsis = True,
position_update_func = lambda m: m.next_to(equals_sign, RIGHT) position_update_func = lambda m: m.next_to(equals_sign, RIGHT)
) )
) ]
self.play(*anims)
self.wait() for i in range(4, len(series_terms)-2):
anims = [
rect_anims[i+1],
ChangeDecimalToValue(
partial_sum_decimal,
series_terms[i+1],
num_decimal_points = 6,
),
]
if i == 5:
anims += [
FadeIn(euler_sum[-3]), # +
FadeIn(euler_sum[-2]), # ...
]
self.play(*anims, run_time = 2./i)
self.q_marks = TextMobject("???").highlight(LIGHT_COLOR) brace = self.brace = Brace(partial_sum_decimal, DOWN)
self.q_marks.move_to(self.partial_sum_decimal) q_marks = self.q_marks = TextMobject("???")
q_marks.next_to(brace, DOWN)
q_marks.highlight(LIGHT_COLOR)
self.play( self.play(
FadeIn(self.euler_sum[-3], run_time = self.duration), # + GrowFromCenter(brace),
FadeIn(self.euler_sum[-2], run_time = self.duration), # ... Write(q_marks),
ReplacementTransform(self.partial_sum_decimal, self.q_marks) ChangeDecimalToValue(
partial_sum_decimal,
series_terms[-1],
num_decimal_points = 6,
),
morty.change, "confused",
)
self.wait()
self.number_line_group = VGroup(
number_line, rects, rect_labels
) )
def show_pi_answer(self): def show_history(self):
# Pietro Mengoli in 1644
morty = self.pi_creature
pietro = ImageMobject("Pietro_Mengoli")
euler = ImageMobject("Euler")
self.pi_answer = TexMobject("{\\pi^2 \\over 6}").highlight(YELLOW) pietro_words = TextMobject("Challenge posed by \\\\ Pietro Mengoli in 1644")
self.pi_answer.move_to(self.partial_sum_decimal) pietro_words.scale(0.75)
self.pi_answer.next_to(self.euler_sum[-1], RIGHT, pietro_words.next_to(pietro, DOWN)
submobject_to_align = self.pi_answer[-2]) pietro.add(pietro_words)
self.play(ReplacementTransform(self.q_marks, self.pi_answer))
euler_words = TextMobject("Solved by Leonard \\\\ Euler in 1735")
euler_words.scale(0.75)
euler_words.next_to(euler, DOWN)
euler.add(euler_words)
pietro.next_to(SPACE_WIDTH*LEFT, LEFT)
euler.next_to(SPACE_WIDTH*RIGHT, RIGHT)
pi_answer = self.pi_answer = TexMobject("{\\pi^2 \\over 6}")
pi_answer.highlight(YELLOW)
pi_answer.move_to(self.partial_sum_decimal, LEFT)
equals_sign = TexMobject("=")
equals_sign.next_to(pi_answer, RIGHT)
pi_answer.shift(SMALL_BUFF*UP)
self.partial_sum_decimal.generate_target()
self.partial_sum_decimal.target.next_to(equals_sign, RIGHT)
pi = pi_answer[0]
pi_rect = SurroundingRectangle(pi, color = RED)
pi_rect.save_state()
pi_rect.scale_to_fit_height(SPACE_HEIGHT)
pi_rect.center()
pi_rect.set_stroke(width = 0)
squared = pi_answer[1]
squared_rect = SurroundingRectangle(squared, color = BLUE)
brace = Brace(
VGroup(self.euler_sum, self.partial_sum_decimal.target),
DOWN, buff = SMALL_BUFF
)
basel_text = brace.get_text("Basel problem", buff = SMALL_BUFF)
self.number_line_group.save_state()
self.play(
pietro.next_to, ORIGIN, LEFT, LARGE_BUFF,
self.number_line_group.next_to, SPACE_HEIGHT*DOWN, DOWN,
morty.change, "pondering",
)
self.wait(2)
self.play(euler.next_to, ORIGIN, RIGHT, LARGE_BUFF)
self.wait(2)
self.play(
ReplacementTransform(self.q_marks, pi_answer),
FadeIn(equals_sign),
FadeOut(self.brace),
MoveToTarget(self.partial_sum_decimal)
)
self.wait()
self.play(morty.change, "surprised")
self.play(pi_rect.restore)
self.wait()
self.play(Transform(pi_rect, squared_rect))
self.play(FadeOut(pi_rect))
self.play(morty.change, "hesitant")
self.wait(2)
self.play(
GrowFromCenter(brace),
euler.to_edge, DOWN,
pietro.to_edge, DOWN,
self.number_line_group.restore,
self.number_line_group.shift, LARGE_BUFF*RIGHT,
)
self.play(Write(basel_text))
self.play(morty.change, "happy")
self.wait(4)
def other_pi_formulas(self): def other_pi_formulas(self):
self.play( self.play(
FadeOut(self.rects), FadeOut(self.rects),
FadeOut(self.number_line_labels),
FadeOut(self.number_line) FadeOut(self.number_line)
) )
@ -468,6 +580,195 @@ class IntroScene(PiCreatureScene):
self.wait() self.wait()
class PiHidingWrapper(Scene):
def construct(self):
title = TextMobject("Pi hiding in prime regularities")
title.to_edge(UP)
screen = ScreenRectangle(height = 6)
screen.next_to(title, DOWN)
self.add(title)
self.play(ShowCreation(screen))
self.wait(2)
class MathematicalWebOfConnections(PiCreatureScene):
def construct(self):
self.complain_that_pi_is_not_about_circles()
self.show_other_pi_formulas()
self.question_fundamental()
self.draw_circle()
self.remove_all_but_basel_sum()
self.show_web_of_connections()
self.show_light()
def complain_that_pi_is_not_about_circles(self):
jerk, randy = self.pi_creatures
words = self.words = TextMobject(
"$\\pi$ is not",
"fundamentally \\\\",
"about circles"
)
words.highlight_by_tex("fundamentally", YELLOW)
self.play(PiCreatureSays(
jerk, words,
target_mode = "angry"
))
self.play(randy.change, "guilty")
self.wait(2)
def show_other_pi_formulas(self):
jerk, randy = self.pi_creatures
words = self.words
basel_sum = TexMobject(
"1 + {1 \\over 4} + {1 \\over 9} + {1 \\over 16} + \\cdots",
"=", "{\\pi^2 \\over 6}"
)
leibniz_sum = TexMobject(
"1-{1\\over 3}+{1\\over 5}-{1\\over 7}+{1\\over 9}-\\cdots",
"=", "{\\pi \\over 4}")
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}")
basel_sum.move_to(randy)
basel_sum.to_edge(UP)
basel_equals = basel_sum.get_part_by_tex("=")
formulas = VGroup(basel_sum, leibniz_sum, wallis_product)
formulas.scale(0.75)
formulas.arrange_submobjects(DOWN, buff = MED_LARGE_BUFF)
for formula in formulas:
basel_equals_x = basel_equals.get_center()[0]
formula_equals_x = formula.get_part_by_tex("=").get_center()[0]
formula.shift((basel_equals_x - formula_equals_x)*RIGHT)
formulas.move_to(randy)
formulas.to_edge(UP)
formulas.shift_onto_screen()
self.formulas = formulas
self.play(
jerk.change, "sassy",
randy.change, "raise_right_hand",
FadeOut(jerk.bubble),
words.next_to, jerk, UP,
FadeIn(basel_sum, submobject_mode = "lagged_start", run_time = 3)
)
for formula in formulas[1:]:
self.play(
FadeIn(
formula,
submobject_mode = "lagged_start",
run_time = 3
),
)
self.wait()
def question_fundamental(self):
jerk, randy = self.pi_creatures
words = self.words
fundamentally = words.get_part_by_tex("fundamentally")
words.remove(fundamentally)
self.play(
fundamentally.move_to, self.pi_creatures,
fundamentally.shift, UP,
FadeOut(words),
jerk.change, "pondering",
randy.change, "pondering",
)
self.wait()
question = TextMobject("Does this mean \\\\ anything?")
question.scale(0.8)
question.set_stroke(WHITE, 0.5)
question.next_to(fundamentally, DOWN, LARGE_BUFF)
arrow = Arrow(question, fundamentally)
arrow.highlight(WHITE)
self.play(
FadeIn(question),
GrowArrow(arrow)
)
self.wait()
fundamentally.add(question, arrow)
self.fundamentally = fundamentally
def draw_circle(self):
semi_circle = Arc(angle = np.pi, radius = 2)
radius = Line(ORIGIN, semi_circle.points[0])
radius.highlight(BLUE)
semi_circle.highlight(YELLOW)
VGroup(radius, semi_circle).move_to(
SPACE_WIDTH*LEFT/2 + SPACE_HEIGHT*UP/2,
)
decimal = DecimalNumber(0)
def decimal_position_update_func(decimal):
decimal.move_to(semi_circle.points[-1])
decimal.shift(0.3*radius.get_vector())
one = TexMobject("1")
one.next_to(radius, UP)
self.play(ShowCreation(radius), FadeIn(one))
self.play(
Rotate(radius, np.pi, about_point = radius.get_start()),
ShowCreation(semi_circle),
ChangeDecimalToValue(
decimal, np.pi,
position_update_func = decimal_position_update_func
),
MaintainPositionRelativeTo(one, radius),
run_time = 3,
)
self.wait(2)
self.circle_group = VGroup(semi_circle, radius, one, decimal)
def remove_all_but_basel_sum(self):
to_shift_down = VGroup(
self.circle_group, self.pi_creatures,
self.fundamentally, self.formulas[1:],
)
to_shift_down.generate_target()
for part in to_shift_down.target:
part.move_to(2*SPACE_HEIGHT*DOWN)
basel_sum = self.formulas[0]
self.play(
MoveToTarget(to_shift_down),
basel_sum.scale, 1.5,
basel_sum.move_to, 2*DOWN,
)
def show_web_of_connections(self):
pass
def show_light(self):
pass
###
def create_pi_creatures(self):
jerk = PiCreature(color = GREEN_D)
randy = Randolph().flip()
jerk.move_to(0.5*SPACE_WIDTH*LEFT).to_edge(DOWN)
randy.move_to(0.5*SPACE_WIDTH*RIGHT).to_edge(DOWN)
return VGroup(jerk, randy)
class FirstLighthouseScene(PiCreatureScene): class FirstLighthouseScene(PiCreatureScene):
def construct(self): def construct(self):

2909
active_projects/basel2.py Normal file

File diff suppressed because it is too large Load diff