mirror of
https://github.com/3b1b/manim.git
synced 2025-04-13 09:47:07 +00:00
Preliminary end to eoc4 animations
This commit is contained in:
parent
aa9384c9b6
commit
77013e4142
3 changed files with 344 additions and 26 deletions
274
eoc/chapter4.py
274
eoc/chapter4.py
|
@ -1676,9 +1676,10 @@ class GeneralizeChainRule(Scene):
|
|||
)
|
||||
general = TexMobject(
|
||||
"\\frac{d}{dx}", "g(", "h(x)", ")", "=",
|
||||
"{dg \\over ", " dh}(", "h(x)", ")", "{dh \\over", " dx}", "(x)"
|
||||
"{dg \\over ", " dh}", "(", "h(x)", ")", "{dh \\over", " dx}", "(x)"
|
||||
)
|
||||
example.to_edge(UP, buff = LARGE_BUFF)
|
||||
example.shift(RIGHT)
|
||||
general.next_to(example, DOWN, buff = 1.5*LARGE_BUFF)
|
||||
for mob in example, general:
|
||||
mob.highlight(SINE_COLOR)
|
||||
|
@ -1694,24 +1695,26 @@ class GeneralizeChainRule(Scene):
|
|||
|
||||
general_outer = VGroup(*general[1:4])
|
||||
general_inner = general[2]
|
||||
d_general_outer = VGroup(*general[5:9])
|
||||
d_general_inner = general[7]
|
||||
d_general_d_inner = VGroup(*general[9:12])
|
||||
d_general_outer = VGroup(*general[5:10])
|
||||
d_general_inner = general[8]
|
||||
d_general_d_inner = VGroup(*general[10:13])
|
||||
|
||||
example_outer_brace = Brace(example_outer)
|
||||
example_inner_brace = Brace(example_inner, buff = SMALL_BUFF)
|
||||
example_inner_brace = Brace(example_inner, UP, buff = SMALL_BUFF)
|
||||
d_example_outer_brace = Brace(d_example_outer)
|
||||
d_example_inner_brace = Brace(d_example_inner, buff = SMALL_BUFF)
|
||||
d_example_d_inner_brace = Brace(d_example_d_inner, UP, buff = SMALL_BUFF)
|
||||
|
||||
general_outer_brace = Brace(general_outer)
|
||||
general_inner_brace = Brace(general_inner, buff = SMALL_BUFF)
|
||||
general_inner_brace = Brace(general_inner, UP, buff = SMALL_BUFF)
|
||||
d_general_outer_brace = Brace(d_general_outer)
|
||||
d_general_inner_brace = Brace(d_general_inner, buff = SMALL_BUFF)
|
||||
d_general_d_inner_brace = Brace(d_general_d_inner, UP, buff = SMALL_BUFF)
|
||||
|
||||
for brace in example_outer_brace, general_outer_brace:
|
||||
brace.text = brace.get_text("Outer")
|
||||
for brace in example_inner_brace, general_inner_brace:
|
||||
brace.text = brace.get_text("Inner")
|
||||
for brace in d_example_outer_brace, d_general_outer_brace:
|
||||
brace.text = brace.get_text("d(Outer)")
|
||||
brace.text.shift(SMALL_BUFF*LEFT)
|
||||
|
@ -1720,12 +1723,16 @@ class GeneralizeChainRule(Scene):
|
|||
|
||||
#d(out)d(in) for example
|
||||
self.add(example)
|
||||
outer_braces = VGroup(example_outer_brace, d_example_outer_brace)
|
||||
self.play(*map(GrowFromCenter, outer_braces))
|
||||
for brace in outer_braces:
|
||||
braces = VGroup(
|
||||
example_outer_brace,
|
||||
example_inner_brace,
|
||||
d_example_outer_brace
|
||||
)
|
||||
for brace in braces:
|
||||
self.play(GrowFromCenter(brace))
|
||||
self.play(Write(brace.text, run_time = 1))
|
||||
self.dither()
|
||||
self.dither()
|
||||
inner_braces = VGroup(example_inner_brace, d_example_inner_brace)
|
||||
self.play(*it.chain(*[
|
||||
[mob.scale_in_place, 1.2, mob.highlight, YELLOW]
|
||||
for mob in example_inner, d_example_inner
|
||||
|
@ -1750,12 +1757,247 @@ class GeneralizeChainRule(Scene):
|
|||
self.dither()
|
||||
|
||||
#Generalize
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
self.play(*map(FadeIn, general[:5]))
|
||||
self.dither()
|
||||
self.play(
|
||||
Transform(example_outer_brace, general_outer_brace),
|
||||
Transform(example_outer_brace.text, general_outer_brace.text),
|
||||
Transform(example_inner_brace, general_inner_brace),
|
||||
Transform(example_inner_brace.text, general_inner_brace.text),
|
||||
)
|
||||
self.dither()
|
||||
self.play(
|
||||
Transform(d_example_outer_brace, d_general_outer_brace),
|
||||
Transform(d_example_outer_brace.text, d_general_outer_brace.text),
|
||||
)
|
||||
self.play(Write(d_general_outer))
|
||||
self.dither(2)
|
||||
self.play(
|
||||
Transform(d_example_d_inner_brace, d_general_d_inner_brace),
|
||||
Transform(d_example_d_inner_brace.text, d_general_d_inner_brace.text),
|
||||
)
|
||||
self.play(Write(d_general_d_inner))
|
||||
self.dither(2)
|
||||
|
||||
#Name chain rule
|
||||
name = TextMobject("``Chain rule''")
|
||||
name.scale(1.2)
|
||||
name.highlight(YELLOW)
|
||||
name.to_corner(UP+LEFT)
|
||||
self.play(Write(name))
|
||||
self.dither()
|
||||
|
||||
#Point out dh bottom
|
||||
morty = Mortimer().flip()
|
||||
morty.to_corner(DOWN+LEFT)
|
||||
d_general_outer_copy = d_general_outer.copy()
|
||||
morty.set_fill(opacity = 0)
|
||||
self.play(
|
||||
morty.set_fill, None, 1,
|
||||
morty.change_mode, "raise_left_hand",
|
||||
morty.look, UP+LEFT,
|
||||
d_general_outer_copy.next_to,
|
||||
morty.get_corner(UP+LEFT), UP, MED_LARGE_BUFF,
|
||||
d_general_outer_copy.shift_onto_screen
|
||||
)
|
||||
self.dither()
|
||||
circle = Circle(color = YELLOW)
|
||||
circle.replace(d_general_outer_copy[1])
|
||||
circle.scale_in_place(1.4)
|
||||
self.play(ShowCreation(circle))
|
||||
self.play(Blink(morty))
|
||||
self.dither()
|
||||
inner = d_general_outer_copy[3]
|
||||
self.play(
|
||||
morty.change_mode, "hooray",
|
||||
morty.look_at, inner,
|
||||
inner.shift, UP
|
||||
)
|
||||
self.play(inner.shift, DOWN)
|
||||
self.dither()
|
||||
self.play(morty.change_mode, "pondering")
|
||||
self.play(Blink(morty))
|
||||
self.dither()
|
||||
self.play(*map(FadeOut, [
|
||||
d_general_outer_copy, inner, circle
|
||||
]))
|
||||
|
||||
#Show cancelation
|
||||
braces = [
|
||||
d_example_d_inner_brace,
|
||||
d_example_outer_brace,
|
||||
example_inner_brace,
|
||||
example_outer_brace,
|
||||
]
|
||||
texts = [brace.text for brace in braces]
|
||||
self.play(*map(FadeOut, braces+texts))
|
||||
|
||||
to_collapse = VGroup(VGroup(*general[7:10]), general[12])
|
||||
dg_dh = VGroup(*general[5:7])
|
||||
dh_dx = VGroup(*general[10:12])
|
||||
to_collapse.generate_target()
|
||||
points = VGroup(*map(VectorizedPoint,
|
||||
[m.get_left() for m in to_collapse]
|
||||
))
|
||||
self.play(
|
||||
Transform(to_collapse, points),
|
||||
dh_dx.next_to, dg_dh,
|
||||
morty.look_at, dg_dh,
|
||||
)
|
||||
self.dither()
|
||||
for mob in list(dg_dh)+list(dh_dx):
|
||||
circle = Circle(color = YELLOW)
|
||||
circle.replace(mob)
|
||||
circle.scale_in_place(1.3)
|
||||
self.play(ShowCreation(circle))
|
||||
self.dither()
|
||||
self.play(FadeOut(circle))
|
||||
|
||||
strikes = VGroup()
|
||||
for dh in dg_dh[1], dh_dx[0]:
|
||||
strike = TexMobject("/")
|
||||
strike.stretch(2, dim = 0)
|
||||
strike.rotate(-np.pi/12)
|
||||
strike.move_to(dh)
|
||||
strike.highlight(RED)
|
||||
strikes.add(strike)
|
||||
self.play(Write(strikes))
|
||||
self.play(morty.change_mode, "hooray")
|
||||
equals_dg_dx = TexMobject("= \\frac{dg}{dx}")
|
||||
equals_dg_dx.next_to(dh_dx)
|
||||
self.play(Write(equals_dg_dx))
|
||||
self.play(Blink(morty))
|
||||
self.dither()
|
||||
|
||||
class WatchingVideo(PiCreatureScene):
|
||||
def construct(self):
|
||||
randy = self.get_primary_pi_creature()
|
||||
laptop = Laptop()
|
||||
laptop.next_to(randy.get_corner(UP+RIGHT), RIGHT)
|
||||
randy.look_at(laptop.screen)
|
||||
|
||||
formulas = VGroup(*[
|
||||
TexMobject("\\frac{d}{dx}\\left( %s \\right)"%s)
|
||||
for s in [
|
||||
"e^x \\sin(x)",
|
||||
"\\sin(x) \\cdot \\frac{1}{\\cos(x)}",
|
||||
"\\cos(3x)^2",
|
||||
"e^x(x^2 + 3x + 2)",
|
||||
]
|
||||
])
|
||||
formulas.arrange_submobjects(
|
||||
DOWN,
|
||||
buff = MED_LARGE_BUFF,
|
||||
aligned_edge = LEFT
|
||||
)
|
||||
formulas.next_to(randy, LEFT, buff = MED_LARGE_BUFF)
|
||||
formulas.shift_onto_screen()
|
||||
|
||||
self.add(randy, laptop)
|
||||
self.dither()
|
||||
self.play(randy.change_mode, "erm")
|
||||
self.play(Blink(randy))
|
||||
self.dither()
|
||||
self.play(randy.change_mode, "maybe")
|
||||
self.dither()
|
||||
self.play(Blink(randy))
|
||||
for formula in formulas:
|
||||
self.play(
|
||||
Write(formula, run_time = 2),
|
||||
randy.change_mode, "thinking"
|
||||
)
|
||||
self.dither()
|
||||
|
||||
def create_pi_creatures(self):
|
||||
return [Randolph().shift(DOWN+RIGHT)]
|
||||
|
||||
|
||||
|
||||
class NextVideo(TeacherStudentsScene):
|
||||
def construct(self):
|
||||
series = VideoSeries()
|
||||
series.to_edge(UP)
|
||||
next_video = series[4]
|
||||
|
||||
pre_expression = TexMobject(
|
||||
"x", "^2", "+", "y", "^2", "=", "1"
|
||||
)
|
||||
d_expression = TexMobject(
|
||||
"2", "x", "\\,dx", "+", "2", "y", "\\,dy", "=", "0"
|
||||
)
|
||||
expression_to_d_expression_indices = [
|
||||
1, 0, 0, 2, 4, 3, 3, 5, 6
|
||||
]
|
||||
expression = VGroup()
|
||||
for i, j in enumerate(expression_to_d_expression_indices):
|
||||
submob = pre_expression[j].copy()
|
||||
if d_expression.expression_parts[i] == "2":
|
||||
two = TexMobject("2")
|
||||
two.replace(submob)
|
||||
expression.add(two)
|
||||
else:
|
||||
expression.add(submob)
|
||||
|
||||
for mob in expression, d_expression:
|
||||
mob.scale(1.2)
|
||||
mob.next_to(
|
||||
self.get_teacher().get_corner(UP+LEFT), UP,
|
||||
buff = MED_LARGE_BUFF
|
||||
)
|
||||
mob.shift_onto_screen()
|
||||
|
||||
self.add(series)
|
||||
self.play(
|
||||
next_video.shift, 0.5*DOWN,
|
||||
next_video.highlight, YELLOW,
|
||||
self.get_teacher().change_mode, "raise_right_hand"
|
||||
)
|
||||
self.dither()
|
||||
self.play(
|
||||
Write(expression),
|
||||
*[
|
||||
ApplyMethod(pi.change_mode, "pondering")
|
||||
for pi in self.get_students()
|
||||
]
|
||||
)
|
||||
self.dither()
|
||||
self.remove(expression)
|
||||
self.play(Transform(expression, d_expression, path_arc = np.pi/2))
|
||||
self.dither(3)
|
||||
|
||||
class Chapter4Thanks(PatreonThanks):
|
||||
CONFIG = {
|
||||
"specific_patrons" : [
|
||||
"Ali Yahya",
|
||||
"Meshal Alshammari",
|
||||
"CrypticSwarm ",
|
||||
"Ankit Agarwal",
|
||||
"Yu Jun",
|
||||
"Shelby Doolittle",
|
||||
"Dave Nicponski",
|
||||
"Damion Kistler",
|
||||
"Juan Benet",
|
||||
"Othman Alikhan",
|
||||
"Justin Helps",
|
||||
"Markus Persson",
|
||||
"Dan Buchoff",
|
||||
"Derek Dai",
|
||||
"Joseph John Cox",
|
||||
"Luc Ritchie",
|
||||
"Nils Schneider",
|
||||
"Mathew Bramson",
|
||||
"Guido Gambardella",
|
||||
"Jerry Ling",
|
||||
"Mark Govea",
|
||||
"Vecht",
|
||||
"Shimin Kuang",
|
||||
"Rish Kundalia",
|
||||
"Achille Brighton",
|
||||
"Kirk Werklund",
|
||||
"Ripta Pasay",
|
||||
"Felipe Diniz",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -8,9 +8,83 @@ from mobject.tex_mobject import TextMobject
|
|||
from animation import Animation
|
||||
from animation.simple_animations import Rotating
|
||||
|
||||
from topics.geometry import Circle, Line
|
||||
from topics.geometry import Circle, Line, Rectangle, Square
|
||||
from topics.three_dimensions import Cube
|
||||
|
||||
|
||||
class Laptop(VGroup):
|
||||
CONFIG = {
|
||||
"width" : 3,
|
||||
"body_dimensions" : [4, 3, 0.05],
|
||||
"screen_thickness" : 0.01,
|
||||
"keyboard_width_to_body_width" : 0.9,
|
||||
"keyboard_height_to_body_height" : 0.5,
|
||||
"screen_width_to_screen_plate_width" : 0.9,
|
||||
"key_color_kwargs" : {
|
||||
"stroke_width" : 0,
|
||||
"fill_color" : BLACK,
|
||||
"fill_opacity" : 1,
|
||||
},
|
||||
"body_color" : LIGHT_GREY,
|
||||
"shaded_body_color" : GREY,
|
||||
"open_angle" : np.pi/4,
|
||||
}
|
||||
def generate_points(self):
|
||||
body = Cube(side_length = 1)
|
||||
for dim, scale_factor in enumerate(self.body_dimensions):
|
||||
body.stretch(scale_factor, dim = dim)
|
||||
body.scale_to_fit_width(self.width)
|
||||
body.set_fill(self.shaded_body_color, opacity = 1)
|
||||
body.sort_submobjects(lambda p : p[2])
|
||||
body[-1].set_fill(self.body_color)
|
||||
keyboard = VGroup(*[
|
||||
VGroup(*[
|
||||
Square(**self.key_color_kwargs)
|
||||
for x in range(12-y%2)
|
||||
]).arrange_submobjects(RIGHT, buff = SMALL_BUFF)
|
||||
for y in range(4)
|
||||
]).arrange_submobjects(DOWN, buff = MED_SMALL_BUFF)
|
||||
keyboard.stretch_to_fit_width(
|
||||
self.keyboard_width_to_body_width*body.get_width(),
|
||||
)
|
||||
keyboard.stretch_to_fit_height(
|
||||
self.keyboard_height_to_body_height*body.get_height(),
|
||||
)
|
||||
keyboard.next_to(body, OUT, buff = 0.1*SMALL_BUFF)
|
||||
keyboard.shift(MED_SMALL_BUFF*UP)
|
||||
body.add(keyboard)
|
||||
|
||||
screen_plate = body.copy()
|
||||
screen_plate.stretch(self.screen_thickness/self.body_dimensions[2], dim = 2)
|
||||
screen = Rectangle(
|
||||
stroke_width = 0,
|
||||
fill_color = BLACK,
|
||||
fill_opacity = 1,
|
||||
)
|
||||
screen.replace(screen_plate, stretch = True)
|
||||
screen.scale_in_place(self.screen_width_to_screen_plate_width)
|
||||
screen.next_to(screen_plate, OUT, buff = 0.1*SMALL_BUFF)
|
||||
screen_plate.add(screen)
|
||||
screen_plate.next_to(body, UP, buff = 0)
|
||||
screen_plate.rotate(
|
||||
self.open_angle, RIGHT,
|
||||
about_point = screen_plate.get_bottom()
|
||||
)
|
||||
self.screen_plate = screen_plate
|
||||
self.screen = screen
|
||||
|
||||
axis = Line(
|
||||
body.get_corner(UP+LEFT+OUT),
|
||||
body.get_corner(UP+RIGHT+OUT),
|
||||
color = BLACK,
|
||||
stroke_width = 2
|
||||
)
|
||||
self.axis = axis
|
||||
|
||||
self.add(body, screen_plate, axis)
|
||||
self.rotate(5*np.pi/12, LEFT)
|
||||
self.rotate(np.pi/6, DOWN)
|
||||
|
||||
class PatreonLogo(SVGMobject):
|
||||
CONFIG = {
|
||||
"file_name" : "patreon_logo",
|
||||
|
|
|
@ -16,8 +16,11 @@ class ThreeDCamera(Camera):
|
|||
self.unit_sun_vect = self.sun_vect/np.linalg.norm(self.sun_vect)
|
||||
|
||||
def display_multiple_vectorized_mobjects(self, vmobjects):
|
||||
def cmp_vmobs(vm1, vm2):
|
||||
return cmp(vm1.get_center()[2], vm2.get_center()[2])
|
||||
def cmp_vmobs(*vmobs):
|
||||
return cmp(*[
|
||||
vm.get_edge_center(IN)[2]
|
||||
for vm in vmobs
|
||||
])
|
||||
Camera.display_multiple_vectorized_mobjects(
|
||||
self,
|
||||
sorted(vmobjects, cmp = cmp_vmobs)
|
||||
|
@ -73,13 +76,12 @@ class Cube(VGroup):
|
|||
"side_length" : 2,
|
||||
}
|
||||
def generate_points(self):
|
||||
faces = [
|
||||
Square(side_length = self.side_length).shift(OUT).apply_function(
|
||||
lambda p : np.dot(p, z_to_vector(vect).T)
|
||||
)
|
||||
for vect in IN, OUT, LEFT, RIGHT, UP, DOWN
|
||||
]
|
||||
self.add(*faces)
|
||||
for vect in IN, OUT, LEFT, RIGHT, UP, DOWN:
|
||||
face = Square(side_length = self.side_length)
|
||||
face.shift(self.side_length*OUT/2.0)
|
||||
face.apply_function(lambda p : np.dot(p, z_to_vector(vect).T))
|
||||
|
||||
self.add(face)
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue