Finished formal derivative definition animations of eoc7

This commit is contained in:
Grant Sanderson 2017-03-23 16:29:27 -07:00
parent dea0d4a948
commit e5411ea1f6
3 changed files with 474 additions and 26 deletions

View file

@ -104,36 +104,52 @@ class ThisVideo(TeacherStudentsScene):
self.change_student_modes(*["happy"]*3)
self.dither(2)
class ApproachWordToLim(PiCreatureScene):
class LimitJustMeansApproach(PiCreatureScene):
CONFIG = {
"dx_color" : GREEN
"dx_color" : GREEN,
"max_num_zeros" : 7,
}
def construct(self):
limit_expression = self.get_limit_expression()
limit_expression.next_to(
self.pi_creature, LEFT, aligned_edge = UP
)
limit_expression.shift(2*LEFT)
limit_expression.to_edge(UP)
evaluated_expressions = self.get_evaluated_expressions()
evaluated_expressions.to_edge(UP)
evaluated_expressions.next_to(limit_expression, DOWN, buff = LARGE_BUFF)
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"
point = VectorizedPoint(limit_expression.get_right())
expression = VGroup(
limit_expression[1].copy(),
point, point.copy()
)
self.play(Indicate(limit_expression[0]))
self.add(limit_expression)
self.change_mode("raise_right_hand")
for next_expression in evaluated_expressions:
next_expression.move_to(evaluated_expressions[0], RIGHT)
self.play(
Transform(
expression, next_expression,
submobject_mode = "lagged_start",
lag_factor = 1.2,
),
self.pi_creature.look_at, next_expression[-1]
)
if brace not in self.get_mobjects():
self.play(
GrowFromCenter(brace),
Write(question)
)
self.dither(0.5)
self.dither(2)
def create_pi_creature(self):
self.pi_creature = Mortimer().flip()
self.pi_creature.to_corner(DOWN+LEFT)
return self.pi_creature
def get_limit_expression(self):
lim = TexMobject("\\lim_", "{dx", " \\to 0}")
lim.highlight_by_tex("dx", self.dx_color)
@ -144,7 +160,7 @@ class ApproachWordToLim(PiCreatureScene):
def get_evaluated_expressions(self):
result = VGroup()
for num_zeros in range(1, 6):
for num_zeros in range(1, self.max_num_zeros+1):
dx_str = "0." + "0"*num_zeros + "1"
expression = self.get_expression(dx_str)
dx = float(dx_str)
@ -165,7 +181,7 @@ class ApproachWordToLim(PiCreatureScene):
class RefreshOnDerivativeDefinition(GraphScene):
CONFIG = {
"start_x" : 2,
"dx" : 0.7,
"start_dx" : 0.7,
"df_color" : YELLOW,
"dx_color" : GREEN,
"secant_line_color" : MAROON_B,
@ -183,11 +199,12 @@ class RefreshOnDerivativeDefinition(GraphScene):
line_class = DashedLine,
color = RED
)
for nudge in 0, self.dx
for nudge in 0, self.start_dx
]
nudged_x_v_line.save_state()
ss_group = self.get_secant_slope_group(
self.start_x, graph,
dx = self.dx,
dx = self.start_dx,
dx_label = "dx",
df_label = "df",
df_line_color = self.df_color,
@ -204,6 +221,7 @@ class RefreshOnDerivativeDefinition(GraphScene):
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))
derivative.save_state()
deriv_brace = Brace(derivative)
dx_to_0 = TexMobject("dx", "\\to 0")
dx_to_0.highlight_by_tex("dx", self.dx_color)
@ -278,7 +296,7 @@ class RefreshOnDerivativeDefinition(GraphScene):
self.animate_secant_slope_group_change(
ss_group,
target_dx = self.dx,
target_dx = self.start_dx,
run_time = 2
)
self.play(ShowCreation(nudged_x_v_line))
@ -323,6 +341,437 @@ class RefreshOnDerivativeDefinition(GraphScene):
)
self.dither(2)
#Record attributes for DiscussLowercaseDs below
digest_locals(self)
class RantOpenAndClose(Scene):
def construct(self):
pass
class DiscussLowercaseDs(RefreshOnDerivativeDefinition, PiCreatureScene, ZoomedScene):
CONFIG = {
"zoomed_canvas_corner" : UP+LEFT
}
def construct(self):
self.skip_superclass_anims()
self.replace_dx_terms()
self.compare_rhs_and_lhs()
self.h_is_finite()
def skip_superclass_anims(self):
self.remove(self.pi_creature)
self.force_skipping()
RefreshOnDerivativeDefinition.construct(self)
self.revert_to_original_skipping_status()
self.animate_secant_slope_group_change(
self.ss_group, target_dx = self.start_dx,
added_anims = [
self.nudged_x_v_line.restore,
Animation(self.ss_group.df_line)
],
run_time = 1
)
everything = self.get_top_level_mobjects()
everything.remove(self.derivative)
self.play(*[
ApplyMethod(mob.shift, 2.5*LEFT)
for mob in everything
] + [
FadeIn(self.pi_creature)
])
def replace_dx_terms(self):
dx_list = [self.dx_to_0[0]]
dx_list += self.new_deriv.get_parts_by_tex("dx")
mover = dx_list[0]
mover_scale_val = 1.5
mover.initial_right = mover.get_right()
self.play(
mover.scale, mover_scale_val,
mover.next_to, self.pi_creature.get_corner(UP+LEFT),
UP, MED_SMALL_BUFF,
self.pi_creature.change_mode, "sassy",
path_arc = np.pi/2,
)
self.blink()
self.dither()
for tex in "\\Delta x", "h":
dx_list_replacement = [
TexMobject(
tex
).highlight(self.dx_color).move_to(dx, DOWN)
for dx in dx_list
]
self.play(
Transform(
VGroup(*dx_list),
VGroup(*dx_list_replacement),
),
self.pi_creature.change_mode, "raise_right_hand"
)
self.dither()
self.play(
mover.scale, 0.9,
mover.move_to, mover.initial_right, RIGHT,
self.pi_creature.change_mode, "happy",
)
self.play(
self.dx_to_0.next_to, self.lim, DOWN, SMALL_BUFF,
)
self.dither()
def compare_rhs_and_lhs(self):
self.derivative.restore()
lhs = self.derivative
equals = TexMobject("=")
rhs = VGroup(self.lim, self.dx_to_0, self.new_deriv)
rhs.generate_target()
rhs.target.next_to(self.pi_creature, UP, MED_LARGE_BUFF)
rhs.target.to_edge(RIGHT)
equals.next_to(rhs.target, LEFT)
lhs.next_to(equals, LEFT)
d_circles = VGroup(*[
Circle(color = BLUE_B).replace(
lhs.get_part_by_tex(tex)[0],
stretch = True,
).scale_in_place(1.5).rotate_in_place(-np.pi/12)
for tex in "df", "dx"
])
d_words = TextMobject("""
Limit idea is
built in
""")
d_words.next_to(d_circles, DOWN)
d_words.highlight(d_circles[0].get_color())
lhs_rect, rhs_rect = rects = [
Rectangle(color = GREEN_B).replace(
mob, stretch = True
)
for mob in lhs, rhs.target
]
for rect in rects:
rect.stretch_to_fit_width(rect.get_width()+2*MED_SMALL_BUFF)
rect.stretch_to_fit_height(rect.get_height()+2*MED_SMALL_BUFF)
formal_definition_words = TextMobject("""
Formal derivative definition
""")
formal_definition_words.scale_to_fit_width(rhs_rect.get_width())
formal_definition_words.next_to(rhs_rect, UP)
formal_definition_words.highlight(rhs_rect.get_color())
formal_definition_words.add_background_rectangle()
df = VGroup(lhs.get_part_by_tex("df"))
df_target = VGroup(*self.new_deriv.get_parts_by_tex("f"))
self.play(
MoveToTarget(rhs),
Write(lhs),
Write(equals),
)
self.play(
ShowCreation(d_circles, run_time = 2),
self.pi_creature.change_mode, "pondering"
)
self.play(Write(d_words))
self.animate_secant_slope_group_change(
self.ss_group, target_dx = 0.01,
added_anims = [
Transform(
self.nudged_x_v_line, self.start_x_v_line,
run_time = 3
)
]
)
self.change_mode("thinking")
self.dither(2)
self.play(
ShowCreation(lhs_rect),
FadeOut(d_circles),
FadeOut(d_words),
)
self.dither(2)
self.play(
ReplacementTransform(lhs_rect, rhs_rect),
self.pi_creature.change_mode, "raise_right_hand"
)
self.dither(2)
self.play(ReplacementTransform(
df.copy(), df_target,
path_arc = -np.pi/2,
run_time = 2
))
self.dither(2)
self.play(Indicate(
VGroup(*rhs[:2]),
run_time = 2
))
self.dither()
self.play(Write(formal_definition_words))
self.play(
self.pi_creature.change_mode, "happy",
self.pi_creature.look_at, formal_definition_words
)
self.dither(2)
lhs.add_background_rectangle()
self.add(rhs_rect, rhs)
self.definition_group = VGroup(
lhs, equals, rhs_rect, rhs, formal_definition_words
)
self.lhs, self.rhs, self.rhs_rect = lhs, rhs, rhs_rect
def h_is_finite(self):
self.play(
FadeOut(self.graph_label),
self.definition_group.center,
self.definition_group.to_corner, UP+RIGHT,
self.pi_creature.change_mode, "sassy",
self.pi_creature.look_at, 4*UP
)
self.dither()
words = TextMobject("No ``infinitely small''")
words.next_to(
self.definition_group, DOWN,
buff = LARGE_BUFF,
)
arrow = Arrow(words.get_top(), self.rhs_rect.get_bottom())
arrow.highlight(WHITE)
h_group = VGroup(
self.rhs[1].get_part_by_tex("dx"),
*self.rhs[2].get_parts_by_tex("dx")
)
moving_h = h_group[0]
moving_h.original_center = moving_h.get_center()
dx_group = VGroup()
for h in h_group:
dx = TexMobject("dx")
dx.highlight(h.get_color())
dx.replace(h, dim_to_match = 1)
dx_group.add(dx)
moving_dx = dx_group[0]
self.play(Write(words), ShowCreation(arrow))
self.dither(2)
self.play(
moving_h.next_to, self.pi_creature.get_corner(UP+RIGHT), UP,
self.pi_creature.change_mode, "raise_left_hand",
)
self.dither()
moving_dx.move_to(moving_h)
h_group.save_state()
self.play(Transform(
h_group, dx_group,
path_arc = np.pi,
))
self.dither(2)
self.play(h_group.restore, path_arc = np.pi)
self.play(
moving_h.move_to, moving_h.original_center,
self.pi_creature.change_mode, "plain"
)
self.dither()
self.activate_zooming()
lil_rect = self.little_rectangle
lil_rect.move_to(self.ss_group)
lil_rect.scale_in_place(3)
lil_rect.save_state()
self.dither()
self.add(self.rhs)
self.play(
lil_rect.scale_to_fit_width,
self.ss_group.dx_line.get_width()*4,
run_time = 4
)
self.dither()
dx = self.ss_group.dx_label
dx.save_state()
h = TexMobject("h")
h.highlight(dx.get_color())
h.replace(dx, dim_to_match = 1)
self.play(Transform(dx, h, path_arc = np.pi))
self.play(Indicate(dx))
self.dither()
self.play(dx.restore, path_arc = np.pi)
self.play(lil_rect.restore, run_time = 4)
self.dither()
self.disactivate_zooming()
class OtherViewsOfDx(TeacherStudentsScene):
def construct(self):
definition = TexMobject(
"{df", "\\over \\,", "dx}", "(", "2", ")", "=",
"\\lim", "_{h", "\\to", "0}",
"{f", "(", "2", "+", "h", ")", "-", "f", "(", "2", ")",
"\\over \\,", "h}"
)
tex_to_color = {
"df" : YELLOW,
"f" : YELLOW,
"dx" : GREEN,
"h" : GREEN,
"2" : RED
}
for tex, color in tex_to_color.items():
definition.highlight_by_tex(tex, color)
definition.scale(0.8)
definition.to_corner(UP+LEFT)
dx_group = VGroup(*definition.get_parts_by_tex("dx"))
h_group = VGroup(*definition.get_parts_by_tex("h"))
self.add(definition)
statements = [
TextMobject(*args)
for args in [
("Why the new \\\\ variable", "$h$", "?"),
("$dx$", "is more $\\dots$ contentious.")
]
]
for statement in statements:
statement.h, statement.dx = [
VGroup(*statement.get_parts_by_tex(
tex, substring = False
)).highlight(GREEN)
for tex in "$h$", "$dx$"
]
self.force_skipping()
self.student_says(
statements[0],
student_index = 1,
target_mode = "confused"
)
self.play(ReplacementTransform(
statements[0].h.copy(), h_group,
run_time = 2,
submobject_mode = "lagged_start",
lag_factor = 1.5,
))
self.dither()
self.revert_to_original_skipping_status()##
self.teacher_says(
statements[1],
target_mode = "hesitant",
)
self.play(ReplacementTransform(
statements[1].dx.copy(), dx_group,
run_time = 2
))
self.dither()
class GraphLimitExpression(GraphScene):
CONFIG = {
"start_x" : 2,
"h_color" : GREEN,
"f_color" : YELLOW,
"start_x_color" : RED,
"graph_origin" : 3*DOWN,
"x_min" : -5,
"x_max" : 5,
"x_axis_label" : "$h$",
"x_labeled_nums" : range(-5, 6),
"y_min" : 0,
"y_max" : 20,
"y_tick_frequency" : 1,
"y_labeled_nums" : range(5, 25, 5),
"y_axis_label" : "",
}
def construct(self):
self.force_skipping()
def func(h):
return 3*(2**2) + 3*2*h + h**2
self.setup_axes()
self.introduce_limit_term()
self.show_graph()
self.emphasize_non_definedness_at_0()
self.point_out_limit_point()
self.show_epsilon_delta_intuition()
self.limits_as_a_language()
def introduce_limit_term(self):
abstract_limit = TexMobject(
"\\lim", "_{h", "\\to 0}", "=",
"{f", "(", str(self.start_x), "+", "h", ")",
"-", "f", "(", str(self.start_x), ")",
"\\over \\,", "h}",
arg_separator = "",
)
cube_limit = TexMobject(
"\\lim", "_{h", "\\to 0}", "=",
"{(", str(self.start_x), "+", "h", ")", "^3",
"-", "(", str(self.start_x), ")", "^3",
"\\over \\,", "h}",
arg_separator = "",
)
tex_to_color = {
"h" : self.h_color,
"f" : self.f_color,
"3" : self.f_color,
str(self.start_x) : self.start_x_color
}
for expression in abstract_limit, cube_limit:
for tex, color in tex_to_color.items():
expression.highlight_by_tex(tex, color)
expression.next_to(ORIGIN, RIGHT, LARGE_BUFF)
expression.to_edge(UP)
brace = Brace(VGroup(*abstract_limit[4:]), DOWN)
graph_this = brace.get_text("Graph this")
self.revert_to_original_skipping_status()
self.add(abstract_limit)
self.play(
GrowFromCenter(brace),
Write(graph_this)
)
self.dither()
self.play(*[
ReplacementTransform(
VGroup(*abstract_limit.get_parts_by_tex(tex)),
VGroup(*cube_limit.get_parts_by_tex(
tex if tex is not "f" else "3"
)),
run_time = 2,
)
for tex in [
"lim", "h", "to", "=", "f", "(",
str(self.start_x), "+", ")", "-", "over"
]
])
self.dither()
for part in cube_limit.get_parts_by_tex("2"):
self.play(Indicate(part))
self.dither(2)
def show_graph(self):
pass
def emphasize_non_definedness_at_0(self):
pass
def point_out_limit_point(self):
pass
def show_epsilon_delta_intuition(self):
pass
def limits_as_a_language(self):
pass

View file

@ -129,7 +129,6 @@ class ZoomedScene(Scene):
)
if self.zoom_activated and self.little_rectangle in moving_mobjects:
# When the camera is moving, so is everything,
mobjects = self.get_mobjects()
return self.get_mobjects(), []
else:
return moving_mobjects, static_mobjects

View file

@ -413,10 +413,10 @@ class PiCreatureScene(Scene):
*content,
bubble_class = bubble_class,
bubble_kwargs = bubble_kwargs,
target_mode = target_mode
target_mode = target_mode,
**kwargs
),
*added_anims,
**kwargs
*added_anims
)
def pi_creature_says(self, pi_creature, *content, **kwargs):