mirror of
https://github.com/3b1b/manim.git
synced 2025-09-01 00:48:45 +00:00
First few scens of eoc1 remake
This commit is contained in:
parent
aa2b5b07cd
commit
ce93d88944
4 changed files with 603 additions and 31 deletions
|
@ -75,7 +75,7 @@ class Write(ShowCreation):
|
||||||
if "run_time" not in kwargs:
|
if "run_time" not in kwargs:
|
||||||
self.establish_run_time(mobject)
|
self.establish_run_time(mobject)
|
||||||
if "lag_factor" not in kwargs:
|
if "lag_factor" not in kwargs:
|
||||||
if len(mobject.family_members_with_points()) < 2:
|
if len(mobject.family_members_with_points()) < 3:
|
||||||
min_lag_factor = 1
|
min_lag_factor = 1
|
||||||
else:
|
else:
|
||||||
min_lag_factor = 2
|
min_lag_factor = 2
|
||||||
|
|
622
eoc/chapter1.py
622
eoc/chapter1.py
|
@ -32,16 +32,18 @@ class CircleScene(PiCreatureScene):
|
||||||
"radius" : 1.5,
|
"radius" : 1.5,
|
||||||
"stroke_color" : WHITE,
|
"stroke_color" : WHITE,
|
||||||
"fill_color" : BLUE_E,
|
"fill_color" : BLUE_E,
|
||||||
"fill_opacity" : 0.5,
|
"fill_opacity" : 0.75,
|
||||||
"radial_line_color" : MAROON_B,
|
"radial_line_color" : MAROON_B,
|
||||||
"outer_ring_color" : GREEN_E,
|
"outer_ring_color" : GREEN_E,
|
||||||
|
"ring_colors" : [BLUE, GREEN],
|
||||||
"dR" : 0.1,
|
"dR" : 0.1,
|
||||||
"dR_color" : YELLOW,
|
"dR_color" : YELLOW,
|
||||||
"unwrapped_tip" : ORIGIN,
|
"unwrapped_tip" : ORIGIN,
|
||||||
"include_pi_creature" : False,
|
"include_pi_creature" : False,
|
||||||
"circle_corner" : UP+LEFT
|
"circle_corner" : UP+LEFT,
|
||||||
}
|
}
|
||||||
def setup(self):
|
def setup(self):
|
||||||
|
PiCreatureScene.setup(self)
|
||||||
self.circle = Circle(
|
self.circle = Circle(
|
||||||
radius = self.radius,
|
radius = self.radius,
|
||||||
stroke_color = self.stroke_color,
|
stroke_color = self.stroke_color,
|
||||||
|
@ -57,19 +59,13 @@ class CircleScene(PiCreatureScene):
|
||||||
self.radius_brace = Brace(self.radius_line, buff = SMALL_BUFF)
|
self.radius_brace = Brace(self.radius_line, buff = SMALL_BUFF)
|
||||||
self.radius_label = self.radius_brace.get_text("$R$", buff = SMALL_BUFF)
|
self.radius_label = self.radius_brace.get_text("$R$", buff = SMALL_BUFF)
|
||||||
|
|
||||||
self.add(
|
self.radius_group = VGroup(
|
||||||
self.circle, self.radius_line,
|
self.radius_line, self.radius_brace, self.radius_label
|
||||||
self.radius_brace, self.radius_label
|
|
||||||
)
|
)
|
||||||
|
self.add(self.circle, *self.radius_group)
|
||||||
|
|
||||||
self.pi_creature = self.create_pi_creature()
|
if not self.include_pi_creature:
|
||||||
if self.include_pi_creature:
|
self.remove(self.get_primary_pi_creature())
|
||||||
self.add(self.pi_creature)
|
|
||||||
else:
|
|
||||||
self.pi_creature.set_fill(opacity = 0)
|
|
||||||
|
|
||||||
def create_pi_creature(self):
|
|
||||||
return Mortimer().to_corner(DOWN+RIGHT)
|
|
||||||
|
|
||||||
def introduce_circle(self, added_anims = []):
|
def introduce_circle(self, added_anims = []):
|
||||||
self.remove(self.circle)
|
self.remove(self.circle)
|
||||||
|
@ -150,6 +146,18 @@ class CircleScene(PiCreatureScene):
|
||||||
ring.dR = dR
|
ring.dR = dR
|
||||||
return ring
|
return ring
|
||||||
|
|
||||||
|
def get_rings(self, **kwargs):
|
||||||
|
dR = kwargs.get("dR", self.dR)
|
||||||
|
colors = kwargs.get("colors", self.ring_colors)
|
||||||
|
radii = np.arange(0, self.radius, dR)
|
||||||
|
colors = color_gradient(colors, len(radii))
|
||||||
|
|
||||||
|
rings = VGroup(*[
|
||||||
|
self.get_ring(radius, dR = dR, color = color)
|
||||||
|
for radius, color in zip(radii, colors)
|
||||||
|
])
|
||||||
|
return rings
|
||||||
|
|
||||||
def get_outer_ring(self):
|
def get_outer_ring(self):
|
||||||
return self.get_ring(
|
return self.get_ring(
|
||||||
radius = self.radius, dR = self.dR,
|
radius = self.radius, dR = self.dR,
|
||||||
|
@ -197,12 +205,21 @@ class CircleScene(PiCreatureScene):
|
||||||
)
|
)
|
||||||
result.move_to(self.unwrapped_tip, aligned_edge = DOWN)
|
result.move_to(self.unwrapped_tip, aligned_edge = DOWN)
|
||||||
result.shift(R_plus_dr*DOWN)
|
result.shift(R_plus_dr*DOWN)
|
||||||
result.to_edge(to_edge)
|
if to_edge is not None:
|
||||||
|
result.to_edge(to_edge)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def create_pi_creature(self):
|
||||||
|
self.pi_creature = Randolph(color = BLUE_C)
|
||||||
|
self.pi_creature.to_corner(DOWN+LEFT)
|
||||||
|
return self.pi_creature
|
||||||
|
|
||||||
|
|
||||||
#############
|
#############
|
||||||
|
|
||||||
|
#revert_to_original_skipping_status
|
||||||
|
|
||||||
class Chapter1OpeningQuote(OpeningQuote):
|
class Chapter1OpeningQuote(OpeningQuote):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"quote" : [
|
"quote" : [
|
||||||
|
@ -218,20 +235,569 @@ class Chapter1OpeningQuote(OpeningQuote):
|
||||||
"author" : "David Hilbert",
|
"author" : "David Hilbert",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Introduction(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
self.show_series()
|
||||||
|
self.show_many_facts()
|
||||||
|
self.invent_calculus()
|
||||||
|
|
||||||
|
def show_series(self):
|
||||||
|
series = VideoSeries()
|
||||||
|
series.to_edge(UP)
|
||||||
|
this_video = series[0]
|
||||||
|
this_video.highlight(YELLOW)
|
||||||
|
this_video.save_state()
|
||||||
|
this_video.set_fill(opacity = 0)
|
||||||
|
this_video.center()
|
||||||
|
this_video.scale_to_fit_height(2*SPACE_HEIGHT)
|
||||||
|
self.this_video = this_video
|
||||||
|
|
||||||
|
|
||||||
|
words = TextMobject(
|
||||||
|
"Welcome to \\\\",
|
||||||
|
"Essence of calculus"
|
||||||
|
)
|
||||||
|
words.highlight_by_tex("Essence of calculus", YELLOW)
|
||||||
|
|
||||||
|
self.teacher.change_mode("happy")
|
||||||
|
self.play(
|
||||||
|
FadeIn(
|
||||||
|
series,
|
||||||
|
submobject_mode = "lagged_start",
|
||||||
|
run_time = 2
|
||||||
|
),
|
||||||
|
Blink(self.get_teacher())
|
||||||
|
)
|
||||||
|
self.teacher_says(words, target_mode = "hooray")
|
||||||
|
self.change_student_modes(
|
||||||
|
*["hooray"]*3,
|
||||||
|
look_at_arg = series[1].get_left(),
|
||||||
|
added_anims = [
|
||||||
|
ApplyMethod(this_video.restore, run_time = 3),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
ApplyWave(series, direction = DOWN, run_time = 2),
|
||||||
|
Animation(self.teacher.bubble),
|
||||||
|
Animation(self.teacher.bubble.content),
|
||||||
|
)
|
||||||
|
|
||||||
|
essence_words = words.get_part_by_tex("Essence").copy()
|
||||||
|
self.play(
|
||||||
|
FadeOut(self.teacher.bubble),
|
||||||
|
FadeOut(self.teacher.bubble.content),
|
||||||
|
essence_words.next_to, series, DOWN,
|
||||||
|
*[
|
||||||
|
ApplyMethod(pi.change_mode, "pondering")
|
||||||
|
for pi in self.get_pi_creatures()
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.dither(3)
|
||||||
|
|
||||||
|
self.series = series
|
||||||
|
self.essence_words = essence_words
|
||||||
|
|
||||||
|
def show_many_facts(self):
|
||||||
|
rules = list(it.starmap(TexMobject, [
|
||||||
|
("{d(", "x", "^2)", "\\over \\,", "dx}", "=", "2", "x"),
|
||||||
|
(
|
||||||
|
"d(", "f", "g", ")", "=",
|
||||||
|
"f", "dg", "+", "g", "df",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"F(x)", "=", "\\int_0^x",
|
||||||
|
"\\frac{dF}{dg}(t)\\,", "dt"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"f(x)", "=", "\\sum_{n = 0}^\\infty",
|
||||||
|
"f^{(n)}(a)", "\\frac{(x-a)^n}{n!}"
|
||||||
|
),
|
||||||
|
]))
|
||||||
|
video_indices = [2, 3, 7, 10]
|
||||||
|
tex_to_color = [
|
||||||
|
("x", BLUE),
|
||||||
|
("f", BLUE),
|
||||||
|
("df", BLUE),
|
||||||
|
("g", YELLOW),
|
||||||
|
("dg", YELLOW),
|
||||||
|
("f(x)", BLUE),
|
||||||
|
( "f^{(n)}(a)", BLUE),
|
||||||
|
]
|
||||||
|
|
||||||
|
for rule in rules:
|
||||||
|
for tex, color in tex_to_color:
|
||||||
|
rule.highlight_by_tex(tex, color, substring = False)
|
||||||
|
rule.next_to(self.teacher.get_corner(UP+LEFT), UP)
|
||||||
|
rule.shift_onto_screen()
|
||||||
|
|
||||||
|
student_index = 1
|
||||||
|
student = self.get_students()[student_index]
|
||||||
|
self.change_student_modes(
|
||||||
|
"pondering", "sassy", "pondering",
|
||||||
|
look_at_arg = self.teacher.eyes,
|
||||||
|
added_anims = [
|
||||||
|
self.teacher.change_mode, "plain"
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
self.play(
|
||||||
|
Write(rules[0]),
|
||||||
|
self.teacher.change_mode, "raise_right_hand",
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
alt_rules_list = list(rules[1:]) + [VectorizedPoint(self.teacher.eyes.get_top())]
|
||||||
|
for last_rule, rule, video_index in zip(rules, alt_rules_list, video_indices):
|
||||||
|
video = self.series[video_index]
|
||||||
|
self.play(
|
||||||
|
last_rule.replace, video,
|
||||||
|
FadeIn(rule),
|
||||||
|
)
|
||||||
|
self.play(Animation(rule))
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
self.teacher.change_mode, "happy",
|
||||||
|
self.teacher.look_at, student.eyes
|
||||||
|
)
|
||||||
|
|
||||||
|
def invent_calculus(self):
|
||||||
|
student = self.get_students()[1]
|
||||||
|
creatures = self.get_pi_creatures()
|
||||||
|
creatures.remove(student)
|
||||||
|
creature_copies = creatures.copy()
|
||||||
|
self.remove(creatures)
|
||||||
|
self.add(creature_copies)
|
||||||
|
|
||||||
|
calculus = VGroup(*self.essence_words[-len("calculus"):])
|
||||||
|
calculus.generate_target()
|
||||||
|
invent = TextMobject("Invent")
|
||||||
|
invent_calculus = VGroup(invent, calculus.target)
|
||||||
|
invent_calculus.arrange_submobjects(RIGHT, buff = MED_SMALL_BUFF)
|
||||||
|
invent_calculus.next_to(student, UP, 1.5*LARGE_BUFF)
|
||||||
|
invent_calculus.shift(RIGHT)
|
||||||
|
arrow = Arrow(invent_calculus, student)
|
||||||
|
|
||||||
|
fader = Rectangle(
|
||||||
|
width = 2*SPACE_WIDTH,
|
||||||
|
height = 2*SPACE_HEIGHT,
|
||||||
|
stroke_width = 0,
|
||||||
|
fill_color = BLACK,
|
||||||
|
fill_opacity = 0.5,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
FadeIn(fader),
|
||||||
|
Animation(student),
|
||||||
|
Animation(calculus)
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
Write(invent),
|
||||||
|
MoveToTarget(calculus),
|
||||||
|
student.change_mode, "erm",
|
||||||
|
student.look_at, calculus
|
||||||
|
)
|
||||||
|
self.play(ShowCreation(arrow))
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
class PreviewFrame(Scene):
|
||||||
|
def construct(self):
|
||||||
|
frame = Rectangle(height = 9, width = 16, color = WHITE)
|
||||||
|
frame.scale_to_fit_height(1.5*SPACE_HEIGHT)
|
||||||
|
|
||||||
|
colors = iter(color_gradient([BLUE, YELLOW], 3))
|
||||||
|
titles = [
|
||||||
|
TextMobject("Chapter %d:"%d, s).to_edge(UP).highlight(colors.next())
|
||||||
|
for d, s in [
|
||||||
|
(3, "Derivative formulas through geometry"),
|
||||||
|
(4, "Chain rule, product rule, etc."),
|
||||||
|
(7, "Limits"),
|
||||||
|
]
|
||||||
|
]
|
||||||
|
title = titles[0]
|
||||||
|
|
||||||
|
frame.next_to(title, DOWN)
|
||||||
|
|
||||||
|
self.add(frame, title)
|
||||||
|
self.dither(3)
|
||||||
|
for next_title in titles[1:]:
|
||||||
|
self.play(Transform(title, next_title))
|
||||||
|
self.dither(3)
|
||||||
|
|
||||||
|
class ProductRuleDiagram(Scene):
|
||||||
|
def construct(self):
|
||||||
|
df = 0.4
|
||||||
|
dg = 0.2
|
||||||
|
rect_kwargs = {
|
||||||
|
"stroke_width" : 0,
|
||||||
|
"fill_color" : BLUE,
|
||||||
|
"fill_opacity" : 0.6,
|
||||||
|
}
|
||||||
|
|
||||||
|
rect = Rectangle(width = 4, height = 3, **rect_kwargs)
|
||||||
|
rect.shift(DOWN)
|
||||||
|
df_rect = Rectangle(
|
||||||
|
height = rect.get_height(),
|
||||||
|
width = df,
|
||||||
|
**rect_kwargs
|
||||||
|
)
|
||||||
|
dg_rect = Rectangle(
|
||||||
|
height = dg,
|
||||||
|
width = rect.get_width(),
|
||||||
|
**rect_kwargs
|
||||||
|
)
|
||||||
|
corner_rect = Rectangle(
|
||||||
|
height = dg,
|
||||||
|
width = df,
|
||||||
|
**rect_kwargs
|
||||||
|
)
|
||||||
|
d_rects = VGroup(df_rect, dg_rect, corner_rect)
|
||||||
|
for d_rect, direction in zip(d_rects, [RIGHT, DOWN, RIGHT+DOWN]):
|
||||||
|
d_rect.next_to(rect, direction, buff = 0)
|
||||||
|
d_rect.set_fill(YELLOW, 0.75)
|
||||||
|
|
||||||
|
corner_pairs = [
|
||||||
|
(DOWN+RIGHT, UP+RIGHT),
|
||||||
|
(DOWN+RIGHT, DOWN+LEFT),
|
||||||
|
(DOWN+RIGHT, DOWN+RIGHT),
|
||||||
|
]
|
||||||
|
for d_rect, corner_pair in zip(d_rects, corner_pairs):
|
||||||
|
line = Line(*[
|
||||||
|
rect.get_corner(corner)
|
||||||
|
for corner in corner_pair
|
||||||
|
])
|
||||||
|
d_rect.line = d_rect.copy().replace(line, stretch = True)
|
||||||
|
d_rect.line.highlight(d_rect.get_color())
|
||||||
|
|
||||||
|
f_brace = Brace(rect, UP)
|
||||||
|
g_brace = Brace(rect, LEFT)
|
||||||
|
df_brace = Brace(df_rect, UP)
|
||||||
|
dg_brace = Brace(dg_rect, LEFT)
|
||||||
|
|
||||||
|
f_label = f_brace.get_text("$f$")
|
||||||
|
g_label = g_brace.get_text("$g$")
|
||||||
|
df_label = df_brace.get_text("$df$")
|
||||||
|
dg_label = dg_brace.get_text("$dg$")
|
||||||
|
|
||||||
|
VGroup(f_label, df_label).highlight(GREEN)
|
||||||
|
VGroup(g_label, dg_label).highlight(RED)
|
||||||
|
|
||||||
|
f_label.generate_target()
|
||||||
|
g_label.generate_target()
|
||||||
|
fg_group = VGroup(f_label.target, g_label.target)
|
||||||
|
fg_group.generate_target()
|
||||||
|
fg_group.target.arrange_submobjects(RIGHT, buff = SMALL_BUFF)
|
||||||
|
fg_group.target.move_to(rect.get_center())
|
||||||
|
|
||||||
|
for mob in df_brace, df_label, dg_brace, dg_label:
|
||||||
|
mob.save_state()
|
||||||
|
mob.scale(0.01, about_point = rect.get_corner(
|
||||||
|
mob.get_center() - rect.get_center()
|
||||||
|
))
|
||||||
|
|
||||||
|
self.add(rect)
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(f_brace),
|
||||||
|
GrowFromCenter(g_brace),
|
||||||
|
Write(f_label),
|
||||||
|
Write(g_label),
|
||||||
|
)
|
||||||
|
self.play(MoveToTarget(fg_group))
|
||||||
|
self.play(*[
|
||||||
|
mob.restore
|
||||||
|
for mob in df_brace, df_label, dg_brace, dg_label
|
||||||
|
] + [
|
||||||
|
ReplacementTransform(d_rect.line, d_rect)
|
||||||
|
for d_rect in d_rects
|
||||||
|
])
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
d_rects.space_out_submobjects, 1.2,
|
||||||
|
MaintainPositionRelativeTo(
|
||||||
|
VGroup(df_brace, df_label),
|
||||||
|
df_rect
|
||||||
|
),
|
||||||
|
MaintainPositionRelativeTo(
|
||||||
|
VGroup(dg_brace, dg_label),
|
||||||
|
dg_rect
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
deriv = TexMobject(
|
||||||
|
"d(", "fg", ")", "=",
|
||||||
|
"f", "\\cdot", "dg", "+", "g", "\\cdot", "df"
|
||||||
|
)
|
||||||
|
deriv.to_edge(UP)
|
||||||
|
alpha_iter = iter(np.linspace(0, 0.5, 5))
|
||||||
|
self.play(*[
|
||||||
|
ApplyMethod(
|
||||||
|
mob.copy().move_to,
|
||||||
|
deriv.get_part_by_tex(tex, substring = False),
|
||||||
|
rate_func = squish_rate_func(smooth, alpha, alpha+0.5)
|
||||||
|
)
|
||||||
|
for mob, tex in [
|
||||||
|
(fg_group, "fg"),
|
||||||
|
(f_label, "f"),
|
||||||
|
(dg_label, "dg"),
|
||||||
|
(g_label, "g"),
|
||||||
|
(df_label, "df"),
|
||||||
|
]
|
||||||
|
for alpha in [alpha_iter.next()]
|
||||||
|
]+[
|
||||||
|
Write(VGroup(*it.chain(*[
|
||||||
|
deriv.get_parts_by_tex(tex, substring = False)
|
||||||
|
for tex in "d(", ")", "=", "\\cdot", "+"
|
||||||
|
])))
|
||||||
|
], run_time = 3)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
class IntroduceCircle(CircleScene):
|
||||||
|
CONFIG = {
|
||||||
|
"include_pi_creature" : True,
|
||||||
|
"unwrapped_tip" : 2*RIGHT
|
||||||
|
}
|
||||||
|
def construct(self):
|
||||||
|
self.force_skipping()
|
||||||
|
|
||||||
|
self.introduce_area()
|
||||||
|
self.question_area()
|
||||||
|
self.show_calculus_symbols()
|
||||||
|
|
||||||
|
def introduce_area(self):
|
||||||
|
area = TexMobject("\\text{Area}", "=", "\\pi", "R", "^2")
|
||||||
|
area.next_to(self.pi_creature.get_corner(UP+RIGHT), UP+RIGHT)
|
||||||
|
|
||||||
|
self.remove(self.circle, self.radius_group)
|
||||||
|
self.play(
|
||||||
|
self.pi_creature.change_mode, "pondering",
|
||||||
|
self.pi_creature.look_at, self.circle
|
||||||
|
)
|
||||||
|
self.introduce_circle()
|
||||||
|
self.dither()
|
||||||
|
R_copy = self.radius_label.copy()
|
||||||
|
self.play(
|
||||||
|
self.pi_creature.change_mode, "raise_right_hand",
|
||||||
|
self.pi_creature.look_at, area,
|
||||||
|
Transform(R_copy, area.get_part_by_tex("R"))
|
||||||
|
)
|
||||||
|
self.play(Write(area))
|
||||||
|
self.remove(R_copy)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
self.area = area
|
||||||
|
|
||||||
|
def question_area(self):
|
||||||
|
q_marks = TexMobject("???")
|
||||||
|
q_marks.next_to(self.pi_creature, UP)
|
||||||
|
rings = VGroup(*reversed(self.get_rings()))
|
||||||
|
unwrapped_rings = VGroup(*[
|
||||||
|
self.get_unwrapped(ring, to_edge = None)
|
||||||
|
for ring in rings
|
||||||
|
])
|
||||||
|
unwrapped_rings.arrange_submobjects(UP, buff = SMALL_BUFF)
|
||||||
|
unwrapped_rings.move_to(self.unwrapped_tip, UP)
|
||||||
|
ring_anim_kwargs = {
|
||||||
|
"run_time" : 3,
|
||||||
|
"submobject_mode" : "lagged_start"
|
||||||
|
}
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
Animation(self.area),
|
||||||
|
Write(q_marks),
|
||||||
|
self.pi_creature.change_mode, "confused",
|
||||||
|
self.pi_creature.look_at, self.area,
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
FadeIn(rings, **ring_anim_kwargs),
|
||||||
|
Animation(self.radius_group),
|
||||||
|
FadeOut(q_marks),
|
||||||
|
self.pi_creature.change_mode, "thinking"
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
rings.rotate, np.pi/2,
|
||||||
|
rings.move_to, unwrapped_rings.get_top(),
|
||||||
|
Animation(self.radius_group),
|
||||||
|
path_arc = np.pi/2,
|
||||||
|
**ring_anim_kwargs
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
Transform(rings, unwrapped_rings, **ring_anim_kwargs),
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
def show_calculus_symbols(self):
|
||||||
|
ftc = TexMobject(
|
||||||
|
"\\int_0^R", "\\frac{dA}{dr}", "\\,dr",
|
||||||
|
"=", "A(R)"
|
||||||
|
)
|
||||||
|
ftc.shift(2*UP)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
ReplacementTransform(
|
||||||
|
self.area.get_part_by_tex("R").copy(),
|
||||||
|
ftc.get_part_by_tex("int")
|
||||||
|
),
|
||||||
|
self.pi_creature.change_mode, "plain"
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
ReplacementTransform(
|
||||||
|
self.area.get_part_by_tex("Area").copy(),
|
||||||
|
ftc.get_part_by_tex("frac")
|
||||||
|
),
|
||||||
|
ReplacementTransform(
|
||||||
|
self.area.get_part_by_tex("R").copy(),
|
||||||
|
ftc.get_part_by_tex("\\,dr")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(Write(VGroup(*ftc[-2:])))
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
class ApproximateOneRing(CircleScene):
|
||||||
|
CONFIG = {
|
||||||
|
"num_lines" : 24,
|
||||||
|
"ring_index_proportion" : 0.75,
|
||||||
|
"ring_shift_val" : 6*RIGHT,
|
||||||
|
"ring_colors" : [BLUE, GREEN_E],
|
||||||
|
}
|
||||||
|
def construct(self):
|
||||||
|
self.force_skipping()
|
||||||
|
|
||||||
|
self.write_radius_three()
|
||||||
|
self.try_to_understand_area()
|
||||||
|
self.slice_into_rings()
|
||||||
|
self.isolate_one_ring()
|
||||||
|
self.straighten_ring_out()
|
||||||
|
self.ask_about_precise_shape()
|
||||||
|
self.approximate_as_rectangle()
|
||||||
|
|
||||||
|
def write_radius_three(self):
|
||||||
|
three = TexMobject("3")
|
||||||
|
three.move_to(self.radius_label)
|
||||||
|
|
||||||
|
self.look_at(self.circle)
|
||||||
|
self.play(Transform(
|
||||||
|
self.radius_label, three,
|
||||||
|
path_arc = np.pi
|
||||||
|
))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
def try_to_understand_area(self):
|
||||||
|
line_sets = [
|
||||||
|
VGroup(*[
|
||||||
|
Line(
|
||||||
|
self.circle.point_from_proportion(alpha),
|
||||||
|
self.circle.point_from_proportion(func(alpha)),
|
||||||
|
)
|
||||||
|
for alpha in np.linspace(0, 1, self.num_lines)
|
||||||
|
])
|
||||||
|
for func in [
|
||||||
|
lambda alpha : 1-alpha,
|
||||||
|
lambda alpha : (0.5-alpha)%1,
|
||||||
|
lambda alpha : (alpha + 0.4)%1,
|
||||||
|
lambda alpha : (alpha + 0.5)%1,
|
||||||
|
]
|
||||||
|
]
|
||||||
|
for lines in line_sets:
|
||||||
|
lines.set_stroke(BLACK, 2)
|
||||||
|
lines = line_sets[0]
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
ShowCreation(
|
||||||
|
lines,
|
||||||
|
run_time = 2,
|
||||||
|
submobject_mode = "lagged_start"
|
||||||
|
),
|
||||||
|
Animation(self.radius_group),
|
||||||
|
self.pi_creature.change_mode, "maybe"
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
for new_lines in line_sets[1:]:
|
||||||
|
self.play(
|
||||||
|
Transform(lines, new_lines),
|
||||||
|
Animation(self.radius_group)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeOut(lines), Animation(self.radius_group))
|
||||||
|
|
||||||
|
def slice_into_rings(self):
|
||||||
|
rings = self.get_rings()
|
||||||
|
rings.set_stroke(BLACK, 1)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
FadeIn(
|
||||||
|
rings,
|
||||||
|
submobject_mode = "lagged_start",
|
||||||
|
run_time = 3
|
||||||
|
),
|
||||||
|
Animation(self.radius_group),
|
||||||
|
self.pi_creature.change_mode, "pondering",
|
||||||
|
self.pi_creature.look_at, self.circle
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
group = VGroup(self.circle, rings, self.radius_group)
|
||||||
|
for x in range(2):
|
||||||
|
self.play(
|
||||||
|
ApplyMethod(
|
||||||
|
group.rotate_in_place, np.pi,
|
||||||
|
path_arc = np.pi,
|
||||||
|
rate_func = there_and_back,
|
||||||
|
),
|
||||||
|
self.pi_creature.change_mode, "happy"
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
self.rings = rings
|
||||||
|
|
||||||
|
def isolate_one_ring(self):
|
||||||
|
index = int(self.ring_index_proportion*len(self.rings))
|
||||||
|
ring = self.rings[index]
|
||||||
|
|
||||||
|
radius = Line(ORIGIN, ring.R*RIGHT, color = WHITE)
|
||||||
|
radius.rotate(np.pi/4)
|
||||||
|
r_label = TexMobject("r")
|
||||||
|
r_label.next_to(radius.get_center(), UP+LEFT, SMALL_BUFF)
|
||||||
|
area_q = TextMobject("Area?")
|
||||||
|
area_q.highlight(YELLOW)
|
||||||
|
|
||||||
|
|
||||||
|
self.revert_to_original_skipping_status()
|
||||||
|
self.play(ring.shift, self.ring_shift_val)
|
||||||
|
|
||||||
|
VGroup(radius, r_label).shift(ring.get_center())
|
||||||
|
area_q.next_to(ring, DOWN)
|
||||||
|
|
||||||
|
self.play(ShowCreation(radius))
|
||||||
|
self.play(Write(r_label))
|
||||||
|
self.dither()
|
||||||
|
self.play(Write(area_q))
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
Indicate(
|
||||||
|
self.rings,
|
||||||
|
scale_factor = 1.01,
|
||||||
|
submobject_mode = "lagged_start",
|
||||||
|
run_time = 3,
|
||||||
|
),
|
||||||
|
Animation(self.radius_group)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def straighten_ring_out(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def ask_about_precise_shape(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def approximate_as_rectangle(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,13 @@ class VMobject(Mobject):
|
||||||
|
|
||||||
def append_vectorized_mobject(self, vectorized_mobject):
|
def append_vectorized_mobject(self, vectorized_mobject):
|
||||||
new_points = list(vectorized_mobject.points)
|
new_points = list(vectorized_mobject.points)
|
||||||
self.add_control_points(2*[new_points[0]] + new_points)
|
if len(new_points) == 0:
|
||||||
|
return
|
||||||
|
if self.get_num_points() == 0:
|
||||||
|
self.start_at(new_points[0])
|
||||||
|
self.add_control_points(new_points[1:])
|
||||||
|
else:
|
||||||
|
self.add_control_points(2*[new_points[0]] + new_points)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def get_subpath_mobjects(self):
|
def get_subpath_mobjects(self):
|
||||||
|
|
|
@ -543,7 +543,7 @@ class PiCreatureScene(Scene):
|
||||||
if pi_creatures is None:
|
if pi_creatures is None:
|
||||||
pi_creatures = self.get_pi_creatures()
|
pi_creatures = self.get_pi_creatures()
|
||||||
self.play(*it.chain(*[
|
self.play(*it.chain(*[
|
||||||
[pi.look_at, self.get_teacher().eyes]
|
[pi.look_at, thing_to_look_at]
|
||||||
for pi in pi_creatures
|
for pi in pi_creatures
|
||||||
]))
|
]))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue