Add various scenes that had been disorganized

This commit is contained in:
Grant Sanderson 2021-08-19 09:00:53 -07:00
parent 487e33299f
commit a187a409fa
5 changed files with 562 additions and 0 deletions

View file

@ -2,6 +2,7 @@ from manimlib.constants import WHITE
from manimlib.constants import BLACK
from manimlib.constants import DOWN
from manimlib.constants import UP
from manimlib.constants import BLUE
from manimlib.scene.scene import Scene
from manimlib.mobject.frame import FullScreenRectangle
from manimlib.mobject.frame import ScreenRectangle
@ -29,3 +30,16 @@ class Spotlight(Scene):
animated_screen = AnimatedBoundary(screen)
self.add(screen, animated_screen)
self.wait(16)
class VideoWrapper(Scene):
def construct(self):
self.add(FullScreenRectangle())
screen = ScreenRectangle()
screen.set_fill(BLACK, 1)
screen.set_stroke(BLUE, 0)
screen.set_height(6)
screen.to_edge(DOWN)
self.add(screen, AnimatedBoundary(screen))
self.wait(32)

View file

@ -0,0 +1,252 @@
from manim_imports_ext import *
class LinalgThumbnail(ThreeDScene):
CONFIG = {
"camera_config": {
"anti_alias_width": 0,
}
}
def construct(self):
grid = NumberPlane((-10, 10), (-10, 10), faded_line_ratio=1)
grid.set_stroke(width=6)
grid.faded_lines.set_stroke(width=1)
grid.apply_matrix([[3, 2], [1, -1]])
# self.add(grid)
frame = self.camera.frame
frame.reorient(0, 75)
cube = Cube()
cube.set_color(BLUE)
cube.set_opacity(0.5)
edges = VGroup()
for vect in [OUT, RIGHT, UP, LEFT, DOWN, IN]:
face = Square()
face.shift(OUT)
face.apply_matrix(z_to_vector(vect))
edges.add(face)
for sm in edges.family_members_with_points():
sm.flat_stroke = False
sm.joint_type = "round"
edges.set_stroke(WHITE, 4)
edges.replace(cube)
edges.apply_depth_test()
cube = Group(cube, edges)
cube2 = cube.copy().apply_matrix(
[[1, 0, 1], [0, 1, 0], [0, 0, 1]]
)
# cube2.match_height(cube)
arrow = Vector(RIGHT)
arrow.rotate(PI / 2, RIGHT)
group = Group(cube, arrow, cube2)
group.arrange(RIGHT, buff=MED_LARGE_BUFF)
self.add(group)
# kw ={
# "thickness": 0.1,
# # "max_tip_length_to_length_ratio": 0.2,
# }
# self.add(Vector(grid.c2p(1, 0), fill_color=GREEN, **kw))
# self.add(Vector(grid.c2p(0, 1), fill_color=RED, **kw))
# self.add(FullScreenFadeRectangle(fill_opacity=0.1))
class CSThumbnail(Scene):
def construct(self):
self.add(self.get_background())
def get_background(self, n=12, k=50, zero_color=GREY_C, one_color=GREY_B):
choices = (Integer(0, color=zero_color), Integer(1, color=one_color))
background = VGroup(*(
random.choice(choices).copy()
for x in range(n * k)
))
background.arrange_in_grid(n, k)
background.set_height(FRAME_HEIGHT)
return background
class GroupThumbnail(ThreeDScene):
def construct(self):
cube = Cube()
cubes = Group(cube)
for axis in [[1, 1, 1], [1, 1, -1], [1, -1, 1], [1, -1, -1]]:
for angle in [60 * DEGREES]:
cubes.add(cube.copy().rotate(angle, axis))
cubes.rotate(95 * DEGREES, RIGHT)
cubes.rotate(30 * DEGREES, UP)
cubes.set_height(6)
cubes.center()
# cubes.set_y(-0.5)
cubes.set_color(BLUE_D)
cubes.set_shadow(0.65)
cubes.set_gloss(0.5)
self.add(cubes)
class BaselThumbnail(Scene):
def construct(self):
# Lake
lake_radius = 6
lake_center = ORIGIN
lake = Circle(
fill_color=BLUE,
fill_opacity=0.0,
radius=lake_radius,
stroke_color=BLUE_D,
stroke_width=3,
)
lake.move_to(lake_center)
R = 2
light_template = VGroup()
rs = np.linspace(0, 1, 100)
for r1, r2 in zip(rs, rs[1:]):
dot1 = Dot(radius=R * r1).flip()
dot2 = Dot(radius=R * r2)
dot2.append_vectorized_mobject(dot1)
dot2.insert_n_curves(100)
dot2.set_fill(YELLOW, opacity=0.5 * (1 - r1)**2)
dot2.set_stroke(width=0)
light_template.add(dot2)
houses = VGroup()
lights = VGroup()
for i in range(16):
theta = -TAU / 4 + (i + 0.5) * TAU / 16
pos = lake_center + lake_radius * np.array([np.cos(theta), np.sin(theta), 0])
house = Lighthouse()
house.set_fill(GREY_B)
house.set_stroke(width=0)
house.set_height(0.5)
house.move_to(pos)
light = light_template.copy()
light.move_to(pos)
houses.add(house)
lights.add(light)
self.add(lake)
self.add(houses)
self.add(lights)
# Equation
equation = Tex(
"1", "+", "{1 \\over 4}", "+",
"{1 \\over 9}", "+", "{1 \\over 16}", "+",
"{1 \\over 25}", "+", "\\cdots"
)
equation.scale(1.8)
equation.move_to(2 * UP)
answer = Tex("= \\frac{\\pi^2}{6}", color=YELLOW)
answer.scale(3)
answer.move_to(1.25 * DOWN)
equation.add(answer)
shadow = VGroup()
for w in np.linspace(20, 0, 50):
shadow.add(equation.copy().set_fill(opacity=0).set_stroke(BLACK, width=w, opacity=0.02))
self.add(shadow)
self.add(equation)
self.wait()
class Eola1Thumbnail(Scene):
def construct(self):
plane = NumberPlane(
x_range=(-2, 2),
y_range=(-5, 5),
)
plane.set_width(FRAME_WIDTH / 3)
plane.to_edge(LEFT, buff=0)
plane.shift(1.5 * DOWN)
vect = Arrow(
plane.get_origin(), plane.c2p(1, 2),
buff=0,
thickness=0.1,
)
vect.set_color(YELLOW)
self.add(plane, vect)
coords = IntegerMatrix([[1], [2]])
coords.set_height(3)
coords.set_color(TEAL)
coords.center()
coords.match_y(vect)
self.add(coords)
symbol = Tex("\\vec{\\textbf{v} } \\in V")
symbol.set_color(BLUE)
symbol.set_width(FRAME_WIDTH / 3 - 1)
symbol.set_x(FRAME_WIDTH / 3)
symbol.match_y(vect)
self.add(symbol)
lines = VGroup(*(Line(DOWN, UP) for x in range(2)))
lines.set_height(FRAME_HEIGHT)
lines.arrange(RIGHT, buff=FRAME_WIDTH / 3)
lines.set_stroke(GREY_A, 5)
self.add(lines)
title = Text("Vectors", font_size=120)
title.to_edge(UP, buff=MED_SMALL_BUFF)
shadow = VGroup()
for w in np.linspace(50, 0, 100):
shadow.add(title.copy().set_fill(opacity=0).set_stroke(BLACK, width=w, opacity=0.01))
self.add(shadow)
self.add(title)
def pendulum_vector_field_func(theta, omega, mu=0.3, g=9.8, L=3):
return [omega, -np.sqrt(g / L) * np.sin(theta) - mu * omega]
class ODEThumbnail(Scene):
def construct(self):
plane = NumberPlane()
field = VectorField(
pendulum_vector_field_func, plane,
step_multiple=0.5,
magnitude_range=(0, 5),
length_func=lambda norm: 0.35 * sigmoid(norm),
)
field.set_opacity(0.75)
# self.add(plane)
# self.add(field)
# return
# Solution curve
dt = 0.1
t = 0
total_time = 50
def func(point):
return plane.c2p(*pendulum_vector_field_func(*plane.p2c(point)))
points = [plane.c2p(-4 * TAU / 4, 4.0)]
while t < total_time:
t += dt
points.append(points[-1] + dt * func(points[-1]))
line = VMobject()
line.set_points_smoothly(points, true_smooth=True)
line.set_stroke([WHITE, WHITE, BLACK], width=[5, 1])
# line.set_stroke((BLUE_C, BLUE_E), width=(10, 1))
line_fuzz = VGroup()
N = 50
for width in np.linspace(50, 0, N):
line_fuzz.add(line.copy().set_stroke(BLACK, width=width, opacity=2 / N))
self.add(line_fuzz)
self.add(line)

View file

@ -0,0 +1,74 @@
from manim_imports_ext import *
class MugToTorus(ThreeDScene):
def construct(self):
frame = self.camera.frame
frame.reorient(-20, 60)
R1, R2 = (2, 0.75)
def torus_func(u, v):
v1 = np.array([-math.sin(u), 0, math.cos(u)])
v2 = math.cos(v) * v1 + math.sin(v) * UP
return R1 * v1 + R2 * v2
def cylinder_func(u, v):
return (math.cos(v), math.sin(v), u)
left_half_torus = ParametricSurface(
torus_func,
u_range=(-PI / 2, PI + PI / 2),
v_range=(0, TAU),
)
right_half_torus = ParametricSurface(
torus_func,
u_range=(PI, TAU),
v_range=(0, TAU),
)
cylinder = ParametricSurface(
cylinder_func,
u_range=(PI, TAU),
v_range=(0, TAU),
)
cylinder.set_width(3)
cylinder.set_depth(5, stretch=True)
cylinder.move_to(ORIGIN, LEFT)
disk = Disk3D(resolution=(2, 50))
disk.match_width(cylinder)
disk.move_to(cylinder, IN)
disk.scale(1.001)
low_disk = disk.copy()
for mob in (left_half_torus, right_half_torus, cylinder, low_disk, disk):
mob.set_color(GREY)
mob.set_gloss(0.7)
left_half_torus.save_state()
left_half_torus.set_depth(3, about_point=ORIGIN)
self.add(left_half_torus)
self.add(cylinder)
self.add(low_disk, disk)
self.add(frame)
self.play(disk.animate.move_to(cylinder, OUT), run_time=2)
for mob in (disk, low_disk):
mob.generate_target()
mob.target.rotate(90 * DEGREES, DOWN)
mob.target.set_depth(2 * R2)
disk.target.move_to(right_half_torus, OUT + LEFT)
low_disk.target.rotate(PI, UP)
low_disk.target.move_to(right_half_torus, IN + LEFT)
self.play(
MoveToTarget(disk),
MoveToTarget(low_disk),
Transform(cylinder, right_half_torus),
Restore(left_half_torus, rate_func=squish_rate_func(smooth, 0, 0.75)),
frame.animate.reorient(-10, 80),
run_time=5,
)
self.wait()

84
outside_videos/podcast.py Normal file
View file

@ -0,0 +1,84 @@
from manim_imports_ext import *
class PodcastIntro(Scene):
def construct(self):
tower = self.get_radio_tower()
n_rings = 15
min_radius = 0.5
max_radius = 9
max_width = 20
min_width = 0
max_opacity = 1
min_opacity = 0
rings = VGroup(*(
self.get_circle(radius=r)
for r in np.linspace(min_radius, max_radius, n_rings)
))
tuples = zip(
rings,
np.linspace(max_width, min_width, n_rings),
np.linspace(max_opacity, min_opacity, n_rings),
)
for ring, width, opacity in tuples:
ring.set_stroke(width=width, opacity=opacity)
ring.save_state()
ring.scale(0)
ring.set_stroke(WHITE, width=2)
self.play(
ShowCreation(tower[0], lag_ratio=0.1),
run_time=3
)
self.play(
FadeIn(tower[1], scale=10, run_time=1),
LaggedStart(
*(
Restore(ring, rate_func=linear)
for ring in reversed(rings)
),
run_time=4,
lag_ratio=0.08
)
)
def get_radio_tower(self):
base = VGroup()
line1 = Line(DL, UP)
line2 = Line(DR, UP)
base.add(line1, line2)
base.set_width(2, stretch=True)
base.set_height(4, stretch=True)
base.to_edge(DOWN, buff=1.5)
# alphas = [0, 0.2, 0.4, 0.6, 0.7, 0.8, 0.85]
values = np.array([0, *(1 / n for n in range(1, 11))])
alphas = np.cumsum(values)
alphas /= alphas[-1]
for a1, a2 in zip(alphas, alphas[1:]):
base.add(
Line(line1.pfp(a1), line2.pfp(a2)),
Line(line2.pfp(a1), line1.pfp(a2)),
)
base.set_stroke(GREY_A, width=2)
VGroup(line1, line2).set_stroke(width=4)
dot = Dot(line1.get_end(), radius=0.125)
dot.set_color(WHITE)
dot.set_gloss(0.5)
tower = VGroup(base, dot)
tower.set_height(3)
tower.shift(-line1.get_end())
tower.set_stroke(background=True)
return tower
def get_circle(self, center=ORIGIN, radius=1):
arc1 = Arc(PI, 3 * PI / 2)
arc2 = Arc(PI / 2, PI / 2)
arc1.set_color(BLUE)
arc2.set_color(GREY_BROWN)
circle = VGroup(arc1, arc2)
circle.set_width(2 * radius)
circle.move_to(center)
return circle

View file

@ -0,0 +1,138 @@
from manim_imports_ext import *
def stereo_project_point(point, axis=0, r=1, max_norm=10000):
point = fdiv(point * r, point[axis] + r)
point[axis] = 0
norm = get_norm(point)
if norm > max_norm:
point *= max_norm / norm
return point
def sudanese_band_func(eta, phi):
z1 = math.sin(eta) * np.exp(complex(0, phi))
z2 = math.cos(eta) * np.exp(complex(0, phi / 2))
r4_point = np.array([z1.real, z1.imag, z2.real, z2.imag])
r4_point[:3] = rotate_vector(r4_point[:3], PI / 3, axis=[1, 1, 1])
return stereo_project_point(r4_point, axis=0)[1:]
def mobius_strip_func(u, phi):
vect = rotate_vector(RIGHT, phi / 2, axis=UP)
vect = rotate_vector(vect, phi, axis=OUT)
ref_point = np.array([np.cos(phi), np.sin(phi), 0])
return ref_point + 0.7 * (u - 0.5) * vect
def reversed_band(band_func):
return lambda x, phi: band_func(x, -phi)
def get_full_surface(band_func, x_range):
surface = ParametricSurface(
band_func, x_range, (0, TAU),
)
surface.set_color(BLUE_D)
surface.set_shadow(0.5)
surface.add_updater(lambda m: m.sort_faces_back_to_front(DOWN))
# surface = TexturedSurface(surface, "EarthTextureMap", "NightEarthTextureMap")
# surface = TexturedSurface(surface, "WaterColor")
# inv_surface = ParametricSurface(
# reversed_band(band_func), x_range[::-1], (0, TAU),
# )
m1, m2 = meshes = VGroup(
SurfaceMesh(surface, normal_nudge=1e-3),
SurfaceMesh(surface, normal_nudge=-1e-3),
)
bound = VGroup(
ParametricCurve(lambda t: band_func(x_range[0], t), (0, TAU)),
ParametricCurve(lambda t: band_func(x_range[1], t), (0, TAU)),
)
bound.set_stroke(RED, 3)
bound.apply_depth_test()
meshes.set_stroke(WHITE, 0.5, 0.5)
return Group(surface, m1, m2, bound)
return Group(surface, bound)
def get_sudanese_band(circle_on_xy_plane=False):
s_band = get_full_surface(
sudanese_band_func,
(0, PI),
)
angle = angle_of_vector(s_band[-1][0].get_start() - s_band[-1][1].get_start())
s_band.rotate(PI / 2 - angle)
if circle_on_xy_plane:
s_band.rotate(90 * DEGREES, DOWN)
s_band.shift(-s_band[-1][0].get_start())
return s_band
class SudaneseBand(ThreeDScene):
circle_on_xy_plane = True
def construct(self):
frame = self.camera.frame
frame.reorient(-45, 70)
frame.add_updater(
lambda m, dt: m.increment_theta(2 * dt * DEGREES)
)
self.add(frame)
s_band = get_sudanese_band(self.circle_on_xy_plane)
m_band = get_full_surface(mobius_strip_func, (0, 1))
for band in s_band, m_band:
band.set_height(6)
# self.play(ShowCreation(m_band[0]))
# self.play(
# FadeIn(m_band[1]),
# FadeIn(m_band[2]),
# ShowCreation(m_band[3]),
# )
self.add(m_band)
self.wait()
m_band.save_state()
self.play(
Transform(m_band, s_band),
run_time=8,
)
# self.wait()
self.play(frame.animate.reorient(-30, 110), run_time=4)
# self.play(frame.animate.reorient(-30, 70), run_time=3)
self.wait(2)
frame.clear_updaters()
self.play(
m_band.animate.restore(),
frame.animate.reorient(-45, 70),
run_time=8,
)
# self.embed()
class SudaneseBandToKleinBottle(ThreeDScene):
def construct(self):
frame = self.camera.frame
frame.reorient(-70, 70)
# frame.add_updater(
# lambda m, dt: m.increment_theta(2 * dt * DEGREES)
# )
# self.add(frame)
s_band = get_sudanese_band()
s_band[1:3].set_opacity(0)
circ = s_band[-1]
s_band.shift(-circ.get_center())
sb_copy = s_band.copy()
self.add(s_band)
self.play(
Rotate(sb_copy, PI, axis=RIGHT, about_point=ORIGIN),
run_time=4
)
self.play(frame.animate.reorient(360 - 70, 70), run_time=15)
self.wait()
self.embed()