mirror of
https://github.com/3b1b/manim.git
synced 2025-08-01 08:54:38 +08:00
Finished epsilon-delta animations
This commit is contained in:
217
eoc/chapter7.py
217
eoc/chapter7.py
@ -870,7 +870,7 @@ class GraphLimitExpression(GraphScene):
|
||||
arrow = Arrow(h_equals_0.get_left(), self.graph_origin)
|
||||
arrow.highlight(WHITE)
|
||||
|
||||
new_expression = expression.copy()
|
||||
new_expression = expression.deepcopy()
|
||||
h_group = VGroup(*new_expression.get_parts_by_tex("h"))
|
||||
for h in h_group:
|
||||
zero = TexMobject("0")
|
||||
@ -1016,6 +1016,7 @@ class GraphLimitExpression(GraphScene):
|
||||
self.dither()
|
||||
|
||||
self.twelve_copy = twelve_copy
|
||||
self.rhs = rhs
|
||||
self.ed_group = ed_group
|
||||
self.input_range_brace_group = VGroup(brace, brace_text)
|
||||
|
||||
@ -1415,9 +1416,21 @@ class PrefaceToEpsilonDeltaDefinition(TeacherStudentsScene):
|
||||
self.change_student_modes(*["happy"]*3)
|
||||
self.dither(6)
|
||||
|
||||
class EpsilonDeltaExample(GraphLimitExpression):
|
||||
class EpsilonDeltaExample(GraphLimitExpression, ZoomedScene):
|
||||
CONFIG = {
|
||||
"epsilon_list" : [2, 1, 0.5],
|
||||
"zoomed_canvas_corner" : DOWN+RIGHT,
|
||||
}
|
||||
def construct(self):
|
||||
self.delta_list = [
|
||||
epsilon/6.0 for epsilon in self.epsilon_list
|
||||
]
|
||||
self.skip_superclass_anims()
|
||||
self.introduce_epsilon()
|
||||
self.match_epsilon()
|
||||
self.zoom_in()
|
||||
self.introduce_delta()
|
||||
self.smaller_epsilon()
|
||||
|
||||
def skip_superclass_anims(self):
|
||||
self.force_skipping()
|
||||
@ -1429,6 +1442,206 @@ class EpsilonDeltaExample(GraphLimitExpression):
|
||||
self.holes.restore()
|
||||
self.add(self.holes)
|
||||
self.revert_to_original_skipping_status()
|
||||
|
||||
def introduce_epsilon(self):
|
||||
epsilon_group, small_epsilon_group = map(
|
||||
self.get_epsilon_group,
|
||||
self.epsilon_list[:2]
|
||||
)
|
||||
|
||||
twelve_line = epsilon_group.limit_line
|
||||
twelve = self.rhs[-1]
|
||||
twelve_copy = twelve.copy()
|
||||
twelve_copy.next_to(twelve_line)
|
||||
|
||||
distance = TextMobject("Distance")
|
||||
distance.next_to(epsilon_group.labels, DOWN, LARGE_BUFF)
|
||||
distance.to_edge(RIGHT)
|
||||
arrows = VGroup(*[
|
||||
Arrow(distance.get_top(), label.get_right())
|
||||
for label in epsilon_group.labels
|
||||
])
|
||||
|
||||
self.play(ShowCreation(twelve_line))
|
||||
self.play(Write(twelve_copy))
|
||||
self.play(ReplacementTransform(twelve_copy, twelve))
|
||||
self.dither()
|
||||
|
||||
self.play(*it.chain(
|
||||
[
|
||||
ReplacementTransform(twelve_line.copy(), line)
|
||||
for line in epsilon_group.epsilon_lines
|
||||
],
|
||||
map(GrowFromCenter, epsilon_group.braces),
|
||||
))
|
||||
self.play(*map(Write, epsilon_group.labels))
|
||||
self.play(
|
||||
Write(distance),
|
||||
ShowCreation(arrows)
|
||||
)
|
||||
self.dither()
|
||||
self.play(*map(FadeOut, [distance, arrows]))
|
||||
self.play(Transform(
|
||||
epsilon_group, small_epsilon_group,
|
||||
run_time = 2
|
||||
))
|
||||
self.dither()
|
||||
|
||||
self.epsilon_group = epsilon_group
|
||||
|
||||
def match_epsilon(self):
|
||||
self.animate_epsilon_delta_group_change(
|
||||
self.ed_group, target_delta = self.delta_list[1],
|
||||
run_time = 2,
|
||||
added_anims = [
|
||||
ApplyMethod(
|
||||
hole.scale_in_place, 0.25,
|
||||
run_time = 2
|
||||
)
|
||||
for hole in self.holes
|
||||
]
|
||||
)
|
||||
self.ed_group.delta = self.delta_list[1]
|
||||
self.ed_group.input_range.make_jagged()
|
||||
self.dither()
|
||||
|
||||
def zoom_in(self):
|
||||
self.ed_group.input_range.make_jagged()
|
||||
|
||||
self.activate_zooming()
|
||||
lil_rect = self.little_rectangle
|
||||
lil_rect.move_to(self.graph_origin)
|
||||
lil_rect.scale_in_place(self.zoom_factor)
|
||||
self.add(self.holes)
|
||||
self.dither()
|
||||
self.play(lil_rect.scale_in_place, 1./self.zoom_factor)
|
||||
self.dither()
|
||||
|
||||
def introduce_delta(self):
|
||||
delta_group = self.get_delta_group(self.delta_list[1])
|
||||
self.play(*map(GrowFromCenter, delta_group.braces))
|
||||
self.play(*map(Write, delta_group.labels))
|
||||
self.dither()
|
||||
self.play(
|
||||
ReplacementTransform(
|
||||
self.ed_group.input_range.copy(),
|
||||
self.ed_group.output_range,
|
||||
run_time = 2
|
||||
),
|
||||
Animation(self.holes),
|
||||
)
|
||||
self.play(ApplyWave(
|
||||
VGroup(self.ed_group.output_range, self.holes[1]),
|
||||
direction = RIGHT
|
||||
))
|
||||
self.dither(2)
|
||||
|
||||
self.delta_group = delta_group
|
||||
|
||||
def smaller_epsilon(self):
|
||||
new_epsilon = self.epsilon_list[-1]
|
||||
new_delta = self.delta_list[-1]
|
||||
self.play(Transform(
|
||||
self.epsilon_group,
|
||||
self.get_epsilon_group(new_epsilon)
|
||||
))
|
||||
self.dither()
|
||||
self.animate_epsilon_delta_group_change(
|
||||
self.ed_group, target_delta = new_delta,
|
||||
added_anims = [
|
||||
Transform(
|
||||
self.delta_group,
|
||||
self.get_delta_group(new_delta)
|
||||
)
|
||||
] + [
|
||||
ApplyMethod(hole.scale_in_place, 0.5)
|
||||
for hole in self.holes
|
||||
]
|
||||
)
|
||||
self.ed_group.input_range.make_jagged()
|
||||
self.dither(2)
|
||||
|
||||
##
|
||||
|
||||
def get_epsilon_group(self, epsilon, limit_value = 12):
|
||||
result = VGroup()
|
||||
line_length = 2*SPACE_HEIGHT
|
||||
lines = [
|
||||
Line(
|
||||
ORIGIN, line_length*RIGHT,
|
||||
).move_to(self.coords_to_point(0, limit_value+nudge))
|
||||
for nudge in 0, -epsilon, epsilon
|
||||
]
|
||||
result.limit_line = lines[0]
|
||||
result.limit_line.set_stroke(RED, width = 3)
|
||||
result.epsilon_lines = VGroup(*lines[1:])
|
||||
result.epsilon_lines.set_stroke(MAROON_B, width = 2)
|
||||
brace = Brace(Line(ORIGIN, 0.5*UP), RIGHT)
|
||||
result.braces = VGroup(*[
|
||||
brace.copy().scale_to_fit_height(
|
||||
group.get_height()
|
||||
).next_to(group, RIGHT)
|
||||
for i in 1, 2
|
||||
for group in [VGroup(lines[0], lines[i])]
|
||||
])
|
||||
result.labels = VGroup(*[
|
||||
brace.get_text("\\Big $\\epsilon$", buff = SMALL_BUFF)
|
||||
for brace in result.braces
|
||||
])
|
||||
for label, brace in zip(result.labels, result.braces):
|
||||
label.scale_to_fit_height(min(
|
||||
label.get_height(),
|
||||
0.8*brace.get_height()
|
||||
))
|
||||
|
||||
result.digest_mobject_attrs()
|
||||
return result
|
||||
|
||||
def get_delta_group(self, delta):
|
||||
result = VGroup()
|
||||
brace = Brace(Line(ORIGIN, RIGHT), DOWN)
|
||||
brace.scale_to_fit_width(
|
||||
(self.coords_to_point(delta, 0)-self.graph_origin)[0]
|
||||
)
|
||||
result.braces = VGroup(*[
|
||||
brace.copy().move_to(self.coords_to_point(x, 0))
|
||||
for x in -delta/2, delta/2
|
||||
])
|
||||
result.braces.shift(self.holes[0].get_height()*DOWN)
|
||||
result.labels = VGroup(*[
|
||||
TexMobject("\\delta").scale(
|
||||
1./self.zoom_factor
|
||||
)
|
||||
for brace in result.braces
|
||||
])
|
||||
for label, brace in zip(result.labels, result.braces):
|
||||
label.next_to(
|
||||
brace, DOWN,
|
||||
buff = SMALL_BUFF/self.zoom_factor
|
||||
)
|
||||
|
||||
result.digest_mobject_attrs()
|
||||
return result
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -129,7 +129,7 @@ class ZoomedScene(Scene):
|
||||
)
|
||||
if self.zoom_activated and self.little_rectangle in moving_mobjects:
|
||||
# When the camera is moving, so is everything,
|
||||
return self.get_mobjects(), []
|
||||
return list(moving_mobjects) + list(static_mobjects), []
|
||||
else:
|
||||
return moving_mobjects, static_mobjects
|
||||
|
||||
|
Reference in New Issue
Block a user