Up to ShowHighVelocityCase in ode part 1

This commit is contained in:
Grant Sanderson
2019-03-25 09:47:45 -07:00
parent a166f6b214
commit 708451964a
4 changed files with 204 additions and 8 deletions

View File

@ -33,4 +33,8 @@ ALL_SCENE_CLASSES = [
VisualizeStates,
IntroduceVectorField,
BreakingSecondOrderIntoTwoFirstOrder,
ShowPendulumPhaseFlow,
ShowHighVelocityCase,
TweakMuInFormula,
TweakMuInVectorField,
]

View File

@ -90,6 +90,9 @@ class Pendulum(VGroup):
self.get_fixed_point() + self.length * DOWN,
**self.dashed_line_config
)
line.add_updater(
lambda l: l.move_to(self.get_fixed_point(), UP)
)
self.add_to_back(line)
def create_angle_arc(self):

View File

@ -439,6 +439,9 @@ class VisualizeStates(Scene):
top_point=rect.get_center(),
**self.big_pendulum_config
)
pendulum.fixed_point_tracker.add_updater(
lambda m: m.move_to(rect.get_center())
)
state = VGroup(rect, pendulum)
state.rect = rect
@ -514,7 +517,7 @@ class IntroduceVectorField(VisualizeStates):
# "delta_y": 2,
},
"big_pendulum_config": {
"initial_theta": -60 * DEGREES,
"initial_theta": -80 * DEGREES,
"omega": 1,
}
}
@ -840,21 +843,24 @@ class IntroduceVectorField(VisualizeStates):
bracket_v_buff=SMALL_BUFF,
element_to_mobject_config={
"tex_to_color_map": {
"{\\theta}": BLUE,
"{\\dot\\theta}": YELLOW,
"{\\omega}": YELLOW,
"{\\ddot\\theta}": RED,
}
},
},
element_alignment_corner=ORIGIN,
).scale(0.9)
def vector_field_func(self, point):
x, y = self.plane.point_to_coords(point)
pend = self.state.pendulum
mu, g, L = [
self.big_pendulum_config.get(key)
for key in ["damping", "gravity", "length"]
]
return pendulum_vector_field_func(
x * RIGHT + y * UP,
mu=pend.damping,
g=pend.gravity,
L=pend.length,
mu=mu, g=g, L=L
)
def ask_about_change(self):
@ -890,3 +896,114 @@ class IntroduceVectorField(VisualizeStates):
0.3 * d_vect.get_vector(),
rate_func=there_and_back,
)
class ShowPendulumPhaseFlow(IntroduceVectorField):
CONFIG = {
"coordinate_plane_config": {
"x_axis_config": {
"unit_size": 0.8,
},
"x_max": 9,
"x_min": -9,
},
"flow_time": 20,
}
def construct(self):
self.initialize_plane()
self.initialize_vector_field()
plane = self.plane
field = self.vector_field
self.add(plane, field)
stream_lines = StreamLines(
field.func,
delta_x=0.3,
delta_y=0.3,
)
animated_stream_lines = AnimatedStreamLines(
stream_lines,
line_anim_class=ShowPassingFlashWithThinningStrokeWidth,
)
self.add(animated_stream_lines)
self.wait(self.flow_time)
class ShowHighVelocityCase(ShowPendulumPhaseFlow, MovingCameraScene):
CONFIG = {
"coordinate_plane_config": {
"x_max": 15,
"x_min": -15,
},
"vector_field_config": {
"x_max": 15,
},
"big_pendulum_config": {
"max_velocity_vector_length_to_length_ratio": 1,
},
}
def setup(self):
MovingCameraScene.setup(self)
def construct(self):
self.initialize_plane()
self.add(self.plane)
self.initialize_vector_field()
self.add(self.vector_field)
self.add_flexible_state()
self.show_trajectory()
def show_trajectory(self):
state = self.state
plane = self.plane
field = self.vector_field
frame = self.camera_frame
state.to_edge(DOWN, buff=SMALL_BUFF),
start_point = plane.coords_to_point(0, 4)
dot = self.get_state_controlling_dot(state)
dot.move_to(start_point)
state.update()
traj = VMobject()
traj.start_new_path(start_point)
dt = 0.01
total_time = 25
for x in range(int(total_time / dt)):
end = traj.points[-1]
dp_dt = field.func(end)
traj.add_smooth_curve_to(end + dp_dt * dt)
traj.set_stroke(WHITE, 2)
self.add(traj, dot)
self.play(
ShowCreation(
traj,
rate_func=linear,
),
UpdateFromFunc(
dot, lambda d: d.move_to(traj.points[-1])
),
ApplyMethod(
frame.shift, TAU * RIGHT,
rate_func=squish_rate_func(
smooth, 0, 0.3,
)
),
MaintainPositionRelativeTo(state.rect, frame),
run_time=total_time,
)
class TweakMuInFormula(Scene):
def construct(self):
pass
class TweakMuInVectorField(Scene):
def construct(self):
pass

View File

@ -2,6 +2,7 @@ from big_ol_pile_of_manim_imports import *
from active_projects.ode.part1.shared_constructs import *
from active_projects.ode.part1.pendulum import Pendulum
from active_projects.ode.part1.pendulum import ThetaVsTAxes
from active_projects.ode.part1.phase_space import IntroduceVectorField
# Scenes
@ -764,9 +765,80 @@ class ReferencePiCollisionStateSpaces(Scene):
pass
class BreakingSecondOrderIntoTwoFirstOrder(Scene):
class BreakingSecondOrderIntoTwoFirstOrder(IntroduceVectorField):
def construct(self):
pass
ode = TexMobject(
"{\\ddot\\theta}", "(t)", "=",
"-\\mu", "{\\dot\\theta}", "(t)"
"-(g / L)\\sin\\big(", "{\\theta}", "(t)\\big)",
tex_to_color_map={
"{\\ddot\\theta}": RED,
"{\\dot\\theta}": YELLOW,
"{\\theta}": BLUE,
# "{t}": WHITE,
}
)
so_word = TextMobject("Second order ODE")
sys_word = TextMobject("System of two first order ODEs")
system1 = self.get_system("{\\theta}", "{\\dot\\theta}")
system2 = self.get_system("{\\theta}", "{\\omega}")
so_word.to_edge(UP)
ode.next_to(so_word, DOWN)
sys_word.move_to(ORIGIN)
system1.next_to(sys_word, DOWN)
system2.move_to(system1)
self.add(ode)
self.play(FadeInFrom(so_word, 0.5 * DOWN))
self.wait()
self.play(
TransformFromCopy(
ode[3:], system1[3].get_entries()[1],
),
TransformFromCopy(ode[2], system1[2]),
TransformFromCopy(
ode[:2], VGroup(
system1[0],
system1[1].get_entries()[1],
)
),
)
self.play(
FadeIn(system1[1].get_brackets()),
FadeIn(system1[1].get_entries()[0]),
FadeIn(system1[3].get_brackets()),
FadeIn(system1[3].get_entries()[0]),
)
self.play(
FadeInFromDown(sys_word)
)
self.wait()
self.play(ReplacementTransform(system1, system2))
self.wait()
def get_system(self, tex1, tex2):
system = VGroup(
TexMobject("d \\over dt"),
self.get_vector_symbol(
tex1 + "(t)",
tex2 + "(t)",
),
TexMobject("="),
self.get_vector_symbol(
tex2 + "(t)",
"".join([
"-\\mu", tex2, "(t)",
"-(g / L) \\sin\\big(",
tex1, "(t)", "\\big)",
])
)
)
system.arrange(RIGHT)
return system
class NewSceneName(Scene):