Files
manim/active_projects/lost_lecture.py
2018-07-12 19:53:30 -07:00

942 lines
28 KiB
Python

from __future__ import absolute_import
from big_ol_pile_of_manim_imports import *
class Orbiting(ContinualAnimation):
CONFIG = {
"rate": 0.3,
}
def __init__(self, planet, star, ellipse, **kwargs):
self.planet = planet
self.star = star
self.ellipse = ellipse
# Proportion of the way around the ellipse
self.proportion = 0
planet.move_to(ellipse.point_from_proportion(0))
ContinualAnimation.__init__(self, planet, **kwargs)
def update_mobject(self, dt):
# time = self.internal_time
rate = self.rate
planet = self.planet
star = self.star
ellipse = self.ellipse
rate *= 1 / np.linalg.norm(
planet.get_center() - star.get_center()
)
self.proportion += rate * dt
self.proportion = self.proportion % 1
planet.move_to(ellipse.point_from_proportion(self.proportion))
class SunAnimation(ContinualAnimation):
CONFIG = {
"rate": 0.2,
"angle": 60 * DEGREES,
}
def __init__(self, sun, **kwargs):
self.sun = sun
self.rotated_sun = sun.deepcopy()
self.rotated_sun.rotate(60 * DEGREES)
ContinualAnimation.__init__(
self, Group(sun, self.rotated_sun), **kwargs
)
def update_mobject(self, dt):
time = self.internal_time
a = (np.sin(self.rate * time * TAU) + 1) / 2.0
self.rotated_sun.rotate(-self.angle)
self.rotated_sun.move_to(self.sun)
self.rotated_sun.rotate(self.angle)
self.rotated_sun.pixel_array = np.array(
a * self.sun.pixel_array,
dtype=self.sun.pixel_array.dtype
)
class ShowWord(Animation):
CONFIG = {
"time_per_char": 0.06,
"rate_func": None,
}
def __init__(self, word, **kwargs):
assert(isinstance(word, SingleStringTexMobject))
digest_config(self, kwargs)
run_time = kwargs.pop(
"run_time",
self.time_per_char * len(word)
)
self.stroke_width = word.get_stroke_width()
Animation.__init__(self, word, run_time=run_time, **kwargs)
def update_mobject(self, alpha):
word = self.mobject
stroke_width = self.stroke_width
count = int(alpha * len(word))
remainder = (alpha * len(word)) % 1
word[:count].set_fill(opacity=1)
word[:count].set_stroke(width=stroke_width)
if count < len(word):
word[count].set_fill(opacity=remainder)
word[count].set_stroke(width=remainder * stroke_width)
word[count + 1:].set_fill(opacity=0)
word[count + 1:].set_stroke(width=0)
# Animations
class ShowEmergingEllipse(Scene):
CONFIG = {
"circle_radius": 3,
"circle_color": BLUE,
"num_lines": 150,
"lines_stroke_width": 1,
"eccentricity_vector": 2 * RIGHT,
"ghost_lines_stroke_color": LIGHT_GREY,
"ghost_lines_stroke_width": 0.5,
"ellipse_color": PINK,
}
def construct(self):
circle = self.get_circle()
e_point = self.get_eccentricity_point()
e_dot = Dot(e_point, color=YELLOW)
lines = self.get_lines()
ellipse = self.get_ellipse()
fade_rect = FullScreenFadeRectangle()
line = lines[len(lines) / 5]
line_dot = Dot(line.get_center(), color=YELLOW)
line_dot.scale(0.5)
ghost_line = self.get_ghost_lines(line)
ghost_lines = self.get_ghost_lines(lines)
rot_words = TextMobject("Rotate $90^\\circ$ \\\\ about center")
rot_words.next_to(line_dot, RIGHT)
elbow = VGroup(Line(UP, UL), Line(UL, LEFT))
elbow.set_stroke(width=1)
elbow.scale(0.2, about_point=ORIGIN)
elbow.rotate(
line.get_angle() - 90 * DEGREES,
about_point=ORIGIN
)
elbow.shift(line.get_center())
eccentric_words = TextMobject("``Eccentric'' point")
eccentric_words.next_to(circle.get_center(), DOWN)
ellipse_words = TextMobject("Perfect ellipse")
ellipse_words.next_to(ellipse, UP, SMALL_BUFF)
for text in rot_words, ellipse_words:
text.add_to_back(text.copy().set_stroke(BLACK, 5))
shuffled_lines = VGroup(*lines)
random.shuffle(shuffled_lines.submobjects)
self.play(ShowCreation(circle))
self.play(
FadeInAndShiftFromDirection(e_dot, LEFT),
Write(eccentric_words, run_time=1)
)
self.wait()
self.play(
LaggedStart(ShowCreation, shuffled_lines),
Animation(VGroup(e_dot, circle)),
FadeOut(eccentric_words)
)
self.add(ghost_lines)
self.add(e_dot, circle)
self.wait()
self.play(
FadeIn(fade_rect),
Animation(line),
GrowFromCenter(line_dot),
FadeInFromDown(rot_words),
)
self.wait()
self.add(ghost_line)
self.play(
MoveToTarget(line, path_arc=90 * DEGREES),
Animation(rot_words),
ShowCreation(elbow)
)
self.wait()
self.play(
FadeOut(fade_rect),
FadeOut(line_dot),
FadeOut(rot_words),
FadeOut(elbow),
Animation(line),
Animation(ghost_line)
)
self.play(
LaggedStart(MoveToTarget, lines, run_time=4),
Animation(VGroup(e_dot, circle))
)
self.wait()
self.play(
ShowCreation(ellipse),
FadeInFromDown(ellipse_words)
)
self.wait()
def get_circle(self):
circle = self.circle = Circle(
radius=self.circle_radius,
color=self.circle_color
)
return circle
def get_eccentricity_point(self):
return self.circle.get_center() + self.eccentricity_vector
def get_lines(self):
center = self.circle.get_center()
radius = self.circle.get_width() / 2
e_point = self.get_eccentricity_point()
lines = VGroup(*[
Line(
e_point,
center + rotate_vector(radius * RIGHT, angle)
)
for angle in np.linspace(0, TAU, self.num_lines)
])
lines.set_stroke(width=self.lines_stroke_width)
for line in lines:
line.generate_target()
line.target.rotate(90 * DEGREES)
return lines
def get_ghost_lines(self, lines):
return lines.copy().set_stroke(
color=self.ghost_lines_stroke_color,
width=self.ghost_lines_stroke_width
)
def get_ellipse(self):
center = self.circle.get_center()
e_point = self.get_eccentricity_point()
radius = self.circle.get_width() / 2
# Ellipse parameters
a = radius / 2
c = np.linalg.norm(e_point - center) / 2
b = np.sqrt(a**2 - c**2)
result = Circle(radius=b, color=self.ellipse_color)
result.stretch(a / b, 0)
result.move_to(Line(center, e_point))
return result
class FeynmanAndOrbitingPlannetOnEllipseDiagram(ShowEmergingEllipse):
def construct(self):
circle = self.get_circle()
lines = self.get_lines()
ghost_lines = self.get_ghost_lines(lines)
for line in lines:
MoveToTarget(line).update(1)
ellipse = self.get_ellipse()
e_dot = Dot(self.get_eccentricity_point())
e_dot.set_color(YELLOW)
comet = ImageMobject("earth")
comet.scale_to_fit_width(0.3)
feynman = ImageMobject("Feynman")
feynman.scale_to_fit_height(6)
feynman.next_to(ORIGIN, LEFT)
feynman.to_edge(UP)
feynman_name = TextMobject("Richard Feynman")
feynman_name.next_to(feynman, DOWN)
feynman.save_state()
feynman.shift(2 * DOWN)
feynman_rect = BackgroundRectangle(
feynman, fill_opacity=1
)
group = VGroup(circle, ghost_lines, lines, e_dot, ellipse)
self.add(group)
self.add(Orbiting(comet, e_dot, ellipse))
self.add_foreground_mobjects(comet)
self.wait()
self.play(
feynman.restore,
MaintainPositionRelativeTo(feynman_rect, feynman),
VFadeOut(feynman_rect),
group.to_edge, RIGHT,
)
self.play(Write(feynman_name))
self.wait()
self.wait(10)
class FeynmanFame(Scene):
def construct(self):
books = VGroup(
ImageMobject("Feynman_QED_cover"),
ImageMobject("Surely_Youre_Joking_cover"),
ImageMobject("Feynman_Lectures_cover"),
)
for book in books:
book.scale_to_fit_height(6)
book.move_to(FRAME_WIDTH * LEFT / 4)
feynman_diagram = self.get_feynman_diagram()
feynman_diagram.next_to(ORIGIN, RIGHT)
fd_parts = VGroup(*reversed(feynman_diagram.family_members_with_points()))
# As a physicist
self.play(self.get_book_intro(books[0]))
self.play(LaggedStart(
Write, feynman_diagram,
run_time=4
))
self.wait()
self.play(
self.get_book_intro(books[1]),
self.get_book_outro(books[0]),
LaggedStart(
ApplyMethod, fd_parts,
lambda m: (m.scale, 0),
run_time=1
),
)
self.remove(feynman_diagram)
self.wait()
# As a public figure
safe = SVGMobject(file_name="safe", height=2)
safe_rect = SurroundingRectangle(safe, buff=0)
safe_rect.set_stroke(width=0)
safe_rect.set_fill(DARK_GREY, 1)
safe.add_to_back(safe_rect)
bongo = SVGMobject(file_name="bongo")
bongo.scale_to_fit_height(1)
bongo.set_color(WHITE)
bongo.next_to(safe, RIGHT, LARGE_BUFF)
objects = VGroup(safe, bongo)
feynman_smile = ImageMobject("Feynman_Los_Alamos")
feynman_smile.match_width(objects)
feynman_smile.next_to(objects, DOWN)
VGroup(objects, feynman_smile).next_to(ORIGIN, RIGHT)
joke = TextMobject(
"``Science is the belief \\\\ in the ignorance of \\\\ experts.''"
)
joke.move_to(objects)
self.play(LaggedStart(
DrawBorderThenFill, objects,
lag_ratio=0.75
))
self.play(self.get_book_intro(feynman_smile))
self.wait()
self.play(
objects.shift, 2 * UP,
VFadeOut(objects)
)
self.play(Write(joke))
self.wait(2)
self.play(
self.get_book_intro(books[2]),
self.get_book_outro(books[1]),
LaggedStart(FadeOut, joke, run_time=1),
ApplyMethod(
feynman_smile.shift, FRAME_HEIGHT * DOWN,
remover=True
)
)
# As a teacher
feynman_teacher = ImageMobject("Feynman_teaching")
feynman_teacher.scale_to_fit_width(FRAME_WIDTH / 2 - 1)
feynman_teacher.next_to(ORIGIN, RIGHT)
self.play(self.get_book_intro(feynman_teacher))
self.wait(3)
def get_book_animation(self, book,
initial_shift,
animated_shift,
opacity_func
):
rect = BackgroundRectangle(book, fill_opacity=1)
book.shift(initial_shift)
return AnimationGroup(
ApplyMethod(book.shift, animated_shift),
UpdateFromAlphaFunc(
rect, lambda r, a: r.move_to(book).set_fill(
opacity=opacity_func(a)
),
remover=True
)
)
def get_book_intro(self, book):
return self.get_book_animation(
book, 2 * DOWN, 2 * UP, lambda a: 1 - a
)
def get_book_outro(self, book):
return ApplyMethod(book.shift, FRAME_HEIGHT * UP, remover=True)
def get_feynman_diagram(self):
x_min = -1.5
x_max = 1.5
arrow = Arrow(LEFT, RIGHT, buff=0, use_rectangular_stem=False)
arrow.tip.move_to(arrow.get_center())
arrows = VGroup(*[
arrow.copy().rotate(angle).next_to(point, vect, buff=0)
for (angle, point, vect) in [
(-45 * DEGREES, x_min * RIGHT, UL),
(-135 * DEGREES, x_min * RIGHT, DL),
(-135 * DEGREES, x_max * RIGHT, UR),
(-45 * DEGREES, x_max * RIGHT, DR),
]
])
labels = VGroup(*[
TexMobject(tex)
for tex in ["e^-", "e^+", "\\text{\\=q}", "q"]
])
vects = [UR, DR, UL, DL]
for arrow, label, vect in zip(arrows, labels, vects):
label.next_to(arrow.get_center(), vect, buff=SMALL_BUFF)
wave = FunctionGraph(
lambda x: 0.2 * np.sin(2 * TAU * x),
x_min=x_min,
x_max=x_max,
)
wave_label = TexMobject("\\gamma")
wave_label.next_to(wave, UP, SMALL_BUFF)
labels.add(wave_label)
squiggle = ParametricFunction(
lambda t: np.array([
t + 0.5 * np.sin(TAU * t),
0.5 * np.cos(TAU * t),
0,
]),
t_min=0,
t_max=4,
)
squiggle.scale(0.25)
squiggle.set_color(BLUE)
squiggle.rotate(-30 * DEGREES)
squiggle.next_to(
arrows[2].point_from_proportion(0.75),
DR, buff=0
)
squiggle_label = TexMobject("g")
squiggle_label.next_to(squiggle, UR, buff=-MED_SMALL_BUFF)
labels.add(squiggle_label)
return VGroup(arrows, wave, squiggle, labels)
class FeynmanLecturesScreenCaptureFrame(Scene):
def construct(self):
url = TextMobject("http://www.feynmanlectures.caltech.edu/")
url.to_edge(UP)
screen_rect = ScreenRectangle(height=6)
screen_rect.next_to(url, DOWN)
self.add(url)
self.play(ShowCreation(screen_rect))
self.wait()
class TheMotionOfPlanets(Scene):
CONFIG = {
"camera_config": {"background_opacity": 1},
"random_seed": 2,
}
def construct(self):
self.add_title()
self.setup_orbits()
def add_title(self):
title = TextMobject("``The motion of planets around the sun''")
title.set_color(YELLOW)
title.to_edge(UP)
title.add_to_back(title.copy().set_stroke(BLACK, 5))
self.add(title)
self.title = title
def setup_orbits(self):
sun = ImageMobject("sun")
sun.scale_to_fit_height(0.7)
planets, ellipses, orbits = self.get_planets_ellipses_and_orbits(sun)
archivist_words = TextMobject(
"Judith Goodstein (Caltech archivist)"
)
archivist_words.to_corner(UL)
archivist_words.shift(1.5 * DOWN)
archivist_words.add_background_rectangle()
alt_name = TextMobject("David Goodstein (Caltech physicist)")
alt_name.next_to(archivist_words, DOWN, aligned_edge=LEFT)
alt_name.add_background_rectangle()
book = ImageMobject("Lost_Lecture_cover")
book.scale_to_fit_height(4)
book.next_to(alt_name, DOWN)
self.add(SunAnimation(sun))
self.add(ellipses, planets)
self.add(self.title)
self.add(*orbits)
self.add_foreground_mobjects(planets)
self.wait(10)
self.play(
VGroup(ellipses, sun).shift, 3 * RIGHT,
FadeInFromDown(archivist_words),
Animation(self.title)
)
self.add_foreground_mobjects(archivist_words)
self.wait(3)
self.play(FadeInFromDown(alt_name))
self.add_foreground_mobjects(alt_name)
self.wait()
self.play(FadeInFromDown(book))
self.wait(15)
def get_planets_ellipses_and_orbits(self, sun):
planets = VGroup(
ImageMobject("mercury"),
ImageMobject("venus"),
ImageMobject("earth"),
ImageMobject("mars"),
ImageMobject("comet")
)
sizes = [0.383, 0.95, 1.0, 0.532, 0.3]
orbit_radii = [0.254, 0.475, 0.656, 1.0, 3.0]
orbit_eccentricies = [0.206, 0.006, 0.0167, 0.0934, 0.967]
for planet, size in zip(planets, sizes):
planet.scale_to_fit_height(0.5)
planet.scale(size)
ellipses = VGroup(*[
Circle(radius=r, color=WHITE, stroke_width=1)
for r in orbit_radii
])
for circle, ec in zip(ellipses, orbit_eccentricies):
a = circle.get_height() / 2
c = ec * a
b = np.sqrt(a**2 - c**2)
circle.stretch(b / a, 1)
c = np.sqrt(a**2 - b**2)
circle.shift(c * RIGHT)
for circle in ellipses:
circle.rotate(
TAU * np.random.random(),
about_point=ORIGIN
)
ellipses.scale(3.5, about_point=ORIGIN)
orbits = [
Orbiting(
planet, sun, circle,
rate=0.25 * r**(2 / 3)
)
for planet, circle, r in zip(planets, ellipses, orbit_radii)
]
orbits[-1].proportion = 0.15
orbits[-1].rate = 0.5
return planets, ellipses, orbits
class AskAboutEllipses(TheMotionOfPlanets):
CONFIG = {
"camera_config": {"background_opacity": 1},
"animate_sun": True,
}
def construct(self):
self.add_title()
self.add_sun()
self.add_orbit()
self.add_focus_lines()
self.add_force_labels()
self.comment_on_imperfections()
self.set_up_differential_equations()
def add_title(self):
title = Title("Why are orbits ellipses?")
self.add(title)
self.title = title
def add_sun(self):
sun = ImageMobject("sun", height=0.5)
self.sun = sun
self.add(sun)
if self.animate_sun:
self.add(SunAnimation(sun))
def add_orbit(self):
sun = self.sun
comet = ImageMobject("comet")
comet.scale_to_fit_height(0.2)
ellipse = self.get_ellipse()
orbit = Orbiting(comet, sun, ellipse)
self.add(ellipse)
self.add(orbit)
self.ellipse = ellipse
self.comet = comet
self.orbit = orbit
def add_focus_lines(self):
f1, f2 = self.focus_points
comet = self.comet
lines = VGroup(Line(LEFT, RIGHT), Line(LEFT, RIGHT))
lines.set_stroke(LIGHT_GREY, 1)
def update_lines(lines):
l1, l2 = lines
P = comet.get_center()
l1.put_start_and_end_on(f1, P)
l2.put_start_and_end_on(f2, P)
return lines
animation = ContinualUpdateFromFunc(
lines, update_lines
)
self.add(animation)
self.wait(8)
self.focus_lines = lines
self.focus_lines_animation = animation
def add_force_labels(self):
radial_line = self.focus_lines[0]
# Radial line measurement
radius_measurement_kwargs = {
"num_decimal_places": 3,
"color": BLUE,
}
radius_measurement = DecimalNumber(1, **radius_measurement_kwargs)
def update_radial_measurement(measurement):
angle = -radial_line.get_angle() + np.pi
radial_line.rotate(angle, about_point=ORIGIN)
new_decimal = DecimalNumber(
radial_line.get_length(),
**radius_measurement_kwargs
)
max_width = 0.6 * radial_line.get_width()
if new_decimal.get_width() > max_width:
new_decimal.scale_to_fit_width(max_width)
new_decimal.next_to(radial_line, UP, SMALL_BUFF)
VGroup(new_decimal, radial_line).rotate(
-angle, about_point=ORIGIN
)
Transform(measurement, new_decimal).update(1)
radius_measurement_animation = ContinualUpdateFromFunc(
radius_measurement, update_radial_measurement
)
# Force equation
force_equation = TexMobject(
"F = {GMm \\over (0.000)^2}",
tex_to_color_map={
"F": YELLOW,
"0.000": BLACK,
}
)
force_equation.next_to(self.title, DOWN)
force_equation.to_edge(RIGHT)
radius_in_denominator_ref = force_equation.get_part_by_tex("0.000")
radius_in_denominator = DecimalNumber(
0, **radius_measurement_kwargs
)
radius_in_denominator.scale(0.95)
update_radius_in_denominator = ContinualChangingDecimal(
radius_in_denominator,
lambda a: radial_line.get_length(),
position_update_func=lambda mob: mob.move_to(
radius_in_denominator_ref, LEFT
)
)
# Force arrow
force_arrow = Arrow(LEFT, RIGHT, color=YELLOW)
def update_force_arrow(arrow):
radius = radial_line.get_length()
# target_length = 1 / radius**2
target_length = 1 / radius # Lies!
arrow.scale(
target_length / arrow.get_length()
)
arrow.rotate(
np.pi + radial_line.get_angle() - arrow.get_angle()
)
arrow.shift(
radial_line.get_end() - arrow.get_start()
)
force_arrow_animation = ContinualUpdateFromFunc(
force_arrow, update_force_arrow
)
inverse_square_law_words = TextMobject(
"``Inverse square law''"
)
inverse_square_law_words.next_to(force_equation, DOWN, MED_LARGE_BUFF)
inverse_square_law_words.to_edge(RIGHT)
force_equation.next_to(inverse_square_law_words, UP, MED_LARGE_BUFF)
def v_fade_in(mobject):
return UpdateFromAlphaFunc(
mobject,
lambda mob, alpha: mob.set_fill(opacity=alpha)
)
self.add(update_radius_in_denominator)
self.add(radius_measurement_animation)
self.play(
FadeIn(force_equation),
v_fade_in(radius_in_denominator),
v_fade_in(radius_measurement)
)
self.add(force_arrow_animation)
self.play(v_fade_in(force_arrow))
self.wait(8)
self.play(Write(inverse_square_law_words))
self.wait(9)
self.force_equation = force_equation
self.inverse_square_law_words = inverse_square_law_words
self.force_arrow = force_arrow
self.radius_measurement = radius_measurement
def comment_on_imperfections(self):
planets, ellipses, orbits = self.get_planets_ellipses_and_orbits(self.sun)
orbits.pop(-1)
ellipses.submobjects.pop(-1)
planets.submobjects.pop(-1)
scale_factor = 20
center = self.sun.get_center()
ellipses.save_state()
ellipses.scale(scale_factor, about_point=center)
self.add(*orbits)
self.play(ellipses.restore, Animation(planets))
self.wait(7)
self.play(
ellipses.scale, scale_factor, {"about_point": center},
Animation(planets)
)
self.remove(*orbits)
self.remove(planets, ellipses)
self.wait(2)
def set_up_differential_equations(self):
d_dt = TexMobject("{d \\over dt}")
in_vect = Matrix(np.array([
"x(t)",
"y(t)",
"\\dot{x}(t)",
"\\dot{y}(t)",
]))
equals = TexMobject("=")
out_vect = Matrix(np.array([
"\\dot{x}(t)",
"\\dot{y}(t)",
"-x(t) / (x(t)^2 + y(t)^2)^{3/2}",
"-y(t) / (x(t)^2 + y(t)^2)^{3/2}",
]), element_alignment_corner=ORIGIN)
equation = VGroup(d_dt, in_vect, equals, out_vect)
equation.arrange_submobjects(RIGHT, buff=SMALL_BUFF)
equation.scale_to_fit_width(6)
equation.to_corner(DR, buff=MED_LARGE_BUFF)
cross = Cross(equation)
self.play(Write(equation))
self.wait(6)
self.play(ShowCreation(cross))
self.wait(6)
# Helpers
def get_ellipse(self):
a = 7.0
b = 4.0
c = np.sqrt(a**2 - b**2)
ellipse = Circle(radius=a / 2)
ellipse.set_stroke(WHITE, 1)
ellipse.stretch(b / a, dim=1)
ellipse.move_to(
self.sun.get_center() + c * LEFT / 2
)
self.focus_points = [
self.sun.get_center(),
self.sun.get_center() + c * LEFT,
]
return ellipse
class FeynmanElementaryQuote(Scene):
def construct(self):
quote_text = """
\\large
I am going to give what I will call an
\\emph{elementary} demonstration. But elementary
does not mean easy to understand. Elementary
means that very little is required
to know ahead of time in order to understand it,
except to have an infinite amount of intelligence.
"""
quote_parts = filter(lambda s: s, quote_text.split(" "))
quote = TextMobject(
*quote_parts,
tex_to_color_map={
"\\emph{elementary}": BLUE,
"elementary": BLUE,
"Elementary": BLUE,
"infinite": YELLOW,
"amount": YELLOW,
"of": YELLOW,
"intelligence": YELLOW,
"very": RED,
"little": RED,
},
alignment=""
)
quote[-1].shift(2 * SMALL_BUFF * LEFT)
quote.scale_to_fit_width(FRAME_WIDTH - 1)
quote.to_edge(UP)
quote.get_part_by_tex("of").set_color(WHITE)
nothing = TextMobject("nothing")
nothing.scale(0.9)
very = quote.get_part_by_tex("very")
nothing.shift(very[0].get_left() - nothing[0].get_left())
nothing.set_color(RED)
for word in quote:
if word is very:
self.add_foreground_mobjects(nothing)
self.play(ShowWord(nothing))
self.wait(0.2)
nothing.sort_submobjects(lambda p: -p[0])
self.play(LaggedStart(
FadeOut, nothing,
run_time=1
))
self.remove_foreground_mobject(nothing)
back_word = word.copy().set_stroke(BLACK, 5)
self.add_foreground_mobjects(back_word, word)
self.play(
ShowWord(back_word),
ShowWord(word),
)
self.wait(0.005 * len(word)**1.5)
class LostLecturePicture(TODOStub):
CONFIG = {"camera_config": {"background_opacity": 1}}
def construct(self):
picture = ImageMobject("Feynman_teaching")
picture.scale_to_fit_height(FRAME_WIDTH)
picture.to_corner(UL, buff=0)
picture.fade(0.5)
self.play(
picture.to_corner, DR, {"buff": 0},
picture.shift, 1.5 * DOWN,
path_arc=60 * DEGREES,
run_time=20,
rate_func=bezier([0, 0, 1, 1])
)
class AskAboutInfiniteIntelligence(TeacherStudentsScene):
def construct(self):
self.student_says(
"Infinite intelligence?",
target_mode="confused"
)
self.play(
self.get_student_changes("horrified", "confused", "sad"),
self.teacher.change, "happy",
)
self.wait()
self.teacher_says(
"It's not too bad, \\\\ but stay focused",
added_anims=[self.get_student_changes(*["happy"] * 3)]
)
self.wait()
self.look_at(self.screen)
self.wait(5)
class ShowEllipseDefiningProperty(Scene):
CONFIG = {
"ellipse_color": BLUE,
"a": 4.0,
"b": 3.0,
}
def construct(self):
self.add_ellipse()
self.add_focal_lines()
self.add_distance_labels()
self.show_constant_sum()
self.label_foci()
self.label_focal_sum()
def add_ellipse(self):
a = self.a
b = self.b
c = np.sqrt(a**2 - b**2)
ellipse = Circle(radius=a, color=self.ellipse_color)
ellipse.stretch(fdiv(b, a), dim=1)
self.foci = [c * LEFT, c * RIGHT]
self.ellipse = ellipse
self.add(ellipse)
def add_focal_lines(self):
pass
def add_distance_labels(self):
pass
def show_constant_sum(self):
pass
def label_foci(self):
pass
def label_focal_sum(self):
pass