mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Changes to basel, and replication of the file
This commit is contained in:
parent
99783d77a0
commit
671b6e6fe8
2 changed files with 3299 additions and 89 deletions
|
@ -247,9 +247,10 @@ class ThinkAboutPondScene(PiCreatureScene):
|
|||
class IntroScene(PiCreatureScene):
|
||||
|
||||
CONFIG = {
|
||||
"rect_height" : 0.2,
|
||||
"rect_height" : 0.1,
|
||||
"duration" : 1.0,
|
||||
"eq_spacing" : 3 * MED_LARGE_BUFF
|
||||
"eq_spacing" : 3 * MED_LARGE_BUFF,
|
||||
"n_rects_to_show" : 30,
|
||||
}
|
||||
|
||||
def construct(self):
|
||||
|
@ -257,12 +258,12 @@ class IntroScene(PiCreatureScene):
|
|||
randy.scale(0.7).to_corner(DOWN+RIGHT)
|
||||
|
||||
self.build_up_euler_sum()
|
||||
self.show_pi_answer()
|
||||
self.other_pi_formulas()
|
||||
self.refocus_on_euler_sum()
|
||||
|
||||
self.show_history()
|
||||
# self.other_pi_formulas()
|
||||
# self.refocus_on_euler_sum()
|
||||
|
||||
def build_up_euler_sum(self):
|
||||
morty = self.pi_creature
|
||||
euler_sum = self.euler_sum = TexMobject(
|
||||
"1", "+",
|
||||
"{1 \\over 4}", "+",
|
||||
|
@ -273,24 +274,26 @@ class IntroScene(PiCreatureScene):
|
|||
arg_separator = " \\, "
|
||||
)
|
||||
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.shift(2*LEFT)
|
||||
|
||||
terms = [1./n**2 for n in range(1,100)]
|
||||
partial_results_values = np.cumsum(terms)
|
||||
max_n = self.n_rects_to_show
|
||||
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]))
|
||||
|
||||
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)
|
||||
partial_sum_decimal = self.partial_sum_decimal = DecimalNumber(
|
||||
series_terms[1],
|
||||
num_decimal_points = 2
|
||||
)
|
||||
partial_sum_decimal.next_to(equals_sign, RIGHT)
|
||||
|
||||
## Number line
|
||||
|
||||
self.number_line = NumberLine(
|
||||
number_line = self.number_line = NumberLine(
|
||||
x_min = 0,
|
||||
color = WHITE,
|
||||
number_at_center = 1,
|
||||
|
@ -301,105 +304,214 @@ class IntroScene(PiCreatureScene):
|
|||
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()
|
||||
number_line.add_numbers()
|
||||
number_line.to_edge(LEFT)
|
||||
number_line.shift(MED_LARGE_BUFF*UP)
|
||||
|
||||
# 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)
|
||||
rects = self.rects = VGroup()
|
||||
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):
|
||||
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,
|
||||
for i, t1, t2 in zip(it.count(1), [0]+series_terms, series_terms):
|
||||
color = slab_colors.next()
|
||||
line = Line(*map(number_line.number_to_point, [t1, t2]))
|
||||
rect = Rectangle(
|
||||
stroke_width = 0,
|
||||
fill_opacity = 1,
|
||||
fill_color = color
|
||||
)
|
||||
rect.stretch_to_fit_width(line.get_width())
|
||||
rect.match_width(line)
|
||||
rect.stretch_to_fit_height(self.rect_height)
|
||||
rect.move_to(line)
|
||||
|
||||
self.rects.add(rect)
|
||||
lines.add(line)
|
||||
if i <= 5:
|
||||
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)
|
||||
|
||||
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)
|
||||
)
|
||||
|
||||
|
||||
##
|
||||
|
||||
|
||||
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)
|
||||
term_mobject = term_mobjects[i-1]
|
||||
rect_anim = GrowFromPoint(rect, term_mobject.get_center())
|
||||
rect_label_anim = ReplacementTransform(
|
||||
term_mobject.copy(), rect_label
|
||||
)
|
||||
|
||||
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),
|
||||
rect_label = VectorizedPoint()
|
||||
rect_anim = GrowFromPoint(rect, rect.get_left())
|
||||
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(
|
||||
self.partial_sum_decimal,
|
||||
partial_results_values[i+1],
|
||||
run_time = self.duration,
|
||||
partial_sum_decimal,
|
||||
series_terms[i+1],
|
||||
run_time = 1,
|
||||
num_decimal_points = 6,
|
||||
show_ellipsis = True,
|
||||
position_update_func = lambda m: m.next_to(equals_sign, RIGHT)
|
||||
)
|
||||
)
|
||||
|
||||
self.wait()
|
||||
]
|
||||
self.play(*anims)
|
||||
|
||||
self.q_marks = TextMobject("???").highlight(LIGHT_COLOR)
|
||||
self.q_marks.move_to(self.partial_sum_decimal)
|
||||
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)
|
||||
|
||||
brace = self.brace = Brace(partial_sum_decimal, DOWN)
|
||||
q_marks = self.q_marks = TextMobject("???")
|
||||
q_marks.next_to(brace, DOWN)
|
||||
q_marks.highlight(LIGHT_COLOR)
|
||||
|
||||
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)
|
||||
GrowFromCenter(brace),
|
||||
Write(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)
|
||||
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))
|
||||
pietro_words = TextMobject("Challenge posed by \\\\ Pietro Mengoli in 1644")
|
||||
pietro_words.scale(0.75)
|
||||
pietro_words.next_to(pietro, DOWN)
|
||||
pietro.add(pietro_words)
|
||||
|
||||
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):
|
||||
|
||||
self.play(
|
||||
FadeOut(self.rects),
|
||||
FadeOut(self.number_line_labels),
|
||||
FadeOut(self.number_line)
|
||||
)
|
||||
|
||||
|
@ -468,6 +580,195 @@ class IntroScene(PiCreatureScene):
|
|||
|
||||
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):
|
||||
|
||||
def construct(self):
|
||||
|
|
2909
active_projects/basel2.py
Normal file
2909
active_projects/basel2.py
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue