Up to GraphCarTrajectory of eoc chapter 2

This commit is contained in:
Grant Sanderson 2017-01-05 11:57:13 -08:00
parent 740eba856d
commit a7720f308d
2 changed files with 210 additions and 15 deletions

View file

@ -377,16 +377,22 @@ class GraphCarTrajectory(GraphScene):
graph = self.graph_function(lambda t : 100*smooth(t/10.))
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 = [
Line(origin, origin, color = color, stroke_width = 2)
for color in MAROON_B, YELLOW
]
def h_update(h_line):
end = graph.points[-1]
def h_update(h_line, proportion = 1):
end = graph.point_from_proportion(proportion)
t_axis_point = end[0]*RIGHT + origin[1]*UP
h_line.put_start_and_end_on(t_axis_point, end)
def v_update(v_line):
end = graph.points[-1]
def v_update(v_line, proportion = 1):
end = graph.point_from_proportion(proportion)
d_axis_point = origin[0]*RIGHT + end[1]*UP
v_line.put_start_and_end_on(d_axis_point, end)
@ -407,6 +413,168 @@ class GraphCarTrajectory(GraphScene):
run_time = 10,
)
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()

View file

@ -28,13 +28,15 @@ class GraphScene(Scene):
"axes_color" : GREY,
"graph_origin" : 2.5*DOWN + 4*LEFT,
"y_axis_numbers_nudge" : 0.4*UP+0.5*LEFT,
"num_graph_anchor_points" : 25,
}
def setup_axes(self, animate = True):
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_min = self.x_min,
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,
leftmost_tick = self.x_leftmost_tick or self.x_min,
numbers_with_elongated_ticks = self.x_labeled_nums,
@ -50,10 +52,11 @@ class GraphScene(Scene):
self.x_axis_label_mob = x_label
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(
x_min = self.y_min,
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,
leftmost_tick = self.y_bottom_tick or self.y_min,
numbers_with_elongated_ticks = self.y_labeled_nums,
@ -88,11 +91,16 @@ class GraphScene(Scene):
is_main_graph = True,
):
def parameterized_graph(alpha):
def parameterized_function(alpha):
x = interpolate(self.x_min, self.x_max, alpha)
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:
self.graph = graph
@ -102,16 +110,35 @@ class GraphScene(Scene):
self.add(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):
assert(hasattr(self, "graph"))
vect = self.graph_point(x + dx) - self.graph_point(x)
def input_to_graph_point(self, x, graph = None):
if graph is None:
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)
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)",
proportion = 0.7,
direction = LEFT,