mirror of
https://github.com/3b1b/manim.git
synced 2025-08-02 19:46:21 +08:00
Intro animation for eoc4
This commit is contained in:
178
eoc/chapter4.py
178
eoc/chapter4.py
@ -40,16 +40,178 @@ class Chapter3OpeningQuote(OpeningQuote):
|
||||
|
||||
class TransitionFromLastVideo(TeacherStudentsScene):
|
||||
def construct(self):
|
||||
rules = power_rule, sine_rule, exp_rule = VGroup(*[
|
||||
TexMobject("\\frac{d(x^3)}{dx} = 3x^2"),
|
||||
TexMobject("\\frac{d(\\sin(x))}{dx} = \\cos(x)"),
|
||||
TexMobject("\\frac{d(e^x)}{dx} = e^x"),
|
||||
simple_rules = VGroup(*map(TexMobject, [
|
||||
"\\frac{d(x^3)}{dx} = 3x^2",
|
||||
"\\frac{d(\\sin(x))}{dx} = \\cos(x)",
|
||||
"\\frac{d(e^x)}{dx} = e^x",
|
||||
]))
|
||||
|
||||
combination_rules = VGroup(*[
|
||||
TexMobject("\\frac{d}{dx}\\left(%s\\right)"%tex)
|
||||
for tex in [
|
||||
"\\sin(x) + x^2",
|
||||
"\\sin(x)(x^2)",
|
||||
"\\sin(x^2)",
|
||||
]
|
||||
])
|
||||
rules.arrange_submobjects(buff = LARGE_BUFF)
|
||||
rules.next_to(self.get_teacher(), UP, buff = MED_LARGE_BUFF)
|
||||
rules.to_edge(LEFT)
|
||||
for rules in simple_rules, combination_rules:
|
||||
rules.arrange_submobjects(buff = LARGE_BUFF)
|
||||
rules.next_to(self.get_teacher(), UP, buff = MED_LARGE_BUFF)
|
||||
rules.to_edge(LEFT)
|
||||
|
||||
series = VideoSeries()
|
||||
series.to_edge(UP)
|
||||
last_video = series[2]
|
||||
last_video.save_state()
|
||||
this_video = series[3]
|
||||
brace = Brace(last_video)
|
||||
|
||||
#Simple rules
|
||||
self.add(series)
|
||||
self.play(
|
||||
FadeIn(brace),
|
||||
last_video.highlight, YELLOW
|
||||
)
|
||||
for rule in simple_rules:
|
||||
self.play(
|
||||
Write(rule, run_time = 1),
|
||||
self.get_teacher().change_mode, "raise_right_hand",
|
||||
*[
|
||||
ApplyMethod(pi.change_mode, "pondering")
|
||||
for pi in self.get_students()
|
||||
]
|
||||
)
|
||||
self.dither(2)
|
||||
self.play(simple_rules.replace, last_video)
|
||||
self.play(
|
||||
last_video.restore,
|
||||
Animation(simple_rules),
|
||||
brace.next_to, this_video, DOWN,
|
||||
this_video.highlight, YELLOW
|
||||
)
|
||||
|
||||
#Combination rules
|
||||
self.play(
|
||||
Write(combination_rules),
|
||||
*[
|
||||
ApplyMethod(pi.change_mode, "confused")
|
||||
for pi in self.get_students()
|
||||
]
|
||||
)
|
||||
self.dither(2)
|
||||
for rule in combination_rules:
|
||||
interior = VGroup(*rule[5:-1])
|
||||
added_anims = []
|
||||
if rule is combination_rules[-1]:
|
||||
inner_func = VGroup(*rule[-4:-2])
|
||||
self.play(inner_func.shift, 0.5*UP)
|
||||
added_anims = [
|
||||
inner_func.shift, 0.5*DOWN,
|
||||
inner_func.highlight, YELLOW
|
||||
]
|
||||
self.play(
|
||||
interior.highlight, YELLOW,
|
||||
*added_anims,
|
||||
submobject_mode = "lagged_start"
|
||||
)
|
||||
self.dither()
|
||||
self.dither()
|
||||
|
||||
#Address subtraction and division
|
||||
subtraction = TexMobject("\\sin(x)", "-", "x^2")
|
||||
decomposed_subtraction = TexMobject("\\sin(x)", "+(-1)\\cdot", "x^2")
|
||||
pre_division = TexMobject("\\frac{\\sin(x)}{x^2}")
|
||||
division = VGroup(
|
||||
VGroup(*pre_division[:6]),
|
||||
VGroup(*pre_division[6:7]),
|
||||
VGroup(*pre_division[7:]),
|
||||
)
|
||||
pre_decomposed_division = TexMobject("\\sin(x)\\cdot\\frac{1}{x^2}")
|
||||
decomposed_division = VGroup(
|
||||
VGroup(*pre_decomposed_division[:6]),
|
||||
VGroup(*pre_decomposed_division[6:9]),
|
||||
VGroup(*pre_decomposed_division[9:]),
|
||||
)
|
||||
for mob in subtraction, decomposed_subtraction, division, decomposed_division:
|
||||
mob.next_to(self.get_teacher(), UP+LEFT)
|
||||
|
||||
top_group = VGroup(series, simple_rules, brace)
|
||||
combination_rules.save_state()
|
||||
self.play(
|
||||
top_group.next_to, SPACE_HEIGHT*UP, UP,
|
||||
combination_rules.to_edge, UP,
|
||||
)
|
||||
pairs = [
|
||||
(subtraction, decomposed_subtraction),
|
||||
(division, decomposed_division)
|
||||
]
|
||||
for question, answer in pairs:
|
||||
self.play(
|
||||
Write(question),
|
||||
combination_rules.fade, 0.2,
|
||||
self.get_students()[2].change_mode, "raise_right_hand",
|
||||
self.get_teacher().change_mode, "plain",
|
||||
)
|
||||
self.dither()
|
||||
answer[1].highlight(GREEN)
|
||||
self.play(
|
||||
Transform(question, answer),
|
||||
self.get_teacher().change_mode, "hooray",
|
||||
self.get_students()[2].change_mode, "plain",
|
||||
)
|
||||
self.dither()
|
||||
self.play(FadeOut(question))
|
||||
|
||||
#Monstrous expression
|
||||
monster = TexMobject(
|
||||
"\\Big(",
|
||||
"e^{\\sin(x)} \\cdot",
|
||||
"\\cos\\big(",
|
||||
"\\frac{1}{x^3}",
|
||||
" + x^3",
|
||||
"\\big)",
|
||||
"\\Big)^4"
|
||||
)
|
||||
monster.next_to(self.get_pi_creatures(), UP)
|
||||
parts = [
|
||||
VGroup(*monster[3][2:]),
|
||||
VGroup(*monster[3][:2]),
|
||||
monster[4],
|
||||
VGroup(monster[2], monster[5]),
|
||||
monster[1],
|
||||
VGroup(monster[0], monster[6])
|
||||
]
|
||||
modes = [
|
||||
"erm", "erm",
|
||||
"confused",
|
||||
"sad", "sad",
|
||||
"pleading",
|
||||
]
|
||||
for part, mode in zip(parts, modes):
|
||||
self.play(
|
||||
FadeIn(part, submobject_mode = "lagged_start"),
|
||||
self.get_teacher().change_mode, "raise_right_hand",
|
||||
*[
|
||||
ApplyMethod(pi.change_mode, mode)
|
||||
for pi in self.get_students()
|
||||
]
|
||||
)
|
||||
self.dither(2)
|
||||
|
||||
#Bring back combinations
|
||||
self.play(
|
||||
FadeOut(monster),
|
||||
combination_rules.restore,
|
||||
*[
|
||||
ApplyMethod(pi_creature.change_mode, "pondering")
|
||||
for pi_creature in self.get_pi_creatures()
|
||||
]
|
||||
)
|
||||
self.dither(2)
|
||||
|
||||
|
||||
|
||||
|
||||
self.add(rules)
|
||||
|
||||
|
||||
|
||||
|
@ -82,7 +82,10 @@ class PiCreature(SVGMobject):
|
||||
return self
|
||||
|
||||
def change_mode(self, mode):
|
||||
new_self = self.__class__(mode = mode)
|
||||
new_self = self.__class__(
|
||||
mode = mode,
|
||||
color = self.color
|
||||
)
|
||||
new_self.scale_to_fit_height(self.get_height())
|
||||
new_self.shift(self.eyes.get_center() - new_self.eyes.get_center())
|
||||
if self.is_flipped() ^ new_self.is_flipped():
|
||||
@ -304,7 +307,8 @@ class PiCreatureScene(Scene):
|
||||
return VGroup(self.create_pi_creature())
|
||||
|
||||
def create_pi_creature(self):
|
||||
return Mortimer().to_corner(DOWN+RIGHT)
|
||||
self.pi_creature = Mortimer().to_corner(DOWN+RIGHT)
|
||||
return self.pi_creature
|
||||
|
||||
def get_pi_creatures(self):
|
||||
return self.pi_creatures
|
||||
@ -406,9 +410,9 @@ class PiCreatureScene(Scene):
|
||||
if pi_creature in anim.mobject.submobject_family()
|
||||
]
|
||||
if anims_with_pi_creature:
|
||||
for anim in animations:
|
||||
for anim in anims_with_pi_creature:
|
||||
if isinstance(anim, Transform):
|
||||
index = anim.submobject_family().index(pi_creature)
|
||||
index = anim.mobject.submobject_family().index(pi_creature)
|
||||
target_family = anim.target_mobject.submobject_family()
|
||||
target = target_family[index]
|
||||
if isinstance(target, PiCreature):
|
||||
|
Reference in New Issue
Block a user