More ode part1 scenes

This commit is contained in:
Grant Sanderson
2019-03-20 17:38:25 -07:00
parent 27200f79d3
commit 8681e18c42
5 changed files with 326 additions and 115 deletions

View File

@ -1,15 +1,21 @@
from active_projects.ode.part1.pendulum import *
from active_projects.ode.part1.staging import *
from active_projects.ode.part1.pi_scenes import *
OUTPUT_DIRECTORY = "ode/part1"
ALL_SCENE_CLASSES = [
IntroducePendulum,
MultiplePendulumsOverlayed,
# FormulasAreLies,
FormulasAreLies,
MediumAnglePendulum,
MediumHighAnglePendulum,
HighAnglePendulum,
LowAnglePendulum,
SomeOfYouWatching,
SmallAngleApproximationTex,
VeryLowAnglePendulum,
FollowThisThread,
StrogatzQuote,
# Tests
PendulumTest,
VectorFieldTest,

View File

@ -1,13 +1,5 @@
from big_ol_pile_of_manim_imports import *
Lg_formula_config = {
"tex_to_color_map": {
"\\theta_0": WHITE,
"{L}": BLUE,
"{g}": YELLOW,
},
}
from active_projects.ode.part1.shared_constructs import *
class Pendulum(VGroup):
@ -828,36 +820,30 @@ class HighAnglePendulum(LowAnglePendulum):
}
class PendulumTest(Scene):
def construct(self):
pendulum = Pendulum(
initial_theta=170 * DEGREES,
top_point=ORIGIN,
damping=0
)
pendulum.add_velocity_vector()
pendulum.add_theta_label()
gravity_vector = GravityVector(pendulum)
gravity_vector.add_component_lines()
axes = ThetaVsTAxes(
y_max=PI,
y_min=-PI,
y_axis_config={
"unit_size": 0.7,
"tick_frequency": PI / 4,
class VeryLowAnglePendulum(LowAnglePendulum):
CONFIG = {
"pendulum_config": {
"initial_theta": 10 * DEGREES,
"n_steps_per_frame": 1000,
"top_point": ORIGIN,
"length": 3,
},
x_max=14
)
axes.to_corner(UL)
axes.add_live_drawn_graph(pendulum)
"axes_config": {
"y_axis_config": {"unit_size": 2},
"y_max": PI / 4,
"y_min": -PI / 4,
"number_line_config": {
"tip_length": 0.3,
"stroke_width": 2,
}
},
"pendulum_shift_vect": 1 * RIGHT,
}
self.add(pendulum, gravity_vector)
self.add(axes)
pendulum.start_swinging()
self.wait(14)
class BuildUpEquation(Scene):
def construct(self):
pass
class NewSceneName(Scene):

View File

@ -0,0 +1,108 @@
from big_ol_pile_of_manim_imports import *
from active_projects.ode.part1.shared_constructs import *
class SomeOfYouWatching(TeacherStudentsScene):
CONFIG = {
"camera_config": {
"background_color": DARKER_GREY,
}
}
def construct(self):
screen = self.screen
screen.scale(1.25, about_edge=UL)
screen.set_fill(BLACK, 1)
self.add(screen)
self.teacher.change("raise_right_hand")
for student in self.students:
student.change("pondering", screen)
self.student_says(
"Well...yeah",
target_mode="tease"
)
self.wait(3)
class FormulasAreLies(PiCreatureScene):
def construct(self):
you = self.pi_creature
t2c = {
"{L}": BLUE,
"{g}": YELLOW,
"\\theta_0": WHITE,
"\\sqrt{\\,": WHITE,
}
kwargs = {"tex_to_color_map": t2c}
period_eq = TexMobject(
"\\text{Period} = 2\\pi \\sqrt{\\,{L} / {g}}",
**kwargs
)
theta_eq = TexMobject(
"\\theta(t) = \\theta_0 \\cos\\left("
"\\sqrt{\\,{L} / {g}} \\cdot t"
"\\right)",
**kwargs
)
equations = VGroup(theta_eq, period_eq)
equations.arrange(DOWN, buff=LARGE_BUFF)
for eq in period_eq, theta_eq:
i = eq.index_of_part_by_tex("\\sqrt")
eq.sqrt_part = eq[i:i + 4]
theta0 = theta_eq.get_part_by_tex("\\theta_0")
theta0_words = TextMobject("Starting angle")
theta0_words.next_to(theta0, UL)
theta0_words.shift(UP + 0.5 * RIGHT)
arrow = Arrow(
theta0_words.get_bottom(),
theta0,
color=WHITE,
tip_length=0.25,
)
bubble = SpeechBubble()
bubble.pin_to(you)
bubble.write("Lies!")
bubble.content.scale(2)
bubble.resize_to_content()
self.add(period_eq)
you.change("pondering", period_eq)
self.wait()
theta_eq.remove(*theta_eq.sqrt_part)
self.play(
TransformFromCopy(
period_eq.sqrt_part,
theta_eq.sqrt_part,
),
FadeIn(theta_eq)
)
theta_eq.add(*theta_eq.sqrt_part)
self.play(
FadeInFrom(theta0_words, LEFT),
GrowArrow(arrow),
)
self.wait()
self.play(you.change, "confused")
self.wait(0)
self.play(
you.change, "angry",
ShowCreation(bubble),
FadeInFromPoint(bubble.content, you.mouth),
equations.to_edge, LEFT,
FadeOut(arrow),
FadeOut(theta0_words),
)
self.wait()
def create_pi_creature(self):
return You().flip().to_corner(DR)
class NewSceneName(Scene):
def construct(self):
pass

View File

@ -0,0 +1,16 @@
from big_ol_pile_of_manim_imports import *
Lg_formula_config = {
"tex_to_color_map": {
"\\theta_0": WHITE,
"{L}": BLUE,
"{g}": YELLOW,
},
}
class You(PiCreature):
CONFIG = {
"color": BLUE_C,
}

View File

@ -1,4 +1,5 @@
from big_ol_pile_of_manim_imports import *
from active_projects.ode.part1.shared_constructs import *
def pendulum_vector_field(point, mu=0.1, g=9.8, L=3):
@ -44,83 +45,177 @@ class VectorFieldTest(Scene):
self.wait(10)
class FormulasAreLies(PiCreatureScene):
class SmallAngleApproximationTex(Scene):
def construct(self):
morty = self.pi_creature
t2c = {
"{L}": BLUE,
"{g}": YELLOW,
"\\theta_0": WHITE,
"\\sqrt{\\,": WHITE,
approx = TexMobject(
"\\sin", "(", "\\theta", ") \\approx \\theta",
tex_to_color_map={"\\theta": RED},
arg_separator="",
)
implies = TexMobject("\\Downarrow")
period = TexMobject(
"\\text{Period}", "\\approx",
"2\\pi \\sqrt{\\,{L} / {g}}",
**Lg_formula_config,
)
group = VGroup(approx, implies, period)
group.arrange(DOWN)
approx_brace = Brace(approx, UP, buff=SMALL_BUFF)
approx_words = TextMobject(
"For small $\\theta$",
tex_to_color_map={"$\\theta$": RED},
)
approx_words.scale(0.75)
approx_words.next_to(approx_brace, UP, SMALL_BUFF)
self.add(approx, approx_brace, approx_words)
self.play(
Write(implies),
FadeInFrom(period, LEFT)
)
self.wait()
class FollowThisThread(Scene):
CONFIG = {
"screen_rect_style": {
"stroke_width": 2,
"stroke_color": WHITE,
"fill_opacity": 1,
"fill_color": DARKER_GREY,
}
}
kwargs = {"tex_to_color_map": t2c}
period_eq = TexMobject(
"\\text{Period} = 2\\pi \\sqrt{\\,{L} / {g}}",
**kwargs
)
theta_eq = TexMobject(
"\\theta(t) = \\theta_0 \\cos\\left("
"\\sqrt{\\,{L} / {g}} \\cdot t"
"\\right)",
**kwargs
)
equations = VGroup(theta_eq, period_eq)
equations.arrange(DOWN, buff=LARGE_BUFF)
for eq in period_eq, theta_eq:
i = eq.index_of_part_by_tex("\\sqrt")
eq.sqrt_part = eq[i:i + 4]
theta0 = theta_eq.get_part_by_tex("\\theta_0")
theta0_words = TextMobject("Starting angle")
theta0_words.next_to(theta0, UL)
theta0_words.shift(UP + 0.5 * RIGHT)
arrow = Arrow(
theta0_words.get_bottom(),
theta0,
color=WHITE,
tip_length=0.25,
)
bubble = SpeechBubble()
bubble.pin_to(morty)
bubble.write("Lies!")
bubble.content.scale(2)
bubble.resize_to_content()
self.add(period_eq)
morty.change("pondering", period_eq)
self.wait()
theta_eq.remove(*theta_eq.sqrt_part)
self.play(
TransformFromCopy(
period_eq.sqrt_part,
theta_eq.sqrt_part,
),
FadeIn(theta_eq)
)
theta_eq.add(*theta_eq.sqrt_part)
self.play(
FadeInFrom(theta0_words, LEFT),
GrowArrow(arrow),
)
self.wait()
self.play(morty.change, "confused")
self.wait(0)
self.play(
morty.change, "angry",
ShowCreation(bubble),
FadeInFromPoint(bubble.content, morty.mouth),
equations.to_edge, LEFT,
FadeOut(arrow),
FadeOut(theta0_words),
)
self.wait()
def create_pi_creature(self):
return Mortimer().to_corner(DR)
class NewSceneName(Scene):
def construct(self):
pass
self.show_thumbnails()
self.show_words()
def show_thumbnails(self):
# TODO, replace each of these with a picture?
thumbnails = self.thumbnails = VGroup(
ScreenRectangle(**self.screen_rect_style),
ScreenRectangle(**self.screen_rect_style),
ScreenRectangle(**self.screen_rect_style),
ScreenRectangle(**self.screen_rect_style),
ScreenRectangle(**self.screen_rect_style),
)
n = len(thumbnails)
thumbnails.set_height(1.5)
line = self.line = CubicBezier([
[-5, 3, 0],
[3, 3, 0],
[-3, -3, 0],
[5, -3, 0],
])
for thumbnail, a in zip(thumbnails, np.linspace(0, 1, n)):
thumbnail.move_to(line.point_from_proportion(a))
self.play(
ShowCreation(
line,
rate_func=lambda t: np.clip(t * (n + 1) / n, 0, 1)
),
LaggedStart(*[
GrowFromCenter(
thumbnail,
rate_func=squish_rate_func(
smooth,
0, 0.7,
)
)
for thumbnail in thumbnails
], lag_ratio=1),
run_time=5
)
def show_words(self):
words = VGroup(
TextMobject("Generalize"),
TextMobject("Put in context"),
TextMobject("Modify"),
)
# words.arrange(DOWN, aligned_edge=LEFT, buff=LARGE_BUFF)
words.scale(1.5)
words.to_corner(UR)
words.add_to_back(VectorizedPoint(words.get_center()))
words.add(VectorizedPoint(words.get_center()))
diffEq = TextMobject("Differential\\\\equations")
diffEq.scale(1.5)
diffEq.to_corner(DL, buff=LARGE_BUFF)
for word1, word2 in zip(words, words[1:]):
self.play(
FadeInFromDown(word2),
FadeOutAndShift(word1, UP),
)
self.wait()
self.play(
ReplacementTransform(
VGroup(self.thumbnails).copy().fade(1),
diffEq,
lag_ratio=0.01,
)
)
self.wait()
class StrogatzQuote(Scene):
def construct(self):
law_words = "laws of physics"
language_words = "language of differential equations"
author = "-Steven Strogatz"
quote = TextMobject(
"""
\\Large
``Since Newton, mankind has come to realize
that the laws of physics are always expressed
in the language of differential equations.''\\\\
""" + author,
alignment="",
arg_separator=" ",
substrings_to_isolate=[law_words, language_words, author]
)
law_part = quote.get_part_by_tex(law_words)
language_part = quote.get_part_by_tex(language_words)
author_part = quote.get_part_by_tex(author)
quote.set_width(12)
quote.to_edge(UP)
quote[-2].shift(SMALL_BUFF * LEFT)
author_part.shift(RIGHT + 0.5 * DOWN)
author_part.scale(1.2, about_edge=UL)
movers = VGroup(*quote[:-1].family_members_with_points())
for mover in movers:
mover.save_state()
disc = Circle(radius=0.05)
disc.set_stroke(width=0)
disc.set_fill(BLACK, 0)
disc.move_to(mover)
mover.become(disc)
self.play(
FadeInFrom(author_part, LEFT),
LaggedStartMap(
# FadeInFromLarge,
# quote[:-1].family_members_with_points(),
Restore, movers,
lag_ratio=0.005,
run_time=2,
)
# FadeInFromDown(quote[:-1]),
# lag_ratio=0.01,
)
self.wait()
self.play(
Write(law_part.copy().set_color(YELLOW)),
run_time=1,
)
self.wait()
self.play(
Write(language_part.copy().set_color(BLUE)),
run_time=1.5,
)
self.wait(2)