2017-05-02 21:09:56 -07:00
|
|
|
import scipy
|
|
|
|
import math
|
|
|
|
|
2018-03-30 12:56:29 -07:00
|
|
|
from big_ol_pile_of_manim_imports import *
|
2017-05-08 08:20:14 -07:00
|
|
|
from old_projects.eoc.chapter1 import Car, MoveCar
|
|
|
|
from old_projects.eoc.chapter10 import derivative
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
#revert_to_original_skipping_status
|
|
|
|
|
|
|
|
|
|
|
|
########
|
2017-05-02 21:09:56 -07:00
|
|
|
|
|
|
|
class Introduce(TeacherStudentsScene):
|
|
|
|
def construct(self):
|
|
|
|
words = TextMobject("Next up is \\\\", "Taylor series")
|
2018-03-30 11:51:31 -07:00
|
|
|
words.set_color_by_tex("Taylor", BLUE)
|
2017-05-02 21:09:56 -07:00
|
|
|
derivs = VGroup(*[
|
|
|
|
TexMobject(
|
|
|
|
"{d", "^%d"%n, "f \\over dx", "^%d}"%n
|
2018-03-30 11:51:31 -07:00
|
|
|
).set_color_by_tex(str(n), YELLOW)
|
2017-05-02 21:09:56 -07:00
|
|
|
for n in range(2, 5)
|
|
|
|
])
|
|
|
|
derivs.next_to(self.teacher, UP, LARGE_BUFF)
|
|
|
|
second_deriv = derivs[0]
|
|
|
|
second_deriv.save_state()
|
|
|
|
card_dot = Dot(radius = SMALL_BUFF)
|
|
|
|
screen_rect = ScreenRectangle(height = 4)
|
|
|
|
screen_rect.move_to(3*UP, UP)
|
|
|
|
|
|
|
|
self.teacher_says(words, run_time = 2)
|
|
|
|
taylor_series = words.get_part_by_tex("Taylor").copy()
|
|
|
|
self.change_student_modes(*["happy"]*3)
|
|
|
|
self.play(
|
|
|
|
RemovePiCreatureBubble(
|
|
|
|
self.teacher,
|
|
|
|
target_mode = "raise_right_hand"
|
|
|
|
),
|
|
|
|
taylor_series.next_to, screen_rect.copy(), UP,
|
|
|
|
ShowCreation(screen_rect)
|
|
|
|
)
|
|
|
|
card_dot.move_to(taylor_series)
|
|
|
|
card_dot.generate_target()
|
|
|
|
card_dot.target.set_fill(opacity = 0)
|
|
|
|
card_dot.target.to_edge(RIGHT, buff = MED_SMALL_BUFF)
|
|
|
|
arrow = Arrow(
|
|
|
|
taylor_series, card_dot.target,
|
|
|
|
buff = MED_SMALL_BUFF,
|
|
|
|
color = WHITE
|
|
|
|
)
|
|
|
|
self.play(FadeIn(second_deriv))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-02 21:09:56 -07:00
|
|
|
self.play(Transform(second_deriv, derivs[1]))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-02 21:09:56 -07:00
|
|
|
self.play(MoveToTarget(card_dot))
|
|
|
|
self.play(ShowCreation(arrow))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-02 21:09:56 -07:00
|
|
|
self.play(Transform(second_deriv, derivs[2]))
|
|
|
|
self.change_student_modes(*["erm"]*3)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-02 21:09:56 -07:00
|
|
|
self.play(second_deriv.restore)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-02 21:09:56 -07:00
|
|
|
|
|
|
|
class SecondDerivativeGraphically(GraphScene):
|
|
|
|
CONFIG = {
|
|
|
|
"x1" : 0,
|
|
|
|
"x2" : 4,
|
|
|
|
"x3" : 8,
|
|
|
|
"y" : 4,
|
|
|
|
"deriv_color" : YELLOW,
|
|
|
|
"second_deriv_color" : GREEN,
|
|
|
|
}
|
|
|
|
def construct(self):
|
2017-05-05 11:19:10 -07:00
|
|
|
self.force_skipping()
|
|
|
|
|
2017-05-02 21:09:56 -07:00
|
|
|
self.setup_axes()
|
|
|
|
self.draw_f()
|
|
|
|
self.show_derivative()
|
|
|
|
self.write_second_derivative()
|
|
|
|
self.show_curvature()
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
self.revert_to_original_skipping_status()
|
2017-05-02 21:09:56 -07:00
|
|
|
self.contrast_big_and_small_concavity()
|
|
|
|
|
|
|
|
def draw_f(self):
|
|
|
|
def func(x):
|
|
|
|
return 0.1*(x-self.x1)*(x-self.x2)*(x-self.x3) + self.y
|
|
|
|
|
|
|
|
graph = self.get_graph(func)
|
|
|
|
graph_label = self.get_graph_label(graph, "f(x)")
|
|
|
|
|
|
|
|
self.play(
|
|
|
|
ShowCreation(graph, run_time = 2),
|
|
|
|
Write(
|
|
|
|
graph_label,
|
|
|
|
run_time = 2,
|
|
|
|
rate_func = squish_rate_func(smooth, 0.5, 1)
|
|
|
|
)
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-02 21:09:56 -07:00
|
|
|
|
|
|
|
self.graph = graph
|
|
|
|
self.graph_label = graph_label
|
|
|
|
|
|
|
|
def show_derivative(self):
|
|
|
|
deriv = TexMobject("\\frac{df}{dx}")
|
|
|
|
deriv.next_to(self.graph_label, DOWN, MED_LARGE_BUFF)
|
2018-03-30 11:51:31 -07:00
|
|
|
deriv.set_color(self.deriv_color)
|
2017-05-02 21:09:56 -07:00
|
|
|
ss_group = self.get_secant_slope_group(
|
|
|
|
1, self.graph,
|
|
|
|
dx = 0.01,
|
|
|
|
secant_line_color = self.deriv_color
|
|
|
|
)
|
|
|
|
|
|
|
|
self.play(
|
|
|
|
Write(deriv),
|
2018-08-09 17:56:05 -07:00
|
|
|
*list(map(ShowCreation, ss_group))
|
2017-05-02 21:09:56 -07:00
|
|
|
)
|
|
|
|
self.animate_secant_slope_group_change(
|
|
|
|
ss_group, target_x = self.x3,
|
|
|
|
run_time = 5
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-02 21:09:56 -07:00
|
|
|
self.animate_secant_slope_group_change(
|
|
|
|
ss_group, target_x = self.x2,
|
|
|
|
run_time = 3
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-02 21:09:56 -07:00
|
|
|
|
|
|
|
self.ss_group = ss_group
|
|
|
|
self.deriv = deriv
|
|
|
|
|
|
|
|
def write_second_derivative(self):
|
|
|
|
second_deriv = TexMobject("\\frac{d^2 f}{dx^2}")
|
|
|
|
second_deriv.next_to(self.deriv, DOWN, MED_LARGE_BUFF)
|
2018-03-30 11:51:31 -07:00
|
|
|
second_deriv.set_color(self.second_deriv_color)
|
2017-05-02 21:09:56 -07:00
|
|
|
points = [
|
|
|
|
self.input_to_graph_point(x, self.graph)
|
2018-06-02 08:59:26 -04:00
|
|
|
for x in (self.x2, self.x3)
|
2017-05-02 21:09:56 -07:00
|
|
|
]
|
|
|
|
words = TextMobject("Change to \\\\ slope")
|
|
|
|
words.next_to(
|
|
|
|
center_of_mass(points), UP, 1.5*LARGE_BUFF
|
|
|
|
)
|
|
|
|
arrows = [
|
|
|
|
Arrow(words.get_bottom(), p, color = WHITE)
|
|
|
|
for p in points
|
|
|
|
]
|
|
|
|
|
|
|
|
self.play(Write(second_deriv))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-02 21:09:56 -07:00
|
|
|
self.play(
|
|
|
|
Write(words),
|
|
|
|
ShowCreation(
|
|
|
|
arrows[0],
|
|
|
|
rate_func = squish_rate_func(smooth, 0.5, 1)
|
|
|
|
),
|
|
|
|
run_time = 2
|
|
|
|
)
|
|
|
|
self.animate_secant_slope_group_change(
|
|
|
|
self.ss_group, target_x = self.x3,
|
|
|
|
run_time = 3,
|
|
|
|
added_anims = [
|
|
|
|
Transform(
|
|
|
|
*arrows,
|
|
|
|
run_time = 3,
|
|
|
|
path_arc = 0.75*np.pi
|
|
|
|
),
|
|
|
|
]
|
|
|
|
)
|
|
|
|
self.play(FadeOut(arrows[0]))
|
|
|
|
self.animate_secant_slope_group_change(
|
|
|
|
self.ss_group, target_x = self.x2,
|
|
|
|
run_time = 3,
|
|
|
|
)
|
|
|
|
|
|
|
|
self.second_deriv_words = words
|
|
|
|
self.second_deriv = second_deriv
|
|
|
|
|
|
|
|
def show_curvature(self):
|
|
|
|
positive_curve, negative_curve = [
|
|
|
|
self.get_graph(
|
|
|
|
self.graph.underlying_function,
|
|
|
|
x_min = x_min,
|
|
|
|
x_max = x_max,
|
|
|
|
color = color,
|
|
|
|
).set_stroke(width = 6)
|
|
|
|
for x_min, x_max, color in [
|
|
|
|
(self.x2, self.x3, PINK),
|
|
|
|
(self.x1, self.x2, RED),
|
|
|
|
]
|
|
|
|
]
|
|
|
|
dot = Dot()
|
|
|
|
def get_dot_update_func(curve):
|
|
|
|
def update_dot(dot):
|
|
|
|
dot.move_to(curve.points[-1])
|
|
|
|
return dot
|
|
|
|
return update_dot
|
|
|
|
|
|
|
|
self.play(
|
|
|
|
ShowCreation(positive_curve, run_time = 3),
|
|
|
|
UpdateFromFunc(dot, get_dot_update_func(positive_curve))
|
|
|
|
)
|
|
|
|
self.play(FadeOut(dot))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-02 21:09:56 -07:00
|
|
|
self.animate_secant_slope_group_change(
|
|
|
|
self.ss_group, target_x = self.x3,
|
|
|
|
run_time = 4,
|
|
|
|
added_anims = [Animation(positive_curve)]
|
|
|
|
)
|
|
|
|
|
2018-08-09 17:56:05 -07:00
|
|
|
self.play(*list(map(FadeOut, [self.ss_group, positive_curve])))
|
2017-05-02 21:09:56 -07:00
|
|
|
self.animate_secant_slope_group_change(
|
|
|
|
self.ss_group, target_x = self.x1,
|
|
|
|
run_time = 0
|
|
|
|
)
|
|
|
|
self.play(FadeIn(self.ss_group))
|
|
|
|
self.play(
|
|
|
|
ShowCreation(negative_curve, run_time = 3),
|
|
|
|
UpdateFromFunc(dot, get_dot_update_func(negative_curve))
|
|
|
|
)
|
|
|
|
self.play(FadeOut(dot))
|
|
|
|
self.animate_secant_slope_group_change(
|
|
|
|
self.ss_group, target_x = self.x2,
|
|
|
|
run_time = 4,
|
|
|
|
added_anims = [Animation(negative_curve)]
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2018-08-09 17:56:05 -07:00
|
|
|
self.play(*list(map(FadeOut, [
|
2017-05-02 21:09:56 -07:00
|
|
|
self.graph, self.ss_group,
|
|
|
|
negative_curve, self.second_deriv_words
|
2018-08-09 17:56:05 -07:00
|
|
|
])))
|
2017-05-02 21:09:56 -07:00
|
|
|
|
|
|
|
def contrast_big_and_small_concavity(self):
|
|
|
|
colors = color_gradient([GREEN, WHITE], 3)
|
|
|
|
x0, y0 = 4, 2
|
|
|
|
graphs = [
|
|
|
|
self.get_graph(func, color = color)
|
|
|
|
for color, func in zip(colors, [
|
|
|
|
lambda x : 5*(x - x0)**2 + y0,
|
|
|
|
lambda x : 0.2*(x - x0)**2 + y0,
|
|
|
|
lambda x : (x-x0) + y0,
|
|
|
|
])
|
|
|
|
]
|
|
|
|
arg_rhs_list = [
|
|
|
|
TexMobject("(", str(x0), ")", "=", str(rhs))
|
2018-06-02 08:59:26 -04:00
|
|
|
for rhs in (10, 0.4, 0)
|
2017-05-02 21:09:56 -07:00
|
|
|
]
|
|
|
|
for graph, arg_rhs in zip(graphs, arg_rhs_list):
|
|
|
|
graph.ss_group = self.get_secant_slope_group(
|
|
|
|
x0-1, graph,
|
|
|
|
dx = 0.001,
|
|
|
|
secant_line_color = YELLOW
|
|
|
|
)
|
|
|
|
arg_rhs.move_to(self.second_deriv.get_center(), LEFT)
|
|
|
|
graph.arg_rhs = arg_rhs
|
|
|
|
graph = graphs[0]
|
|
|
|
|
|
|
|
v_line = DashedLine(*[
|
|
|
|
self.coords_to_point(x0, 0),
|
|
|
|
self.coords_to_point(x0, y0),
|
|
|
|
])
|
|
|
|
input_label = TexMobject(str(x0))
|
|
|
|
input_label.next_to(v_line, DOWN)
|
|
|
|
|
|
|
|
self.play(ShowCreation(graph, run_time = 2))
|
|
|
|
self.play(
|
|
|
|
Write(input_label),
|
|
|
|
ShowCreation(v_line)
|
|
|
|
)
|
|
|
|
self.play(
|
|
|
|
ReplacementTransform(
|
|
|
|
input_label.copy(),
|
|
|
|
graph.arg_rhs.get_part_by_tex(str(x0))
|
|
|
|
),
|
|
|
|
self.second_deriv.next_to, graph.arg_rhs.copy(), LEFT, SMALL_BUFF,
|
|
|
|
Write(VGroup(*[
|
|
|
|
submob
|
|
|
|
for submob in graph.arg_rhs
|
|
|
|
if submob is not graph.arg_rhs.get_part_by_tex(str(x0))
|
|
|
|
]))
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-02 21:09:56 -07:00
|
|
|
self.play(FadeIn(graph.ss_group))
|
|
|
|
self.animate_secant_slope_group_change(
|
|
|
|
graph.ss_group, target_x = x0 + 1,
|
|
|
|
run_time = 3,
|
|
|
|
)
|
|
|
|
self.play(FadeOut(graph.ss_group))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-02 21:09:56 -07:00
|
|
|
for new_graph in graphs[1:]:
|
|
|
|
self.play(Transform(graph, new_graph))
|
|
|
|
self.play(Transform(
|
|
|
|
graph.arg_rhs,
|
|
|
|
new_graph.arg_rhs,
|
|
|
|
))
|
|
|
|
self.play(FadeIn(new_graph.ss_group))
|
|
|
|
self.animate_secant_slope_group_change(
|
|
|
|
new_graph.ss_group, target_x = x0 + 1,
|
|
|
|
run_time = 3,
|
|
|
|
)
|
|
|
|
self.play(FadeOut(new_graph.ss_group))
|
|
|
|
|
|
|
|
class IntroduceNotation(TeacherStudentsScene):
|
|
|
|
def construct(self):
|
2017-05-05 11:19:10 -07:00
|
|
|
clunky_deriv = TexMobject(
|
|
|
|
"{d", "\\big(", "{df", "\\over", "dx}", "\\big)",
|
|
|
|
"\\over", "dx }"
|
|
|
|
)
|
|
|
|
over_index = clunky_deriv.index_of_part(
|
|
|
|
clunky_deriv.get_parts_by_tex("\\over")[1]
|
|
|
|
)
|
|
|
|
numerator = VGroup(*clunky_deriv[:over_index])
|
|
|
|
denominator = VGroup(*clunky_deriv[over_index+1:])
|
|
|
|
|
|
|
|
|
|
|
|
rp = clunky_deriv.get_part_by_tex("(")
|
|
|
|
lp = clunky_deriv.get_part_by_tex(")")
|
2018-08-09 17:56:05 -07:00
|
|
|
dfs, overs, dxs = list(map(clunky_deriv.get_parts_by_tex, [
|
2017-05-05 11:19:10 -07:00
|
|
|
"df", "over", "dx"
|
2018-08-09 17:56:05 -07:00
|
|
|
]))
|
2017-05-05 11:19:10 -07:00
|
|
|
df_over_dx = VGroup(dfs[0], overs[0], dxs[0])
|
|
|
|
d = clunky_deriv.get_part_by_tex("d")
|
|
|
|
d_over_dx = VGroup(d, overs[1], dxs[1])
|
|
|
|
|
|
|
|
d2f_over_dx2 = TexMobject("{d^2 f", "\\over", "dx", "^2}")
|
2018-03-30 11:51:31 -07:00
|
|
|
d2f_over_dx2.set_color_by_tex("dx", YELLOW)
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
for mob in clunky_deriv, d2f_over_dx2:
|
|
|
|
mob.next_to(self.teacher, UP+LEFT)
|
|
|
|
|
|
|
|
for mob in numerator, denominator:
|
|
|
|
circle = Circle(color = YELLOW)
|
|
|
|
circle.replace(mob, stretch = True)
|
|
|
|
circle.scale_in_place(1.3)
|
|
|
|
mob.circle = circle
|
|
|
|
dx_to_zero = TexMobject("dx \\to 0")
|
2018-03-30 11:51:31 -07:00
|
|
|
dx_to_zero.set_color(YELLOW)
|
2017-05-05 11:19:10 -07:00
|
|
|
dx_to_zero.next_to(clunky_deriv, UP+LEFT)
|
2017-05-02 21:09:56 -07:00
|
|
|
|
|
|
|
self.student_says(
|
2017-05-05 11:19:10 -07:00
|
|
|
"What's that notation?",
|
|
|
|
target_mode = "raise_left_hand"
|
|
|
|
)
|
|
|
|
self.change_student_modes("confused", "raise_left_hand", "confused")
|
|
|
|
self.play(
|
|
|
|
FadeIn(
|
|
|
|
clunky_deriv,
|
|
|
|
run_time = 2,
|
2019-02-08 15:53:27 -08:00
|
|
|
lag_ratio = 0.5
|
2017-05-05 11:19:10 -07:00
|
|
|
),
|
|
|
|
RemovePiCreatureBubble(self.get_students()[1]),
|
|
|
|
self.teacher.change_mode, "raise_right_hand"
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(ShowCreation(numerator.circle))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(ReplacementTransform(
|
|
|
|
numerator.circle,
|
|
|
|
denominator.circle,
|
|
|
|
))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(
|
|
|
|
FadeOut(denominator.circle),
|
|
|
|
Write(dx_to_zero),
|
2018-03-30 11:51:31 -07:00
|
|
|
dxs.set_color, YELLOW
|
2017-05-05 11:19:10 -07:00
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(
|
|
|
|
FadeOut(dx_to_zero),
|
|
|
|
*[ApplyMethod(pi.change, "plain") for pi in self.get_pi_creatures()]
|
|
|
|
)
|
|
|
|
self.play(
|
|
|
|
df_over_dx.scale, dxs[1].get_height()/dxs[0].get_height(),
|
|
|
|
df_over_dx.move_to, d_over_dx, RIGHT,
|
|
|
|
FadeOut(VGroup(lp, rp)),
|
|
|
|
d_over_dx.shift, 0.8*LEFT + 0.05*UP,
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(*[
|
|
|
|
ReplacementTransform(
|
|
|
|
group,
|
|
|
|
VGroup(d2f_over_dx2.get_part_by_tex(tex))
|
|
|
|
)
|
|
|
|
for group, tex in [
|
|
|
|
(VGroup(d, dfs[0]), "d^2"),
|
|
|
|
(overs, "over"),
|
|
|
|
(dxs, "dx"),
|
|
|
|
(VGroup(dxs[1].copy()), "^2}"),
|
|
|
|
]
|
|
|
|
])
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-05 11:19:10 -07:00
|
|
|
self.student_says(
|
|
|
|
"How does one... \\\\ read that?",
|
|
|
|
student_index = 0,
|
|
|
|
)
|
|
|
|
self.play(self.teacher.change, "happy")
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
class HowToReadNotation(GraphScene, ReconfigurableScene):
|
|
|
|
CONFIG = {
|
|
|
|
"x_max" : 5,
|
|
|
|
"dx" : 0.4,
|
|
|
|
"x" : 2,
|
|
|
|
"graph_origin" : 2.5*DOWN + 5*LEFT,
|
|
|
|
}
|
|
|
|
def setup(self):
|
|
|
|
for base in self.__class__.__bases__:
|
|
|
|
base.setup(self)
|
|
|
|
|
|
|
|
def construct(self):
|
|
|
|
self.force_skipping()
|
|
|
|
|
|
|
|
self.add_graph()
|
|
|
|
self.take_two_steps()
|
|
|
|
self.change_step_size()
|
|
|
|
self.show_dfs()
|
|
|
|
self.show_ddf()
|
|
|
|
|
|
|
|
self.revert_to_original_skipping_status()
|
|
|
|
self.show_proportionality_to_dx_squared()
|
|
|
|
return
|
|
|
|
|
|
|
|
self.write_second_derivative()
|
|
|
|
|
|
|
|
def add_graph(self):
|
|
|
|
self.setup_axes()
|
|
|
|
graph = self.get_graph(lambda x : x**2)
|
|
|
|
graph_label = self.get_graph_label(
|
|
|
|
graph, "f(x)",
|
|
|
|
direction = LEFT,
|
|
|
|
x_val = 3.3
|
2017-05-02 21:09:56 -07:00
|
|
|
)
|
2017-05-05 11:19:10 -07:00
|
|
|
self.add(graph, graph_label)
|
2017-05-02 21:09:56 -07:00
|
|
|
|
2017-05-05 11:19:10 -07:00
|
|
|
self.graph = graph
|
2017-05-02 21:09:56 -07:00
|
|
|
|
2017-05-05 11:19:10 -07:00
|
|
|
def take_two_steps(self):
|
|
|
|
v_lines = [
|
|
|
|
self.get_vertical_line_to_graph(
|
|
|
|
self.x + i*self.dx, self.graph,
|
|
|
|
line_class = DashedLine,
|
|
|
|
color = WHITE
|
|
|
|
)
|
|
|
|
for i in range(3)
|
|
|
|
]
|
|
|
|
braces = [
|
|
|
|
Brace(VGroup(*v_lines[i:i+2]), buff = 0)
|
|
|
|
for i in range(2)
|
|
|
|
]
|
|
|
|
for brace in braces:
|
|
|
|
brace.dx = TexMobject("dx")
|
|
|
|
max_width = 0.7*brace.get_width()
|
|
|
|
if brace.dx.get_width() > max_width:
|
2018-08-08 10:30:52 -07:00
|
|
|
brace.dx.set_width(max_width)
|
2017-05-05 11:19:10 -07:00
|
|
|
brace.dx.next_to(brace, DOWN, SMALL_BUFF)
|
|
|
|
|
|
|
|
self.play(ShowCreation(v_lines[0]))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
for brace, line in zip(braces, v_lines[1:]):
|
|
|
|
self.play(
|
|
|
|
ReplacementTransform(
|
|
|
|
VectorizedPoint(brace.get_corner(UP+LEFT)),
|
|
|
|
brace,
|
|
|
|
),
|
|
|
|
Write(brace.dx, run_time = 1),
|
|
|
|
)
|
|
|
|
self.play(ShowCreation(line))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
self.v_lines = v_lines
|
|
|
|
self.braces = braces
|
|
|
|
|
|
|
|
def change_step_size(self):
|
|
|
|
self.transition_to_alt_config(dx = 0.6)
|
|
|
|
self.transition_to_alt_config(dx = 0.01, run_time = 3)
|
|
|
|
|
|
|
|
def show_dfs(self):
|
|
|
|
dx_lines = VGroup()
|
|
|
|
df_lines = VGroup()
|
|
|
|
df_dx_groups = VGroup()
|
|
|
|
df_labels = VGroup()
|
|
|
|
for i, v_line1, v_line2 in zip(it.count(1), self.v_lines, self.v_lines[1:]):
|
|
|
|
dx_line = Line(
|
|
|
|
v_line1.get_bottom(),
|
|
|
|
v_line2.get_bottom(),
|
|
|
|
color = GREEN
|
|
|
|
)
|
|
|
|
dx_line.move_to(v_line1.get_top(), LEFT)
|
|
|
|
dx_lines.add(dx_line)
|
2017-05-02 21:09:56 -07:00
|
|
|
|
2017-05-05 11:19:10 -07:00
|
|
|
df_line = Line(
|
|
|
|
dx_line.get_right(),
|
|
|
|
v_line2.get_top(),
|
|
|
|
color = YELLOW
|
|
|
|
)
|
|
|
|
df_lines.add(df_line)
|
|
|
|
df_label = TexMobject("df_%d"%i)
|
2018-03-30 11:51:31 -07:00
|
|
|
df_label.set_color(YELLOW)
|
2017-05-05 11:19:10 -07:00
|
|
|
df_label.scale(0.8)
|
|
|
|
df_label.next_to(df_line.get_center(), UP+LEFT, MED_LARGE_BUFF)
|
|
|
|
df_arrow = Arrow(
|
|
|
|
df_label.get_bottom(),
|
|
|
|
df_line.get_center(),
|
|
|
|
buff = SMALL_BUFF,
|
|
|
|
)
|
|
|
|
df_line.label = df_label
|
|
|
|
df_line.arrow = df_arrow
|
|
|
|
df_labels.add(df_label)
|
2017-05-02 21:09:56 -07:00
|
|
|
|
2017-05-05 11:19:10 -07:00
|
|
|
df_dx_groups.add(VGroup(df_line, dx_line))
|
|
|
|
|
|
|
|
for brace, dx_line, df_line in zip(self.braces, dx_lines, df_lines):
|
|
|
|
self.play(
|
|
|
|
VGroup(brace, brace.dx).next_to,
|
|
|
|
dx_line, DOWN, SMALL_BUFF,
|
|
|
|
FadeIn(dx_line),
|
|
|
|
)
|
|
|
|
self.play(ShowCreation(df_line))
|
|
|
|
self.play(
|
|
|
|
ShowCreation(df_line.arrow),
|
|
|
|
Write(df_line.label)
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
self.df_dx_groups = df_dx_groups
|
|
|
|
self.df_labels = df_labels
|
|
|
|
|
|
|
|
def show_ddf(self):
|
|
|
|
df_dx_groups = self.df_dx_groups.copy()
|
|
|
|
df_dx_groups.generate_target()
|
2019-02-04 14:54:25 -08:00
|
|
|
df_dx_groups.target.arrange(
|
2017-05-05 11:19:10 -07:00
|
|
|
RIGHT,
|
|
|
|
buff = MED_LARGE_BUFF,
|
|
|
|
aligned_edge = DOWN
|
|
|
|
)
|
|
|
|
df_dx_groups.target.next_to(
|
|
|
|
self.df_dx_groups, RIGHT,
|
|
|
|
buff = 3,
|
|
|
|
aligned_edge = DOWN
|
|
|
|
)
|
|
|
|
|
|
|
|
df_labels = self.df_labels.copy()
|
|
|
|
df_labels.generate_target()
|
|
|
|
h_lines = VGroup()
|
|
|
|
for group, label in zip(df_dx_groups.target, df_labels.target):
|
|
|
|
label.next_to(group.get_right(), LEFT, SMALL_BUFF)
|
|
|
|
width = df_dx_groups.target.get_width() + MED_SMALL_BUFF
|
|
|
|
h_line = DashedLine(ORIGIN, width*RIGHT)
|
|
|
|
h_line.move_to(
|
|
|
|
group.get_corner(UP+RIGHT)[1]*UP + \
|
|
|
|
df_dx_groups.target.get_right()[0]*RIGHT,
|
|
|
|
RIGHT
|
|
|
|
)
|
|
|
|
h_lines.add(h_line)
|
|
|
|
max_height = 0.8*group.get_height()
|
|
|
|
if label.get_height() > max_height:
|
2018-08-08 10:30:52 -07:00
|
|
|
label.set_height(max_height)
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
|
|
|
|
ddf_brace = Brace(h_lines, LEFT, buff = SMALL_BUFF)
|
|
|
|
ddf = ddf_brace.get_tex("d(df)", buff = SMALL_BUFF)
|
|
|
|
ddf.scale(
|
|
|
|
df_labels[0].get_height()/ddf.get_height(),
|
|
|
|
about_point = ddf.get_right()
|
|
|
|
)
|
2018-03-30 11:51:31 -07:00
|
|
|
ddf.set_color(MAROON_B)
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
self.play(
|
2018-08-09 17:56:05 -07:00
|
|
|
*list(map(MoveToTarget, [df_dx_groups, df_labels])),
|
2017-05-05 11:19:10 -07:00
|
|
|
run_time = 2
|
|
|
|
)
|
|
|
|
self.play(ShowCreation(h_lines, run_time = 2))
|
|
|
|
self.play(GrowFromCenter(ddf_brace))
|
|
|
|
self.play(Write(ddf))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
self.ddf = ddf
|
|
|
|
|
|
|
|
def show_proportionality_to_dx_squared(self):
|
|
|
|
ddf = self.ddf.copy()
|
|
|
|
ddf.generate_target()
|
|
|
|
ddf.target.next_to(self.ddf, UP, LARGE_BUFF)
|
|
|
|
rhs = TexMobject(
|
|
|
|
"\\approx", "(\\text{Some constant})", "(dx)^2"
|
|
|
|
)
|
|
|
|
rhs.scale(0.8)
|
|
|
|
rhs.next_to(ddf.target, RIGHT)
|
|
|
|
|
|
|
|
example_dx = TexMobject(
|
|
|
|
"dx = 0.01 \\Rightarrow (dx)^2 = 0.0001"
|
|
|
|
)
|
|
|
|
example_dx.scale(0.8)
|
|
|
|
example_dx.to_corner(UP+RIGHT)
|
|
|
|
|
|
|
|
self.play(MoveToTarget(ddf))
|
|
|
|
self.play(Write(rhs))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(Write(example_dx))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(FadeOut(example_dx))
|
|
|
|
|
|
|
|
self.ddf = ddf
|
|
|
|
self.dx_squared = rhs.get_part_by_tex("dx")
|
|
|
|
|
|
|
|
def write_second_derivative(self):
|
|
|
|
ddf_over_dx_squared = TexMobject(
|
|
|
|
"{d(df)", "\\over", "(dx)^2}"
|
|
|
|
)
|
|
|
|
ddf_over_dx_squared.scale(0.8)
|
|
|
|
ddf_over_dx_squared.move_to(self.ddf, RIGHT)
|
2018-03-30 11:51:31 -07:00
|
|
|
ddf_over_dx_squared.set_color_by_tex("df", self.ddf.get_color())
|
2017-05-05 11:19:10 -07:00
|
|
|
parens = VGroup(
|
|
|
|
ddf_over_dx_squared[0][1],
|
|
|
|
ddf_over_dx_squared[0][4],
|
|
|
|
ddf_over_dx_squared[2][0],
|
|
|
|
ddf_over_dx_squared[2][3],
|
|
|
|
)
|
|
|
|
|
|
|
|
right_shifter = ddf_over_dx_squared[0][0]
|
|
|
|
left_shifter = ddf_over_dx_squared[2][4]
|
|
|
|
|
|
|
|
exp_two = TexMobject("2")
|
2018-03-30 11:51:31 -07:00
|
|
|
exp_two.set_color(self.ddf.get_color())
|
2017-05-05 11:19:10 -07:00
|
|
|
exp_two.scale(0.5)
|
|
|
|
exp_two.move_to(right_shifter.get_corner(UP+RIGHT), LEFT)
|
|
|
|
exp_two.shift(MED_SMALL_BUFF*RIGHT)
|
|
|
|
pre_exp_two = VGroup(ddf_over_dx_squared[0][2])
|
|
|
|
|
|
|
|
self.play(
|
|
|
|
Write(ddf_over_dx_squared.get_part_by_tex("over")),
|
|
|
|
*[
|
|
|
|
ReplacementTransform(
|
|
|
|
mob,
|
|
|
|
ddf_over_dx_squared.get_part_by_tex(tex),
|
|
|
|
path_arc = -np.pi/2,
|
|
|
|
)
|
2018-09-19 08:53:28 +05:30
|
|
|
for mob, tex in [(self.ddf, "df"), (self.dx_squared, "dx")]
|
2017-05-05 11:19:10 -07:00
|
|
|
]
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(FadeOut(parens))
|
|
|
|
self.play(
|
|
|
|
left_shifter.shift, 0.2*LEFT,
|
|
|
|
right_shifter.shift, 0.2*RIGHT,
|
|
|
|
ReplacementTransform(pre_exp_two, exp_two),
|
|
|
|
ddf_over_dx_squared.get_part_by_tex("over").scale_in_place, 0.8
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
class Footnote(Scene):
|
|
|
|
def construct(self):
|
|
|
|
self.add(TextMobject("""
|
|
|
|
Interestingly, there is a notion in math
|
|
|
|
called the ``exterior derivative'' which
|
|
|
|
treats this ``d'' as having a more independent
|
|
|
|
meaning, though it's less related to the
|
|
|
|
intuitions I've introduced in this series.
|
|
|
|
""", alignment = ""))
|
|
|
|
|
|
|
|
class TrajectoryGraphScene(GraphScene):
|
|
|
|
CONFIG = {
|
|
|
|
"x_min" : 0,
|
|
|
|
"x_max" : 10,
|
|
|
|
"x_axis_label" : "t",
|
|
|
|
"y_axis_label" : "s",
|
|
|
|
# "func" : lambda x : 10*smooth(x/10.0),
|
|
|
|
"func" : lambda t : 10*bezier([0, 0, 0, 1, 1, 1])(t/10.0),
|
|
|
|
"color" : BLUE,
|
|
|
|
}
|
|
|
|
def construct(self):
|
|
|
|
self.setup_axes()
|
|
|
|
self.graph = self.get_graph(
|
|
|
|
self.func,
|
|
|
|
color = self.color
|
|
|
|
)
|
|
|
|
self.add(self.graph)
|
|
|
|
|
|
|
|
class SecondDerivativeAsAcceleration(Scene):
|
|
|
|
CONFIG = {
|
|
|
|
"car_run_time" : 6,
|
|
|
|
}
|
|
|
|
def construct(self):
|
|
|
|
self.init_car_and_line()
|
|
|
|
self.introduce_acceleration()
|
|
|
|
self.show_functions()
|
|
|
|
|
|
|
|
def init_car_and_line(self):
|
|
|
|
line = Line(5.5*LEFT, 4.5*RIGHT)
|
|
|
|
line.shift(2*DOWN)
|
|
|
|
car = Car()
|
|
|
|
car.move_to(line.get_left())
|
|
|
|
self.add(line, car)
|
|
|
|
self.car = car
|
|
|
|
self.start_car_copy = car.copy()
|
|
|
|
self.line = line
|
|
|
|
|
|
|
|
def introduce_acceleration(self):
|
|
|
|
a_words = TexMobject(
|
|
|
|
"{d^2 s \\over dt^2}(t)", "\\Leftrightarrow",
|
|
|
|
"\\text{Acceleration}"
|
|
|
|
)
|
2018-03-30 11:51:31 -07:00
|
|
|
a_words.set_color_by_tex("d^2 s", MAROON_B)
|
|
|
|
a_words.set_color_by_tex("Acceleration", YELLOW)
|
2017-05-05 11:19:10 -07:00
|
|
|
a_words.to_corner(UP+RIGHT )
|
|
|
|
self.add(a_words)
|
|
|
|
self.show_car_movement()
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
self.a_words = a_words
|
|
|
|
|
|
|
|
def show_functions(self):
|
|
|
|
def get_deriv(n):
|
|
|
|
return lambda x : derivative(
|
|
|
|
s_scene.graph.underlying_function, x, n
|
|
|
|
)
|
|
|
|
s_scene = TrajectoryGraphScene()
|
|
|
|
v_scene = TrajectoryGraphScene(
|
|
|
|
func = get_deriv(1),
|
|
|
|
color = GREEN,
|
|
|
|
y_max = 4,
|
|
|
|
y_axis_label = "v",
|
|
|
|
)
|
|
|
|
a_scene = TrajectoryGraphScene(
|
|
|
|
func = get_deriv(2),
|
|
|
|
color = MAROON_B,
|
|
|
|
y_axis_label = "a",
|
|
|
|
y_min = -2,
|
|
|
|
y_max = 2,
|
|
|
|
)
|
|
|
|
j_scene = TrajectoryGraphScene(
|
|
|
|
func = get_deriv(3),
|
|
|
|
color = PINK,
|
|
|
|
y_axis_label = "j",
|
|
|
|
y_min = -2,
|
|
|
|
y_max = 2,
|
|
|
|
)
|
|
|
|
s_graph, v_graph, a_graph, j_graph = graphs = [
|
|
|
|
VGroup(*scene.get_top_level_mobjects())
|
2018-06-02 08:59:26 -04:00
|
|
|
for scene in (s_scene, v_scene, a_scene, j_scene)
|
2017-05-05 11:19:10 -07:00
|
|
|
]
|
|
|
|
for i, graph in enumerate(graphs):
|
2018-08-08 10:30:52 -07:00
|
|
|
graph.set_height(FRAME_Y_RADIUS)
|
2017-05-05 11:19:10 -07:00
|
|
|
graph.to_corner(UP+LEFT)
|
|
|
|
graph.shift(i*DOWN/2.0)
|
|
|
|
|
|
|
|
s_words = TexMobject(
|
|
|
|
"s(t)", "\\Leftrightarrow", "\\text{Displacement}"
|
|
|
|
)
|
2018-03-30 11:51:31 -07:00
|
|
|
s_words.set_color_by_tex("s(t)", s_scene.graph.get_color())
|
2017-05-05 11:19:10 -07:00
|
|
|
v_words = TexMobject(
|
|
|
|
"\\frac{ds}{dt}(t)", "\\Leftrightarrow",
|
|
|
|
"\\text{Velocity}"
|
|
|
|
)
|
2018-03-30 11:51:31 -07:00
|
|
|
v_words.set_color_by_tex("ds", v_scene.graph.get_color())
|
2017-05-05 11:19:10 -07:00
|
|
|
j_words = TexMobject(
|
|
|
|
"\\frac{d^3 s}{dt^3}(t)", "\\Leftrightarrow",
|
|
|
|
"\\text{Jerk}"
|
|
|
|
)
|
2018-03-30 11:51:31 -07:00
|
|
|
j_words.set_color_by_tex("d^3", j_scene.graph.get_color())
|
2017-05-05 11:19:10 -07:00
|
|
|
self.a_words.generate_target()
|
|
|
|
words_group = VGroup(s_words, v_words, self.a_words.target, j_words)
|
2019-02-04 14:54:25 -08:00
|
|
|
words_group.arrange(
|
2017-05-05 11:19:10 -07:00
|
|
|
DOWN,
|
|
|
|
buff = MED_LARGE_BUFF,
|
|
|
|
aligned_edge = LEFT
|
|
|
|
)
|
|
|
|
words_group.to_corner(UP+RIGHT)
|
|
|
|
j_graph.scale(0.3).next_to(j_words, LEFT)
|
|
|
|
|
|
|
|
positive_rect = Rectangle()
|
|
|
|
positive_rect.set_stroke(width = 0)
|
|
|
|
positive_rect.set_fill(GREEN, 0.5)
|
|
|
|
positive_rect.replace(
|
|
|
|
Line(
|
|
|
|
a_scene.coords_to_point(0, -1),
|
|
|
|
a_scene.coords_to_point(5, 1),
|
|
|
|
),
|
|
|
|
stretch = True
|
|
|
|
)
|
|
|
|
negative_rect = Rectangle()
|
|
|
|
negative_rect.set_stroke(width = 0)
|
|
|
|
negative_rect.set_fill(RED, 0.5)
|
|
|
|
negative_rect.replace(
|
|
|
|
Line(
|
|
|
|
a_scene.coords_to_point(5, 1),
|
|
|
|
a_scene.coords_to_point(10, -1),
|
|
|
|
),
|
|
|
|
stretch = True
|
|
|
|
)
|
|
|
|
|
|
|
|
self.show_car_movement(
|
|
|
|
MoveToTarget(self.a_words),
|
|
|
|
FadeIn(s_words),
|
|
|
|
FadeIn(s_graph),
|
|
|
|
)
|
|
|
|
self.play(
|
|
|
|
s_graph.scale, 0.3,
|
|
|
|
s_graph.next_to, s_words, LEFT
|
|
|
|
)
|
2018-08-09 17:56:05 -07:00
|
|
|
self.play(*list(map(FadeIn, [v_graph, v_words])) )
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(
|
|
|
|
v_graph.scale, 0.3,
|
|
|
|
v_graph.next_to, v_words, LEFT
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(
|
|
|
|
Indicate(self.a_words),
|
|
|
|
FadeIn(a_graph),
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(FadeIn(positive_rect))
|
|
|
|
for x in range(2):
|
|
|
|
self.show_car_movement(
|
|
|
|
run_time = 3,
|
|
|
|
rate_func = lambda t : smooth(t/2.0)
|
|
|
|
)
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(FadeIn(negative_rect))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(MoveCar(
|
|
|
|
self.car, self.line.get_end(),
|
|
|
|
run_time = 3,
|
|
|
|
rate_func = lambda t : 2*smooth((t+1)/2.0) - 1
|
|
|
|
))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
self.play(
|
|
|
|
a_graph.scale, 0.3,
|
|
|
|
a_graph.next_to, self.a_words, LEFT,
|
2018-08-09 17:56:05 -07:00
|
|
|
*list(map(FadeOut, [positive_rect, negative_rect]))
|
2017-05-05 11:19:10 -07:00
|
|
|
)
|
|
|
|
self.play(
|
|
|
|
FadeOut(self.car),
|
|
|
|
FadeIn(j_words),
|
|
|
|
FadeIn(j_graph),
|
|
|
|
self.line.scale, 0.5, self.line.get_left(),
|
|
|
|
self.line.shift, LEFT,
|
|
|
|
)
|
|
|
|
self.car.scale(0.5)
|
|
|
|
self.car.move_to(self.line.get_start())
|
|
|
|
self.play(FadeIn(self.car))
|
|
|
|
self.show_car_movement()
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait(2)
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
##########
|
|
|
|
|
|
|
|
def show_car_movement(self, *added_anims, **kwargs):
|
2018-08-15 17:30:24 -07:00
|
|
|
distance = get_norm(
|
2017-05-05 11:19:10 -07:00
|
|
|
self.car.get_center() - self.start_car_copy.get_center()
|
|
|
|
)
|
|
|
|
if distance > 1:
|
|
|
|
self.play(FadeOut(self.car))
|
|
|
|
self.car.move_to(self.line.get_left())
|
|
|
|
self.play(FadeIn(self.car))
|
|
|
|
|
|
|
|
kwargs["run_time"] = kwargs.get("run_time", self.car_run_time)
|
|
|
|
self.play(
|
|
|
|
MoveCar(self.car, self.line.get_right(), **kwargs),
|
|
|
|
*added_anims
|
|
|
|
)
|
|
|
|
|
|
|
|
class NextVideo(Scene):
|
|
|
|
def construct(self):
|
|
|
|
title = TextMobject("Chapter 10: Taylor series")
|
|
|
|
title.to_edge(UP)
|
|
|
|
rect = ScreenRectangle(height = 6)
|
|
|
|
rect.next_to(title, DOWN)
|
|
|
|
self.add(rect)
|
|
|
|
self.play(Write(title))
|
2018-01-15 19:15:05 -08:00
|
|
|
self.wait()
|
2017-05-05 11:19:10 -07:00
|
|
|
|
|
|
|
class Thumbnail(SecondDerivativeGraphically):
|
|
|
|
CONFIG = {
|
|
|
|
"graph_origin" : 5*LEFT + 3*DOWN,
|
|
|
|
"x_axis_label" : "",
|
|
|
|
"y_axis_label" : "",
|
|
|
|
}
|
|
|
|
def construct(self):
|
|
|
|
self.setup_axes()
|
|
|
|
self.force_skipping()
|
|
|
|
self.draw_f()
|
|
|
|
self.remove(self.graph_label)
|
|
|
|
self.graph.set_stroke(GREEN, width = 8)
|
2017-05-02 21:09:56 -07:00
|
|
|
|
2017-05-05 11:19:10 -07:00
|
|
|
tex = TexMobject("{d^n f", "\\over", "dx^n}")
|
2018-03-30 11:51:31 -07:00
|
|
|
tex.set_color_by_tex("d^n", YELLOW)
|
|
|
|
tex.set_color_by_tex("dx", BLUE)
|
2018-08-08 10:30:52 -07:00
|
|
|
tex.set_height(4)
|
2017-05-05 11:19:10 -07:00
|
|
|
tex.to_edge(UP)
|
2017-05-02 21:09:56 -07:00
|
|
|
|
2017-05-05 11:19:10 -07:00
|
|
|
self.add(tex)
|
2017-05-02 21:09:56 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|