mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Up to GraphCarTrajectory of eoc chapter 2
This commit is contained in:
parent
740eba856d
commit
a7720f308d
2 changed files with 210 additions and 15 deletions
176
eoc/chapter2.py
176
eoc/chapter2.py
|
@ -377,16 +377,22 @@ class GraphCarTrajectory(GraphScene):
|
||||||
graph = self.graph_function(lambda t : 100*smooth(t/10.))
|
graph = self.graph_function(lambda t : 100*smooth(t/10.))
|
||||||
origin = self.coords_to_point(0, 0)
|
origin = self.coords_to_point(0, 0)
|
||||||
|
|
||||||
|
self.introduce_graph(graph, origin)
|
||||||
|
self.comment_on_slope(graph, origin)
|
||||||
|
self.show_velocity_graph()
|
||||||
|
self.ask_critically_about_velocity()
|
||||||
|
|
||||||
|
def introduce_graph(self, graph, origin):
|
||||||
h_line, v_line = [
|
h_line, v_line = [
|
||||||
Line(origin, origin, color = color, stroke_width = 2)
|
Line(origin, origin, color = color, stroke_width = 2)
|
||||||
for color in MAROON_B, YELLOW
|
for color in MAROON_B, YELLOW
|
||||||
]
|
]
|
||||||
def h_update(h_line):
|
def h_update(h_line, proportion = 1):
|
||||||
end = graph.points[-1]
|
end = graph.point_from_proportion(proportion)
|
||||||
t_axis_point = end[0]*RIGHT + origin[1]*UP
|
t_axis_point = end[0]*RIGHT + origin[1]*UP
|
||||||
h_line.put_start_and_end_on(t_axis_point, end)
|
h_line.put_start_and_end_on(t_axis_point, end)
|
||||||
def v_update(v_line):
|
def v_update(v_line, proportion = 1):
|
||||||
end = graph.points[-1]
|
end = graph.point_from_proportion(proportion)
|
||||||
d_axis_point = origin[0]*RIGHT + end[1]*UP
|
d_axis_point = origin[0]*RIGHT + end[1]*UP
|
||||||
v_line.put_start_and_end_on(d_axis_point, end)
|
v_line.put_start_and_end_on(d_axis_point, end)
|
||||||
|
|
||||||
|
@ -407,6 +413,168 @@ class GraphCarTrajectory(GraphScene):
|
||||||
run_time = 10,
|
run_time = 10,
|
||||||
)
|
)
|
||||||
self.dither()
|
self.dither()
|
||||||
|
self.play(*map(FadeOut, [h_line, v_line, car]))
|
||||||
|
|
||||||
|
#Show example vertical distance
|
||||||
|
h_update(h_line, 0.6)
|
||||||
|
t_dot = Dot(h_line.get_start(), color = h_line.get_color())
|
||||||
|
t_dot.save_state()
|
||||||
|
t_dot.move_to(self.x_axis_label_mob)
|
||||||
|
t_dot.set_fill(opacity = 0)
|
||||||
|
dashed_h = DashedLine(*h_line.get_start_and_end())
|
||||||
|
dashed_h.highlight(h_line.get_color())
|
||||||
|
brace = Brace(dashed_h, RIGHT)
|
||||||
|
brace_text = brace.get_text("Distance traveled")
|
||||||
|
self.play(t_dot.restore)
|
||||||
|
self.dither()
|
||||||
|
self.play(ShowCreation(dashed_h))
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(brace),
|
||||||
|
Write(brace_text)
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
self.play(*map(FadeOut, [t_dot, dashed_h, brace, brace_text]))
|
||||||
|
|
||||||
|
#Name graph
|
||||||
|
s_of_t = TexMobject("s(t)")
|
||||||
|
s_of_t.next_to(
|
||||||
|
graph.point_from_proportion(1),
|
||||||
|
DOWN+RIGHT,
|
||||||
|
buff = SMALL_BUFF
|
||||||
|
)
|
||||||
|
s = s_of_t[0]
|
||||||
|
d = TexMobject("d")
|
||||||
|
d.move_to(s, DOWN)
|
||||||
|
d.highlight(YELLOW)
|
||||||
|
|
||||||
|
self.play(Write(s_of_t))
|
||||||
|
self.dither()
|
||||||
|
s.save_state()
|
||||||
|
self.play(Transform(s, d))
|
||||||
|
self.dither()
|
||||||
|
self.play(s.restore)
|
||||||
|
|
||||||
|
def comment_on_slope(self, graph, origin):
|
||||||
|
delta_t = 1
|
||||||
|
curr_time = 0
|
||||||
|
ghost_line = Line(
|
||||||
|
origin,
|
||||||
|
self.coords_to_point(delta_t, self.y_max)
|
||||||
|
)
|
||||||
|
rect = Rectangle().replace(ghost_line, stretch = True)
|
||||||
|
rect.set_stroke(width = 0)
|
||||||
|
rect.set_fill(BLUE, opacity = 0.3)
|
||||||
|
def get_change_lines():
|
||||||
|
p1 = self.input_to_graph_point(curr_time)
|
||||||
|
p2 = self.input_to_graph_point(curr_time+delta_t)
|
||||||
|
interim_point = p2[0]*RIGHT + p1[1]*UP
|
||||||
|
delta_t_line = Line(p1, interim_point, color = YELLOW)
|
||||||
|
delta_s_line = Line(interim_point, p2, color = MAROON_B)
|
||||||
|
brace = Brace(delta_s_line, RIGHT, buff = SMALL_BUFF)
|
||||||
|
return VGroup(delta_t_line, delta_s_line, brace)
|
||||||
|
|
||||||
|
change_lines = get_change_lines()
|
||||||
|
self.play(FadeIn(rect))
|
||||||
|
self.dither()
|
||||||
|
self.play(Write(change_lines))
|
||||||
|
self.dither()
|
||||||
|
for x in range(1, 10):
|
||||||
|
curr_time = x
|
||||||
|
new_change_lines = get_change_lines()
|
||||||
|
self.play(
|
||||||
|
rect.move_to, self.coords_to_point(curr_time, 0), DOWN+LEFT,
|
||||||
|
Transform(change_lines, new_change_lines)
|
||||||
|
)
|
||||||
|
if curr_time == 5:
|
||||||
|
text = change_lines[-1].get_text(
|
||||||
|
"$\\frac{\\text{meters}}{\\text{second}}$"
|
||||||
|
)
|
||||||
|
self.play(Write(text))
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeOut(text))
|
||||||
|
else:
|
||||||
|
self.dither()
|
||||||
|
self.play(*map(FadeOut, [rect, change_lines]))
|
||||||
|
self.rect = rect
|
||||||
|
|
||||||
|
def show_velocity_graph(self):
|
||||||
|
velocity_graph = self.get_derivative_graph()
|
||||||
|
|
||||||
|
self.play(ShowCreation(velocity_graph))
|
||||||
|
def get_velocity_label(v_graph):
|
||||||
|
result = self.label_graph(
|
||||||
|
v_graph,
|
||||||
|
label = "v(t)",
|
||||||
|
direction = UP+RIGHT,
|
||||||
|
proportion = 0.5,
|
||||||
|
buff = SMALL_BUFF,
|
||||||
|
animate = False,
|
||||||
|
)
|
||||||
|
self.remove(result)
|
||||||
|
return result
|
||||||
|
label = get_velocity_label(velocity_graph)
|
||||||
|
self.play(Write(label))
|
||||||
|
self.dither()
|
||||||
|
self.rect.move_to(self.coords_to_point(0, 0), DOWN+LEFT)
|
||||||
|
self.play(FadeIn(self.rect))
|
||||||
|
self.dither()
|
||||||
|
for time in 4.5, 9:
|
||||||
|
self.play(
|
||||||
|
self.rect.move_to, self.coords_to_point(time, 0), DOWN+LEFT
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeOut(self.rect))
|
||||||
|
|
||||||
|
#Change distance and velocity graphs
|
||||||
|
self.graph.save_state()
|
||||||
|
velocity_graph.save_state()
|
||||||
|
label.save_state()
|
||||||
|
def shallow_slope(t):
|
||||||
|
return 100*smooth(t/10., inflection = 4)
|
||||||
|
def steep_slope(t):
|
||||||
|
return 100*smooth(t/10., inflection = 25)
|
||||||
|
def double_smooth_graph_function(t):
|
||||||
|
if t < 5:
|
||||||
|
return 50*smooth(t/5.)
|
||||||
|
else:
|
||||||
|
return 50*(1+smooth((t-5)/5.))
|
||||||
|
graph_funcs = [
|
||||||
|
shallow_slope,
|
||||||
|
steep_slope,
|
||||||
|
double_smooth_graph_function,
|
||||||
|
]
|
||||||
|
for graph_func in graph_funcs:
|
||||||
|
new_graph = self.graph_function(
|
||||||
|
graph_func,
|
||||||
|
is_main_graph = False
|
||||||
|
)
|
||||||
|
self.remove(new_graph)
|
||||||
|
new_velocity_graph = self.get_derivative_graph(graph = new_graph)
|
||||||
|
new_velocity_label = get_velocity_label(new_velocity_graph)
|
||||||
|
|
||||||
|
self.play(Transform(self.graph, new_graph))
|
||||||
|
self.play(
|
||||||
|
Transform(velocity_graph, new_velocity_graph),
|
||||||
|
Transform(label, new_velocity_label),
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
self.play(self.graph.restore)
|
||||||
|
self.play(
|
||||||
|
velocity_graph.restore,
|
||||||
|
label.restore,
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
def ask_critically_about_velocity(self):
|
||||||
|
morty = Mortimer().flip()
|
||||||
|
morty.to_corner(DOWN+LEFT)
|
||||||
|
self.play(PiCreatureSays(morty,
|
||||||
|
"Think critically about \\\\",
|
||||||
|
"what velocity means."
|
||||||
|
))
|
||||||
|
self.play(Blink(morty))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,15 @@ class GraphScene(Scene):
|
||||||
"axes_color" : GREY,
|
"axes_color" : GREY,
|
||||||
"graph_origin" : 2.5*DOWN + 4*LEFT,
|
"graph_origin" : 2.5*DOWN + 4*LEFT,
|
||||||
"y_axis_numbers_nudge" : 0.4*UP+0.5*LEFT,
|
"y_axis_numbers_nudge" : 0.4*UP+0.5*LEFT,
|
||||||
|
"num_graph_anchor_points" : 25,
|
||||||
}
|
}
|
||||||
def setup_axes(self, animate = True):
|
def setup_axes(self, animate = True):
|
||||||
x_num_range = float(self.x_max - self.x_min)
|
x_num_range = float(self.x_max - self.x_min)
|
||||||
|
self.space_unit_to_x = self.x_axis_width/x_num_range
|
||||||
x_axis = NumberLine(
|
x_axis = NumberLine(
|
||||||
x_min = self.x_min,
|
x_min = self.x_min,
|
||||||
x_max = self.x_max,
|
x_max = self.x_max,
|
||||||
space_unit_to_num = self.x_axis_width/x_num_range,
|
space_unit_to_num = self.space_unit_to_x,
|
||||||
tick_frequency = self.x_tick_frequency,
|
tick_frequency = self.x_tick_frequency,
|
||||||
leftmost_tick = self.x_leftmost_tick or self.x_min,
|
leftmost_tick = self.x_leftmost_tick or self.x_min,
|
||||||
numbers_with_elongated_ticks = self.x_labeled_nums,
|
numbers_with_elongated_ticks = self.x_labeled_nums,
|
||||||
|
@ -50,10 +52,11 @@ class GraphScene(Scene):
|
||||||
self.x_axis_label_mob = x_label
|
self.x_axis_label_mob = x_label
|
||||||
|
|
||||||
y_num_range = float(self.y_max - self.y_min)
|
y_num_range = float(self.y_max - self.y_min)
|
||||||
|
self.space_unit_to_y = self.y_axis_height/y_num_range
|
||||||
y_axis = NumberLine(
|
y_axis = NumberLine(
|
||||||
x_min = self.y_min,
|
x_min = self.y_min,
|
||||||
x_max = self.y_max,
|
x_max = self.y_max,
|
||||||
space_unit_to_num = self.y_axis_height/y_num_range,
|
space_unit_to_num = self.space_unit_to_y,
|
||||||
tick_frequency = self.y_tick_frequency,
|
tick_frequency = self.y_tick_frequency,
|
||||||
leftmost_tick = self.y_bottom_tick or self.y_min,
|
leftmost_tick = self.y_bottom_tick or self.y_min,
|
||||||
numbers_with_elongated_ticks = self.y_labeled_nums,
|
numbers_with_elongated_ticks = self.y_labeled_nums,
|
||||||
|
@ -88,11 +91,16 @@ class GraphScene(Scene):
|
||||||
is_main_graph = True,
|
is_main_graph = True,
|
||||||
):
|
):
|
||||||
|
|
||||||
def parameterized_graph(alpha):
|
def parameterized_function(alpha):
|
||||||
x = interpolate(self.x_min, self.x_max, alpha)
|
x = interpolate(self.x_min, self.x_max, alpha)
|
||||||
return self.coords_to_point(x, func(x))
|
return self.coords_to_point(x, func(x))
|
||||||
|
|
||||||
graph = ParametricFunction(parameterized_graph, color = color)
|
graph = ParametricFunction(
|
||||||
|
parameterized_function,
|
||||||
|
color = color,
|
||||||
|
num_anchor_points = self.num_graph_anchor_points,
|
||||||
|
)
|
||||||
|
graph.underlying_function = func
|
||||||
|
|
||||||
if is_main_graph:
|
if is_main_graph:
|
||||||
self.graph = graph
|
self.graph = graph
|
||||||
|
@ -102,16 +110,35 @@ class GraphScene(Scene):
|
||||||
self.add(graph)
|
self.add(graph)
|
||||||
return graph
|
return graph
|
||||||
|
|
||||||
def input_to_graph_point(self, x):
|
|
||||||
assert(hasattr(self, "graph"))
|
|
||||||
alpha = (x - self.x_min)/(self.x_max - self.x_min)
|
|
||||||
return self.graph.point_from_proportion(alpha)
|
|
||||||
|
|
||||||
def angle_of_tangent(self, x, dx = 0.01):
|
def input_to_graph_point(self, x, graph = None):
|
||||||
assert(hasattr(self, "graph"))
|
if graph is None:
|
||||||
vect = self.graph_point(x + dx) - self.graph_point(x)
|
assert(hasattr(self, "graph"))
|
||||||
|
graph = self.graph
|
||||||
|
return self.coords_to_point(
|
||||||
|
x, graph.underlying_function(x)
|
||||||
|
)
|
||||||
|
# alpha = (x - self.x_min)/(self.x_max - self.x_min)
|
||||||
|
# return graph.point_from_proportion(alpha)
|
||||||
|
|
||||||
|
def angle_of_tangent(self, x, graph = None, dx = 0.01):
|
||||||
|
vect = self.input_to_graph_point(x + dx, graph) - self.input_to_graph_point(x, graph)
|
||||||
return angle_of_vector(vect)
|
return angle_of_vector(vect)
|
||||||
|
|
||||||
|
def slope_of_tangent(self, *args):
|
||||||
|
return np.tan(self.angle_of_tangent(*args))
|
||||||
|
|
||||||
|
def get_derivative_graph(self, graph = None, dx = 0.01, color = RED):
|
||||||
|
derivative_graph = self.graph_function(
|
||||||
|
lambda x : self.slope_of_tangent(x, graph, dx) / self.space_unit_to_y,
|
||||||
|
color = color,
|
||||||
|
animate = False,
|
||||||
|
is_main_graph = False
|
||||||
|
)
|
||||||
|
self.remove(derivative_graph)
|
||||||
|
return derivative_graph
|
||||||
|
|
||||||
|
|
||||||
def label_graph(self, graph, label = "f(x)",
|
def label_graph(self, graph, label = "f(x)",
|
||||||
proportion = 0.7,
|
proportion = 0.7,
|
||||||
direction = LEFT,
|
direction = LEFT,
|
||||||
|
|
Loading…
Add table
Reference in a new issue