mirror of
https://github.com/3b1b/manim.git
synced 2025-11-14 22:57:44 +00:00
RefreshOnDerivativeDefinition in eoc7
This commit is contained in:
parent
ecdbba3c4b
commit
dea0d4a948
9 changed files with 6433 additions and 6058 deletions
|
|
@ -178,6 +178,26 @@ class SmoothedVectorizedHomotopy(Homotopy):
|
|||
submob.make_smooth()
|
||||
|
||||
|
||||
class ApplyWave(Homotopy):
|
||||
CONFIG = {
|
||||
"direction" : DOWN,
|
||||
"amplitude" : 0.2,
|
||||
"run_time" : 1,
|
||||
}
|
||||
def __init__(self, mobject, **kwargs):
|
||||
digest_config(self, kwargs, locals())
|
||||
left_x = mobject.get_left()[0]
|
||||
right_x = mobject.get_right()[0]
|
||||
vect = self.amplitude*self.direction
|
||||
def homotopy(x, y, z, t):
|
||||
start_point = np.array([x, y, z])
|
||||
alpha = (x-left_x)/(right_x-left_x)
|
||||
power = np.exp(2*(alpha-0.5))
|
||||
nudge = there_and_back(t**power)
|
||||
return np.array([x, y, z]) + nudge*vect
|
||||
Homotopy.__init__(self, homotopy, mobject, **kwargs)
|
||||
|
||||
|
||||
class PhaseFlow(Animation):
|
||||
CONFIG = {
|
||||
"virtual_time" : 1,
|
||||
|
|
|
|||
3234
eoc/chapter4.py
3234
eoc/chapter4.py
File diff suppressed because it is too large
Load diff
4877
eoc/chapter5.py
4877
eoc/chapter5.py
File diff suppressed because it is too large
Load diff
2755
eoc/chapter6.py
Normal file
2755
eoc/chapter6.py
Normal file
File diff suppressed because it is too large
Load diff
350
eoc/chapter7.py
Normal file
350
eoc/chapter7.py
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
from helpers import *
|
||||
|
||||
from mobject.tex_mobject import TexMobject
|
||||
from mobject import Mobject
|
||||
from mobject.image_mobject import ImageMobject
|
||||
from mobject.vectorized_mobject import *
|
||||
|
||||
from animation.animation import Animation
|
||||
from animation.transform import *
|
||||
from animation.simple_animations import *
|
||||
from animation.playground import *
|
||||
from topics.geometry import *
|
||||
from topics.characters import *
|
||||
from topics.functions import *
|
||||
from topics.fractals import *
|
||||
from topics.number_line import *
|
||||
from topics.combinatorics import *
|
||||
from topics.numerals import *
|
||||
from topics.three_dimensions import *
|
||||
from topics.objects import *
|
||||
from scene import Scene
|
||||
from scene.zoomed_scene import ZoomedScene
|
||||
from scene.reconfigurable_scene import ReconfigurableScene
|
||||
from camera import Camera
|
||||
from mobject.svg_mobject import *
|
||||
from mobject.tex_mobject import *
|
||||
|
||||
from topics.common_scenes import OpeningQuote, PatreonThanks
|
||||
|
||||
from eoc.graph_scene import *
|
||||
|
||||
class Chapter7OpeningQuote(OpeningQuote):
|
||||
CONFIG = {
|
||||
"quote" : [
|
||||
" Calculus required ",
|
||||
"continuity",
|
||||
", and ",
|
||||
"continuity ",
|
||||
"was supposed to require the ",
|
||||
"infinitely little",
|
||||
"; but nobody could discover what the ",
|
||||
"infinitely little",
|
||||
" might be. ",
|
||||
],
|
||||
"quote_arg_separator" : "",
|
||||
"highlighted_quote_terms" : {
|
||||
"continuity" : BLUE,
|
||||
"infinitely" : GREEN,
|
||||
},
|
||||
"author" : "Bertrand Russell",
|
||||
}
|
||||
|
||||
class ThisVideo(TeacherStudentsScene):
|
||||
def construct(self):
|
||||
series = VideoSeries()
|
||||
series.to_edge(UP)
|
||||
deriv_videos = VGroup(*series[1:6])
|
||||
this_video = series[6]
|
||||
integral_videos = VGroup(*series[7:9])
|
||||
video_groups = [deriv_videos, this_video, integral_videos]
|
||||
|
||||
braces = map(Brace, video_groups)
|
||||
deriv_brace, this_brace, integral_brace = braces
|
||||
|
||||
tex_mobs = [
|
||||
TexMobject(*args)
|
||||
for args in [
|
||||
("{df ", " \\over \\, ", " dx}"),
|
||||
("\\lim_{h \\to 0}",),
|
||||
("\\int ", "f(x)", "\\,dx"),
|
||||
]
|
||||
]
|
||||
deriv_tex, this_tex, integral_tex = tex_mobs
|
||||
for tex_mob, brace in zip(tex_mobs, braces):
|
||||
tex_mob.highlight_by_tex("f", GREEN)
|
||||
tex_mob.highlight_by_tex("dx", YELLOW)
|
||||
tex_mob.next_to(brace, DOWN)
|
||||
integral_tex.shift(LARGE_BUFF*RIGHT)
|
||||
|
||||
lim_to_deriv_arrow = Arrow(this_tex, deriv_tex, color = WHITE)
|
||||
|
||||
self.add(series)
|
||||
for index in 0, 2:
|
||||
videos = video_groups[index]
|
||||
brace = braces[index]
|
||||
tex_mob = tex_mobs[index]
|
||||
self.play(ApplyWave(
|
||||
videos,
|
||||
apply_function_kwargs = {"maintain_smoothness" : False}
|
||||
))
|
||||
self.play(
|
||||
GrowFromCenter(brace),
|
||||
Write(tex_mob, run_time = 2)
|
||||
)
|
||||
self.dither()
|
||||
self.play(self.get_teacher().change_mode, "raise_right_hand")
|
||||
self.play(
|
||||
this_video.highlight, YELLOW,
|
||||
GrowFromCenter(this_brace)
|
||||
)
|
||||
self.play(Write(this_tex))
|
||||
self.dither()
|
||||
self.play(ShowCreation(lim_to_deriv_arrow))
|
||||
self.change_student_modes(*["happy"]*3)
|
||||
self.dither(2)
|
||||
|
||||
class ApproachWordToLim(PiCreatureScene):
|
||||
CONFIG = {
|
||||
"dx_color" : GREEN
|
||||
}
|
||||
def construct(self):
|
||||
limit_expression = self.get_limit_expression()
|
||||
limit_expression.next_to(
|
||||
self.pi_creature, LEFT, aligned_edge = UP
|
||||
)
|
||||
|
||||
evaluated_expressions = self.get_evaluated_expressions()
|
||||
evaluated_expressions.to_edge(UP)
|
||||
brace = Brace(evaluated_expressions[0][-1], DOWN)
|
||||
question = TextMobject("What does this ``approach''?")
|
||||
question.next_to(brace, DOWN)
|
||||
|
||||
expression = evaluated_expressions[0]
|
||||
self.add(expression, brace, question)
|
||||
self.change_mode("raise_right_hand")
|
||||
for next_expression in evaluated_expressions[1:]:
|
||||
next_expression.move_to(expression, RIGHT)
|
||||
self.play(Transform(expression, next_expression))
|
||||
self.dither(0.5)
|
||||
self.play(
|
||||
Write(limit_expression),
|
||||
self.pi_creature.change_mode, "pondering"
|
||||
)
|
||||
self.play(Indicate(limit_expression[0]))
|
||||
self.dither(2)
|
||||
|
||||
def get_limit_expression(self):
|
||||
lim = TexMobject("\\lim_", "{dx", " \\to 0}")
|
||||
lim.highlight_by_tex("dx", self.dx_color)
|
||||
ratio = self.get_expression("dx")
|
||||
ratio.next_to(lim, RIGHT)
|
||||
limit_expression = VGroup(lim, ratio)
|
||||
return limit_expression
|
||||
|
||||
def get_evaluated_expressions(self):
|
||||
result = VGroup()
|
||||
for num_zeros in range(1, 6):
|
||||
dx_str = "0." + "0"*num_zeros + "1"
|
||||
expression = self.get_expression(dx_str)
|
||||
dx = float(dx_str)
|
||||
ratio = ((2+dx)**3-2**3)/dx
|
||||
ratio_mob = TexMobject("%.6f\\dots"%ratio)
|
||||
group = VGroup(expression, TexMobject("="), ratio_mob)
|
||||
group.arrange_submobjects(RIGHT)
|
||||
result.add(group)
|
||||
return result
|
||||
|
||||
def get_expression(self, dx):
|
||||
result = TexMobject(
|
||||
"{(2 + ", str(dx), ")^3 - 2^3 \\over", str(dx)
|
||||
)
|
||||
result.highlight_by_tex(dx, self.dx_color)
|
||||
return result
|
||||
|
||||
class RefreshOnDerivativeDefinition(GraphScene):
|
||||
CONFIG = {
|
||||
"start_x" : 2,
|
||||
"dx" : 0.7,
|
||||
"df_color" : YELLOW,
|
||||
"dx_color" : GREEN,
|
||||
"secant_line_color" : MAROON_B,
|
||||
}
|
||||
def construct(self):
|
||||
self.setup_axes()
|
||||
def func(x):
|
||||
u = 0.3*x - 1.5
|
||||
return -u**3 + 5*u + 7
|
||||
graph = self.get_graph(func)
|
||||
graph_label = self.get_graph_label(graph)
|
||||
start_x_v_line, nudged_x_v_line = [
|
||||
self.get_vertical_line_to_graph(
|
||||
self.start_x + nudge, graph,
|
||||
line_class = DashedLine,
|
||||
color = RED
|
||||
)
|
||||
for nudge in 0, self.dx
|
||||
]
|
||||
ss_group = self.get_secant_slope_group(
|
||||
self.start_x, graph,
|
||||
dx = self.dx,
|
||||
dx_label = "dx",
|
||||
df_label = "df",
|
||||
df_line_color = self.df_color,
|
||||
dx_line_color = self.dx_color,
|
||||
secant_line_color = self.secant_line_color,
|
||||
)
|
||||
derivative = TexMobject(
|
||||
"{df", "\\over \\,", "dx}", "(", str(self.start_x), ")"
|
||||
)
|
||||
derivative.highlight_by_tex("df", self.df_color)
|
||||
derivative.highlight_by_tex("dx", self.dx_color)
|
||||
derivative.highlight_by_tex(str(self.start_x), RED)
|
||||
df = derivative.get_part_by_tex("df")
|
||||
dx = derivative.get_part_by_tex("dx")
|
||||
input_x = derivative.get_part_by_tex(str(self.start_x))
|
||||
derivative.move_to(self.coords_to_point(7, 4))
|
||||
deriv_brace = Brace(derivative)
|
||||
dx_to_0 = TexMobject("dx", "\\to 0")
|
||||
dx_to_0.highlight_by_tex("dx", self.dx_color)
|
||||
dx_to_0.next_to(deriv_brace, DOWN)
|
||||
|
||||
#Introduce graph
|
||||
self.play(ShowCreation(graph))
|
||||
self.play(Write(graph_label, run_time = 1))
|
||||
self.play(Write(derivative))
|
||||
self.dither()
|
||||
input_copy = input_x.copy()
|
||||
self.play(
|
||||
input_copy.next_to,
|
||||
self.coords_to_point(self.start_x, 0),
|
||||
DOWN
|
||||
)
|
||||
self.play(ShowCreation(start_x_v_line))
|
||||
self.dither()
|
||||
|
||||
#ss_group_development
|
||||
self.play(
|
||||
ShowCreation(ss_group.dx_line),
|
||||
ShowCreation(ss_group.dx_label),
|
||||
)
|
||||
self.dither()
|
||||
self.play(ShowCreation(ss_group.df_line))
|
||||
self.play(Write(ss_group.df_label))
|
||||
self.dither(2)
|
||||
self.play(
|
||||
ReplacementTransform(ss_group.dx_label.copy(), dx),
|
||||
ReplacementTransform(ss_group.df_label.copy(), df),
|
||||
run_time = 2
|
||||
)
|
||||
self.play(ShowCreation(ss_group.secant_line))
|
||||
self.dither()
|
||||
|
||||
#Let dx approach 0
|
||||
self.play(
|
||||
GrowFromCenter(deriv_brace),
|
||||
Write(dx_to_0),
|
||||
)
|
||||
self.animate_secant_slope_group_change(
|
||||
ss_group,
|
||||
target_dx = 0.01,
|
||||
run_time = 5,
|
||||
)
|
||||
self.dither()
|
||||
|
||||
#Write out fuller limit
|
||||
new_deriv = TexMobject(
|
||||
"{f", "(", str(self.start_x), "+", "dx", ")",
|
||||
"-", "f", "(", str(self.start_x), ")",
|
||||
"\\over \\,", "dx"
|
||||
)
|
||||
new_deriv.highlight_by_tex("dx", self.dx_color)
|
||||
new_deriv.highlight_by_tex("f", self.df_color)
|
||||
new_deriv.highlight_by_tex(str(self.start_x), RED)
|
||||
deriv_to_new_deriv = dict([
|
||||
(
|
||||
VGroup(derivative.get_part_by_tex(s)),
|
||||
VGroup(*new_deriv.get_parts_by_tex(s))
|
||||
)
|
||||
for s in ["f", "over", "dx", "(", str(self.start_x), ")"]
|
||||
])
|
||||
covered_new_deriv_parts = list(it.chain(*deriv_to_new_deriv.values()))
|
||||
uncovered_new_deriv_parts = filter(
|
||||
lambda part : part not in covered_new_deriv_parts,
|
||||
new_deriv
|
||||
)
|
||||
new_deriv.move_to(derivative)
|
||||
new_brace = Brace(new_deriv, DOWN)
|
||||
|
||||
self.animate_secant_slope_group_change(
|
||||
ss_group,
|
||||
target_dx = self.dx,
|
||||
run_time = 2
|
||||
)
|
||||
self.play(ShowCreation(nudged_x_v_line))
|
||||
self.dither()
|
||||
self.play(*[
|
||||
ReplacementTransform(*pair, run_time = 2)
|
||||
for pair in deriv_to_new_deriv.items()
|
||||
]+[
|
||||
Transform(deriv_brace, new_brace),
|
||||
dx_to_0.next_to, new_brace, DOWN
|
||||
])
|
||||
self.play(Write(VGroup(*uncovered_new_deriv_parts), run_time = 2))
|
||||
self.dither()
|
||||
|
||||
#Introduce limit notation
|
||||
lim = TexMobject("\\lim").scale(1.3)
|
||||
dx_to_0.generate_target()
|
||||
dx_to_0.target.scale(0.7)
|
||||
dx_to_0.target.next_to(lim, DOWN, buff = SMALL_BUFF)
|
||||
lim_group = VGroup(lim, dx_to_0.target)
|
||||
lim_group.move_to(new_deriv, LEFT)
|
||||
|
||||
self.play(
|
||||
ReplacementTransform(deriv_brace, lim),
|
||||
MoveToTarget(dx_to_0),
|
||||
new_deriv.next_to, lim_group, RIGHT,
|
||||
run_time = 2
|
||||
)
|
||||
for sf, color in (1.2, YELLOW), (1/1.2, WHITE):
|
||||
self.play(
|
||||
lim.scale_in_place, sf,
|
||||
lim.highlight, color,
|
||||
submobject_mode = "lagged_start"
|
||||
)
|
||||
self.dither(2)
|
||||
self.animate_secant_slope_group_change(
|
||||
ss_group, target_dx = 0.01,
|
||||
run_time = 5,
|
||||
added_anims = [
|
||||
Transform(nudged_x_v_line, start_x_v_line, run_time = 5)
|
||||
]
|
||||
)
|
||||
self.dither(2)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1221
eoc/exp_footnote.py
1221
eoc/exp_footnote.py
File diff suppressed because it is too large
Load diff
|
|
@ -251,6 +251,7 @@ class GraphScene(Scene):
|
|||
df_label, (if applicable)
|
||||
secant_line, (if applicable)
|
||||
)
|
||||
with attributes of those names.
|
||||
"""
|
||||
kwargs = locals()
|
||||
kwargs.pop("self")
|
||||
|
|
|
|||
|
|
@ -110,28 +110,23 @@ class TexMobject(SVGMobject):
|
|||
self.submobjects = new_submobjects
|
||||
return self
|
||||
|
||||
def get_part_by_tex(self, tex, substring = True, return_all_parts = False):
|
||||
def get_parts_by_tex(self, tex, substring = True):
|
||||
def test(tex1, tex2):
|
||||
return tex1 == tex2 or (substring and tex1 in tex2)
|
||||
|
||||
if not hasattr(self, "expression_parts"):
|
||||
if test(tex, self.get_tex_string()):
|
||||
return self
|
||||
return None
|
||||
all_parts = [
|
||||
return []
|
||||
return [
|
||||
submob
|
||||
for submob, part_tex in zip(self.split(), self.expression_parts)
|
||||
if test(tex, part_tex)
|
||||
]
|
||||
if return_all_parts:
|
||||
return all_parts
|
||||
else:
|
||||
if len(all_parts) > 0:
|
||||
return all_parts[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_parts_by_tex(self, tex, **kwargs):
|
||||
return self.get_part_by_tex(tex, return_all_parts = True, **kwargs)
|
||||
def get_part_by_tex(self, tex, **kwargs):
|
||||
all_parts = self.get_parts_by_tex(tex, **kwargs)
|
||||
return all_parts[0] if all_parts else None
|
||||
|
||||
def highlight_by_tex(self, tex, color, **kwargs):
|
||||
parts_to_color = self.get_parts_by_tex(tex, **kwargs)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ class OpeningQuote(Scene):
|
|||
"""that contains all the
|
||||
germs of generality."""
|
||||
],
|
||||
"quote_arg_separator" : " ",
|
||||
"highlighted_quote_terms" : {
|
||||
"special case" : BLUE
|
||||
},
|
||||
|
|
@ -25,7 +26,7 @@ class OpeningQuote(Scene):
|
|||
"fade_in_kwargs" : {
|
||||
"submobject_mode" : "lagged_start",
|
||||
"rate_func" : None,
|
||||
"lag_factor" : 3,
|
||||
"lag_factor" : 4,
|
||||
"run_time" : 5,
|
||||
},
|
||||
}
|
||||
|
|
@ -39,14 +40,15 @@ class OpeningQuote(Scene):
|
|||
self.dither()
|
||||
|
||||
def get_quote(self, max_width = 2*SPACE_WIDTH-1):
|
||||
text_mobject_kwargs = {
|
||||
"alignment" : "",
|
||||
"arg_separator" : self.quote_arg_separator,
|
||||
}
|
||||
if isinstance(self.quote, str):
|
||||
quote = TextMobject(
|
||||
"``%s''"%self.quote.strip(),
|
||||
alignment = "",
|
||||
)
|
||||
quote = TextMobject("``%s''"%self.quote.strip(), **text_mobject_kwargs)
|
||||
else:
|
||||
words = ["``"] + list(self.quote) + ["''"]
|
||||
quote = TextMobject(*words, alignment = "")
|
||||
quote = TextMobject(*words, **text_mobject_kwargs)
|
||||
##TODO, make less hacky
|
||||
quote[0].shift(0.2*RIGHT)
|
||||
quote[-1].shift(0.2*LEFT)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue