2016-12-26 07:10:38 -08:00
|
|
|
from helpers import *
|
|
|
|
|
|
|
|
from mobject.tex_mobject import TexMobject
|
|
|
|
from mobject import Mobject
|
|
|
|
from mobject.image_mobject import ImageMobject
|
|
|
|
from mobject.vectorized_mobject import *
|
|
|
|
|
|
|
|
from animation.animation import Animation
|
|
|
|
from animation.transform import *
|
|
|
|
from animation.simple_animations import *
|
|
|
|
from animation.playground import *
|
|
|
|
from topics.geometry import *
|
|
|
|
from topics.characters import *
|
|
|
|
from topics.functions import *
|
|
|
|
from topics.fractals import *
|
|
|
|
from topics.number_line import *
|
|
|
|
from topics.combinatorics import *
|
|
|
|
from topics.numerals import *
|
|
|
|
from topics.three_dimensions import *
|
|
|
|
from topics.objects import *
|
|
|
|
from scene import Scene
|
|
|
|
from scene.zoomed_scene import ZoomedScene
|
|
|
|
from camera import Camera
|
|
|
|
from mobject.svg_mobject import *
|
|
|
|
from mobject.tex_mobject import *
|
|
|
|
|
|
|
|
from eoc.chapter1 import OpeningQuote
|
|
|
|
from eoc.graph_scene import *
|
|
|
|
|
|
|
|
|
|
|
|
class Car(SVGMobject):
|
|
|
|
CONFIG = {
|
|
|
|
"file_name" : "Car",
|
|
|
|
"height" : 1,
|
2016-12-29 14:31:01 -08:00
|
|
|
"color" : "#BBBBBB",
|
2016-12-26 07:10:38 -08:00
|
|
|
}
|
|
|
|
def __init__(self, **kwargs):
|
|
|
|
SVGMobject.__init__(self, **kwargs)
|
|
|
|
self.scale_to_fit_height(self.height)
|
|
|
|
self.set_stroke(color = WHITE, width = 0)
|
|
|
|
self.set_fill(self.color, opacity = 1)
|
|
|
|
|
|
|
|
randy = Randolph(mode = "happy")
|
|
|
|
randy.scale_to_fit_height(0.6*self.get_height())
|
|
|
|
randy.stretch(0.8, 0)
|
|
|
|
randy.look(RIGHT)
|
|
|
|
randy.move_to(self)
|
|
|
|
randy.shift(0.07*self.height*(RIGHT+UP))
|
|
|
|
self.add_to_back(randy)
|
|
|
|
|
|
|
|
orientation_line = Line(self.get_left(), self.get_right())
|
|
|
|
orientation_line.set_stroke(width = 0)
|
|
|
|
self.add(orientation_line)
|
|
|
|
self.orientation_line = orientation_line
|
|
|
|
|
|
|
|
|
|
|
|
self.add_treds_to_tires()
|
|
|
|
|
|
|
|
def move_to(self, point_or_mobject):
|
|
|
|
vect = rotate_vector(
|
|
|
|
UP+LEFT, self.orientation_line.get_angle()
|
|
|
|
)
|
|
|
|
self.next_to(point_or_mobject, vect, buff = 0)
|
|
|
|
return self
|
|
|
|
|
|
|
|
def get_front_line(self):
|
|
|
|
return DashedLine(
|
|
|
|
self.get_corner(UP+RIGHT),
|
|
|
|
self.get_corner(DOWN+RIGHT),
|
|
|
|
color = YELLOW,
|
|
|
|
dashed_segment_length = 0.05,
|
|
|
|
)
|
|
|
|
|
|
|
|
def add_treds_to_tires(self):
|
|
|
|
for tire in self.get_tires():
|
|
|
|
radius = tire.get_width()/2
|
|
|
|
center = tire.get_center()
|
|
|
|
tred = Line(
|
|
|
|
0.9*radius*RIGHT, 1.4*radius*RIGHT,
|
|
|
|
stroke_width = 2,
|
|
|
|
color = BLACK
|
|
|
|
)
|
|
|
|
tred.rotate_in_place(np.pi/4)
|
|
|
|
for theta in np.arange(0, 2*np.pi, np.pi/4):
|
|
|
|
new_tred = tred.copy()
|
|
|
|
new_tred.rotate(theta)
|
|
|
|
new_tred.shift(center)
|
|
|
|
tire.add(new_tred)
|
|
|
|
return self
|
|
|
|
|
|
|
|
def get_tires(self):
|
|
|
|
return self[1][1], self[1][3]
|
|
|
|
|
|
|
|
class MoveCar(ApplyMethod):
|
|
|
|
def __init__(self, car, target_point, **kwargs):
|
|
|
|
ApplyMethod.__init__(self, car.move_to, target_point, **kwargs)
|
|
|
|
displacement = self.ending_mobject.get_right()-self.starting_mobject.get_right()
|
|
|
|
distance = np.linalg.norm(displacement)
|
|
|
|
tire_radius = car.get_tires()[0].get_width()/2
|
|
|
|
self.total_tire_radians = -distance/tire_radius
|
|
|
|
|
|
|
|
def update_mobject(self, alpha):
|
|
|
|
ApplyMethod.update_mobject(self, alpha)
|
|
|
|
if alpha == 0:
|
|
|
|
return
|
|
|
|
radians = alpha*self.total_tire_radians
|
|
|
|
for tire in self.mobject.get_tires():
|
|
|
|
tire.rotate_in_place(radians)
|
|
|
|
|
|
|
|
class IncrementNumber(Succession):
|
|
|
|
CONFIG = {
|
|
|
|
"start_num" : 0,
|
|
|
|
"changes_per_second" : 1,
|
|
|
|
"run_time" : 11,
|
|
|
|
}
|
|
|
|
def __init__(self, num_mob, **kwargs):
|
|
|
|
digest_config(self, kwargs)
|
|
|
|
n_iterations = int(self.run_time * self.changes_per_second)
|
|
|
|
new_num_mobs = [
|
|
|
|
TexMobject(str(num)).move_to(num_mob, LEFT)
|
|
|
|
for num in range(self.start_num, self.start_num+n_iterations)
|
|
|
|
]
|
|
|
|
transforms = [
|
|
|
|
Transform(
|
|
|
|
num_mob, new_num_mob,
|
|
|
|
run_time = 1.0/self.changes_per_second,
|
|
|
|
rate_func = squish_rate_func(smooth, 0, 0.5)
|
|
|
|
)
|
|
|
|
for new_num_mob in new_num_mobs
|
|
|
|
]
|
|
|
|
Succession.__init__(
|
|
|
|
self, *transforms, **{
|
|
|
|
"rate_func" : None,
|
|
|
|
"run_time" : self.run_time,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
class IncrementTest(Scene):
|
|
|
|
def construct(self):
|
|
|
|
num = TexMobject("0")
|
|
|
|
num.shift(UP)
|
|
|
|
self.play(IncrementNumber(num))
|
|
|
|
self.dither()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
############################
|
|
|
|
|
|
|
|
class Chapter2OpeningQuote(OpeningQuote):
|
|
|
|
CONFIG = {
|
|
|
|
"quote" : [
|
|
|
|
"So far as the theories of mathematics are about",
|
|
|
|
"reality,",
|
|
|
|
"they are not",
|
|
|
|
"certain;",
|
|
|
|
"so far as they are",
|
|
|
|
"certain,",
|
|
|
|
"they are not about",
|
|
|
|
"reality.",
|
|
|
|
],
|
|
|
|
"highlighted_quote_terms" : {
|
|
|
|
"reality," : BLUE,
|
|
|
|
"certain;" : GREEN,
|
|
|
|
"certain," : GREEN,
|
|
|
|
"reality." : BLUE,
|
|
|
|
},
|
|
|
|
"author" : "Albert Einstein"
|
|
|
|
}
|
|
|
|
|
|
|
|
class Introduction(TeacherStudentsScene):
|
|
|
|
def construct(self):
|
|
|
|
self.student_says(
|
|
|
|
"What is a derivative?"
|
|
|
|
)
|
|
|
|
self.play(self.get_teacher().change_mode, "happy")
|
|
|
|
self.dither()
|
|
|
|
self.teacher_says(
|
|
|
|
"It's actually a \\\\",
|
|
|
|
"very subtle idea",
|
|
|
|
target_mode = "well"
|
|
|
|
)
|
|
|
|
self.change_student_modes(None, "pondering", "thinking")
|
|
|
|
self.dither()
|
|
|
|
self.change_student_modes("erm")
|
|
|
|
self.student_says(
|
|
|
|
"Doesn't the derivative measure\\\\",
|
|
|
|
"instantaneous rate of change", "?",
|
|
|
|
student_index = 0,
|
|
|
|
)
|
|
|
|
self.dither()
|
|
|
|
|
|
|
|
bubble = self.get_students()[0].bubble
|
|
|
|
phrase = bubble.content[1]
|
|
|
|
bubble.content.remove(phrase)
|
|
|
|
self.play(
|
|
|
|
phrase.center,
|
|
|
|
phrase.scale, 1.5,
|
|
|
|
phrase.to_edge, UP,
|
|
|
|
FadeOut(bubble),
|
|
|
|
FadeOut(bubble.content),
|
|
|
|
*it.chain(*[
|
|
|
|
[
|
|
|
|
pi.change_mode, mode,
|
|
|
|
pi.look_at, SPACE_HEIGHT*UP
|
|
|
|
]
|
|
|
|
for pi, mode in zip(self.get_everyone(), [
|
|
|
|
"speaking", "pondering", "confused", "confused",
|
|
|
|
])
|
|
|
|
])
|
|
|
|
)
|
|
|
|
self.dither()
|
|
|
|
change = VGroup(*phrase[-len("change"):])
|
|
|
|
instantaneous = VGroup(*phrase[:len("instantaneous")])
|
|
|
|
change_brace = Brace(change)
|
|
|
|
change_description = change_brace.get_text(
|
|
|
|
"Requires multiple \\\\ points in time"
|
|
|
|
)
|
|
|
|
instantaneous_brace = Brace(instantaneous)
|
|
|
|
instantaneous_description = instantaneous_brace.get_text(
|
|
|
|
"One point \\\\ in time"
|
|
|
|
)
|
|
|
|
clock = Clock()
|
|
|
|
clock.next_to(change_description, DOWN)
|
|
|
|
def get_clock_anim(run_time = 3):
|
|
|
|
return ClockPassesTime(
|
|
|
|
clock,
|
|
|
|
hours_passed = 0.4*run_time,
|
|
|
|
run_time = run_time,
|
|
|
|
)
|
|
|
|
self.play(FadeIn(clock))
|
|
|
|
self.play(
|
|
|
|
change.gradient_highlight, BLUE, YELLOW,
|
|
|
|
GrowFromCenter(change_brace),
|
|
|
|
Write(change_description),
|
|
|
|
get_clock_anim()
|
|
|
|
)
|
|
|
|
self.play(get_clock_anim(1))
|
|
|
|
stopped_clock = clock.copy()
|
|
|
|
stopped_clock.next_to(instantaneous_description, DOWN)
|
|
|
|
self.play(
|
|
|
|
instantaneous.highlight, BLUE,
|
|
|
|
GrowFromCenter(instantaneous_brace),
|
|
|
|
Transform(change_description.copy(), instantaneous_description),
|
|
|
|
clock.copy().next_to, instantaneous_description, DOWN,
|
|
|
|
get_clock_anim(3)
|
|
|
|
)
|
|
|
|
self.play(get_clock_anim(6))
|
|
|
|
|
|
|
|
class FathersOfCalculus(Scene):
|
|
|
|
CONFIG = {
|
|
|
|
"names" : [
|
|
|
|
"Barrow",
|
|
|
|
"Newton",
|
|
|
|
"Leibniz",
|
|
|
|
"Cauchy",
|
|
|
|
"Weierstrass",
|
|
|
|
],
|
|
|
|
"picture_height" : 2.5,
|
|
|
|
}
|
|
|
|
def construct(self):
|
|
|
|
title = TextMobject("(A few) Fathers of Calculus")
|
|
|
|
title.to_edge(UP)
|
|
|
|
self.add(title)
|
|
|
|
|
|
|
|
men = Mobject()
|
|
|
|
for name in self.names:
|
|
|
|
image = ImageMobject(name, invert = False)
|
|
|
|
image.scale_to_fit_height(self.picture_height)
|
|
|
|
title = TextMobject(name)
|
|
|
|
title.scale(0.8)
|
|
|
|
title.next_to(image, DOWN)
|
|
|
|
image.add(title)
|
|
|
|
men.add(image)
|
|
|
|
men.arrange_submobjects(RIGHT, aligned_edge = UP)
|
|
|
|
men.shift(DOWN)
|
|
|
|
|
|
|
|
discover_brace = Brace(Mobject(*men[:3]), UP)
|
|
|
|
discover = discover_brace.get_text("Discovered it")
|
|
|
|
VGroup(discover_brace, discover).highlight(BLUE)
|
|
|
|
rigor_brace = Brace(Mobject(*men[3:]), UP)
|
|
|
|
rigor = rigor_brace.get_text("Made it rigorous")
|
|
|
|
rigor.shift(0.1*DOWN)
|
|
|
|
VGroup(rigor_brace, rigor).highlight(YELLOW)
|
|
|
|
|
|
|
|
|
|
|
|
for man in men:
|
|
|
|
self.play(FadeIn(man))
|
|
|
|
self.play(
|
|
|
|
GrowFromCenter(discover_brace),
|
|
|
|
Write(discover, run_time = 1)
|
|
|
|
)
|
|
|
|
self.play(
|
|
|
|
GrowFromCenter(rigor_brace),
|
|
|
|
Write(rigor, run_time = 1)
|
|
|
|
)
|
|
|
|
self.dither()
|
|
|
|
|
|
|
|
class IntroduceCar(Scene):
|
|
|
|
def construct(self):
|
|
|
|
point_A = DOWN+4*LEFT
|
|
|
|
point_B = DOWN+5*RIGHT
|
|
|
|
A = Dot(point_A)
|
|
|
|
B = Dot(point_B)
|
|
|
|
line = Line(point_A, point_B)
|
|
|
|
VGroup(A, B, line).highlight(WHITE)
|
|
|
|
for dot, tex in (A, "A"), (B, "B"):
|
|
|
|
label = TexMobject(tex).next_to(dot, DOWN)
|
|
|
|
dot.add(label)
|
|
|
|
|
|
|
|
car = Car()
|
|
|
|
car.move_to(point_A)
|
|
|
|
front_line = car.get_front_line()
|
|
|
|
|
|
|
|
time_label = TextMobject("Time (in seconds):", "0")
|
|
|
|
time_label.shift(2*UP)
|
|
|
|
|
|
|
|
distance_brace = Brace(line, UP)
|
|
|
|
# distance_brace.set_fill(opacity = 0.5)
|
|
|
|
distance = distance_brace.get_text("100m")
|
|
|
|
|
|
|
|
self.add(A, B, line, car, time_label)
|
|
|
|
self.play(ShowCreation(front_line))
|
|
|
|
self.play(FadeOut(front_line))
|
|
|
|
self.play(
|
|
|
|
MoveCar(car, point_B, run_time = 10),
|
|
|
|
IncrementNumber(time_label[1], run_time = 11)
|
|
|
|
)
|
|
|
|
front_line = car.get_front_line()
|
|
|
|
self.play(ShowCreation(front_line))
|
|
|
|
self.play(FadeOut(front_line))
|
|
|
|
self.play(
|
|
|
|
GrowFromCenter(distance_brace),
|
|
|
|
Write(distance)
|
|
|
|
)
|
|
|
|
self.dither()
|
|
|
|
self.play(
|
|
|
|
car.move_to, point_A,
|
|
|
|
FadeOut(time_label),
|
|
|
|
FadeOut(distance_brace),
|
|
|
|
FadeOut(distance)
|
|
|
|
)
|
|
|
|
graph_scene = GraphCarTrajectory(skip_animations = True)
|
|
|
|
origin = graph_scene.graph_origin
|
|
|
|
top = graph_scene.coords_to_point(0, 100)
|
|
|
|
new_length = np.linalg.norm(top-origin)
|
|
|
|
new_point_B = point_A + new_length*RIGHT
|
|
|
|
|
|
|
|
group = VGroup(car, A, B, line)
|
|
|
|
for mob in group:
|
|
|
|
mob.generate_target()
|
|
|
|
group.target = VGroup(*[m.target for m in group])
|
|
|
|
B.target.shift(new_point_B - point_B)
|
|
|
|
line.target.put_start_and_end_on(
|
|
|
|
point_A, new_point_B
|
|
|
|
)
|
|
|
|
|
|
|
|
group.target.rotate(np.pi/2, about_point = point_A)
|
|
|
|
group.target.shift(graph_scene.graph_origin - point_A)
|
2016-12-29 14:31:01 -08:00
|
|
|
self.play(MoveToTarget(group, path_arc = np.pi/2))
|
2016-12-26 07:10:38 -08:00
|
|
|
self.dither()
|
|
|
|
|
|
|
|
class GraphCarTrajectory(GraphScene):
|
|
|
|
CONFIG = {
|
|
|
|
"x_min" : 0,
|
2016-12-29 14:31:01 -08:00
|
|
|
"x_max" : 10.01,
|
|
|
|
"x_labeled_nums" : range(1, 11),
|
2016-12-26 07:10:38 -08:00
|
|
|
"x_axis_label" : "Time (seconds)",
|
|
|
|
"y_min" : 0,
|
|
|
|
"y_max" : 110,
|
|
|
|
"y_tick_frequency" : 10,
|
|
|
|
"y_labeled_nums" : range(10, 110, 10),
|
|
|
|
"y_axis_label" : "Distance traveled \\\\ (meters)",
|
|
|
|
"graph_origin" : 2.5*DOWN + 5*LEFT,
|
|
|
|
}
|
|
|
|
def construct(self):
|
|
|
|
self.setup_axes(animate = False)
|
2016-12-29 14:31:01 -08:00
|
|
|
graph = self.graph_function(lambda t : 100*smooth(t/10.))
|
|
|
|
origin = self.coords_to_point(0, 0)
|
|
|
|
|
2017-01-05 11:57:13 -08:00
|
|
|
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):
|
2016-12-29 14:31:01 -08:00
|
|
|
h_line, v_line = [
|
|
|
|
Line(origin, origin, color = color, stroke_width = 2)
|
|
|
|
for color in MAROON_B, YELLOW
|
|
|
|
]
|
2017-01-05 11:57:13 -08:00
|
|
|
def h_update(h_line, proportion = 1):
|
|
|
|
end = graph.point_from_proportion(proportion)
|
2016-12-29 14:31:01 -08:00
|
|
|
t_axis_point = end[0]*RIGHT + origin[1]*UP
|
|
|
|
h_line.put_start_and_end_on(t_axis_point, end)
|
2017-01-05 11:57:13 -08:00
|
|
|
def v_update(v_line, proportion = 1):
|
|
|
|
end = graph.point_from_proportion(proportion)
|
2016-12-29 14:31:01 -08:00
|
|
|
d_axis_point = origin[0]*RIGHT + end[1]*UP
|
|
|
|
v_line.put_start_and_end_on(d_axis_point, end)
|
2016-12-26 07:10:38 -08:00
|
|
|
|
|
|
|
car = Car()
|
|
|
|
car.rotate(np.pi/2)
|
2016-12-29 14:31:01 -08:00
|
|
|
car.move_to(origin)
|
2016-12-26 07:10:38 -08:00
|
|
|
self.add(car)
|
2016-12-29 14:31:01 -08:00
|
|
|
self.play(
|
|
|
|
ShowCreation(
|
|
|
|
graph,
|
|
|
|
rate_func = None,
|
|
|
|
),
|
|
|
|
MoveCar(
|
|
|
|
car, self.coords_to_point(0, 100),
|
|
|
|
),
|
|
|
|
UpdateFromFunc(h_line, h_update),
|
|
|
|
UpdateFromFunc(v_line, v_update),
|
|
|
|
run_time = 10,
|
|
|
|
)
|
|
|
|
self.dither()
|
2017-01-05 11:57:13 -08:00
|
|
|
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()
|
|
|
|
|
2016-12-29 14:31:01 -08:00
|
|
|
|
2016-12-26 07:10:38 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|