Added new example scenes and cleaned up the couple of old ones

This commit is contained in:
Grant Sanderson 2021-01-05 22:04:49 -08:00
parent 06f0374143
commit 9ee1a526ed

View file

@ -30,83 +30,133 @@ class OpeningManimExample(Scene):
transform_title.to_corner(UP + LEFT)
self.play(
Transform(title, transform_title),
LaggedStart(*map(FadeOutAndShiftDown, basel)),
LaggedStartMap(FadeOut, basel, shift=DOWN),
)
self.wait()
fade_comment = TextMobject("""
You probably don't want to over use\\\\
Transforms, though, a simple fade often\\\\
looks nicer.
""")
fade_comment.next_to(
transform_title, DOWN,
buff=LARGE_BUFF,
aligned_edge=LEFT
)
self.play(FadeIn(fade_comment, shift=DOWN))
self.wait(3)
grid = NumberPlane()
grid_title = TextMobject("This is a grid")
grid_title.scale(1.5)
grid_title.move_to(transform_title)
grid_title = TextMobject(
"But manim is for illustrating math, not text",
)
grid_title.to_edge(UP)
grid_title.add_background_rectangle()
self.add(grid, grid_title) # Make sure title is on top of grid
self.play(
FadeOut(title),
FadeInFromDown(grid_title),
FadeOut(title, shift=LEFT),
FadeOut(fade_comment, shift=LEFT),
FadeIn(grid_title),
ShowCreation(grid, run_time=3, lag_ratio=0.1),
)
self.wait()
grid_transform_title = TextMobject(
"That was a non-linear function \\\\"
"applied to the grid"
"This is a non-linear function applied to the grid"
)
grid_transform_title.move_to(grid_title, UL)
grid_transform_title.set_stroke(BLACK, 5, background=True)
grid_transform_title.to_edge(UP)
grid.prepare_for_nonlinear_transform()
self.play(
grid.apply_function,
lambda p: p + np.array([
np.sin(p[1]),
np.sin(p[0]),
0,
]),
run_time=3,
ApplyPointwiseFunction(
lambda p: p + np.array([np.sin(p[1]), np.sin(p[0]), 0]),
grid,
run_time=5,
),
FadeOut(grid_title),
FadeIn(grid_transform_title),
)
self.wait()
self.play(
Transform(grid_title, grid_transform_title)
)
class WarpSquare(Scene):
def construct(self):
square = Square()
self.play(square.apply_complex_function, np.exp)
self.wait()
class SquareToCircle(Scene):
def construct(self):
circle = Circle()
circle.set_fill(BLUE, opacity=0.5)
circle.set_stroke(BLUE_E, width=4)
square = Square()
square.flip(RIGHT)
square.rotate(-3 * TAU / 8)
circle.set_fill(PINK, opacity=0.5)
self.play(ShowCreation(square))
self.play(Transform(square, circle))
self.play(FadeOut(square))
class WarpSquare(Scene):
def construct(self):
square = Square()
self.play(ApplyPointwiseFunction(
lambda point: complex_to_R3(np.exp(R3_to_complex(point))),
square
))
self.wait()
self.play(ReplacementTransform(square, circle))
self.wait()
# This opens an iPython termnial where you can keep writing
# lines as if they were part of this construct method
self.embed()
# Try typing the following lines
# self.play(circle.stretch, 4, {"dim": 0})
# self.play(Rotate(circle, TAU / 4))
# self.play(circle.shift, 2 * RIGHT, circle.scale, 0.25)
# circle.insert_n_curves(10)
# self.play(circle.apply_complex_function, lambda z: z**2)
class WriteStuff(Scene):
class TexTransformExample(Scene):
def construct(self):
example_text = TextMobject(
"This is a some text",
tex_to_color_map={"text": YELLOW}
lines = VGroup(
# Surrounding substrings with double braces
# will ensure that those parts are separated
# out in the TexMobject. For example, here the
# TexMobject will have 5 submobjects, corresponding
# to the strings [A^2, +, B^2, =, C^2]
TexMobject("{{A^2}} + {{B^2}} = {{C^2}}"),
TexMobject("{{A^2}} = {{C^2}} - {{B^2}}"),
TexMobject(
"A = \\sqrt{(C + B)(C - B)}",
substrings_to_isolate=["A", "B", "C"]
),
)
example_tex = TexMobject(
"\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}",
)
group = VGroup(example_text, example_tex)
group.arrange(DOWN)
group.set_width(FRAME_WIDTH - 2 * LARGE_BUFF)
lines.arrange(DOWN, buff=LARGE_BUFF)
for line in lines:
line.set_color_by_tex_to_color_map({
"A": BLUE,
"B": TEAL,
"C": GREEN,
})
self.play(Write(example_text))
self.play(Write(example_tex))
self.add(lines[0])
# The animation TransformMatchingTex will line up parts
# of the source and target which have matching tex strings
self.play(TransformMatchingTex(
lines[0].copy(), lines[1],
run_time=2, path_arc=90 * DEGREES,
))
self.wait()
# The animation TransformMatchingShapes will line up parts
# of the source and target which have matching shapes, regardless
# of where they fall in the mobject family heirarchies.
# For example, calling TransformMatchingTex below would not
# quite look like we want, becuase lines[2] has none of its
# substringsisolated, and even if it did it would not know to
# match the symbol "C", say, from line[1] to the "C" from line[2],
# since in line[1] it is tied up with the full C^2 submobject.
# However, TransformMatchingShapes just does its best to pair
# pieces which look the same
self.play(TransformMatchingShapes(
lines[1].copy(), lines[2],
run_time=2,
))
self.wait()
@ -118,16 +168,100 @@ class UpdatersExample(Scene):
num_decimal_places=3,
include_sign=True,
)
square = Square().to_edge(UP)
square = Square()
square.to_edge(UP)
# This ensures that the method deicmal.next_to(square)
# is called on every frame
always(decimal.next_to, square)
# This ensures thst decimal.set_value(square.get_y()) is
# called every frame
f_always(decimal.set_value, square.get_y)
decimal.add_updater(lambda d: d.next_to(square, RIGHT))
decimal.add_updater(lambda d: d.set_value(square.get_center()[1]))
self.add(square, decimal)
self.play(
square.to_edge, DOWN,
rate_func=there_and_back,
run_time=5,
run_time=3,
)
self.play(square.center)
self.wait()
# You can also add any function generally to a Mobject's
# list of 'updaters'.
now = self.time
square.add_updater(
lambda m: m.set_y(math.sin(self.time - now))
)
self.wait(10)
class SurfaceExample(Scene):
CONFIG = {
"camera_class": ThreeDCamera,
}
def construct(self):
torus1 = Torus(r1=1, r2=1)
torus2 = Torus(r1=3, r2=1)
sphere = Sphere(radius=3, resolution=torus1.resolution)
surfaces = [sphere, torus1, torus2]
# If you want these to be textured with pictures of, say, earth,
# find images for the texture maps you want, perhaps
# https://en.wikipedia.org/wiki/File:Blue_Marble_2002.png and
# https://commons.wikimedia.org/wiki/File:The_earth_at_night.jpg
# and make sure they are available in whatever folder manim
# looks for images, then uncomment the lines below
surfaces = [
TexturedSurface(surface, "EarthTextureMap", "NightEarthTextureMap")
for surface in [sphere, torus1, torus2]
]
for mob in surfaces:
mob.mesh = SurfaceMesh(mob)
mob.mesh.set_stroke(BLUE, 1, opacity=0.5)
# Set perspective
frame = self.camera.frame
frame.set_rotation(
theta=-30 * DEGREES,
phi=70 * DEGREES,
)
surface = surfaces[0]
self.play(
FadeIn(surface),
ShowCreation(surface.mesh, lag_ratio=0.01, run_time=3),
)
for mob in surfaces:
mob.add(mob.mesh)
surface.save_state()
self.play(Rotate(surface, PI / 2), run_time=2)
for mob in surfaces[1:]:
mob.rotate(PI / 2)
self.play(
Transform(surface, surfaces[1]),
run_time=3
)
self.play(
Transform(surface, surfaces[2]),
# Move camera frame during the transition
frame.increment_phi, -10 * DEGREES,
frame.increment_theta, -20 * DEGREES,
run_time=3
)
# Add ambient rotation
frame.add_updater(lambda m, dt: m.increment_theta(-0.1 * dt))
# Play around with where the light is
light = self.camera.light_source
self.add(light)
light.save_state()
self.play(light.move_to, 3 * IN, run_time=5)
self.play(light.shift, 10 * OUT, run_time=5)
self.wait(4)
# See https://github.com/3b1b/videos for many, many more