mirror of
https://github.com/3b1b/manim.git
synced 2025-07-30 21:44:19 +08:00
Preliminary end to exp_footnote
This commit is contained in:
@ -25,19 +25,30 @@ from camera import Camera
|
|||||||
from mobject.svg_mobject import *
|
from mobject.svg_mobject import *
|
||||||
from mobject.tex_mobject import *
|
from mobject.tex_mobject import *
|
||||||
|
|
||||||
|
from topics.common_scenes import OpeningQuote
|
||||||
|
|
||||||
from eoc.graph_scene import *
|
from eoc.graph_scene import *
|
||||||
|
|
||||||
|
class ExpFootnoteOpeningQuote(OpeningQuote):
|
||||||
|
CONFIG = {
|
||||||
|
"quote" : [
|
||||||
|
"Who has not be amazed to learn that the function",
|
||||||
|
"$y = e^x$,", "like a phoenix rising again from its own",
|
||||||
|
"ashes, is its own derivative?",
|
||||||
|
],
|
||||||
|
"highlighted_quote_terms" : {
|
||||||
|
"$y = e^x$" : MAROON_B
|
||||||
|
},
|
||||||
|
"author" : "Francois le Lionnais"
|
||||||
|
}
|
||||||
|
|
||||||
class LastVideo(TeacherStudentsScene):
|
class LastVideo(TeacherStudentsScene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
series = VideoSeries()
|
series = VideoSeries()
|
||||||
series.to_edge(UP)
|
series.to_edge(UP)
|
||||||
last_video = series[2]
|
last_video = series[2]
|
||||||
next_video = series[3]
|
last_video.save_state()
|
||||||
last_video_color = last_video[0].get_fill_color()
|
this_video = series[3]
|
||||||
early_videos = VGroup(*series[:3])
|
|
||||||
later_videos = VGroup(*series[3:])
|
|
||||||
this_video = VideoIcon().scale(0.5)
|
|
||||||
this_video.move_to(VGroup(last_video, next_video), DOWN)
|
|
||||||
|
|
||||||
known_formulas = VGroup(*map(TexMobject, [
|
known_formulas = VGroup(*map(TexMobject, [
|
||||||
"\\frac{d(x^n)}{dx} = nx^{n-1}",
|
"\\frac{d(x^n)}{dx} = nx^{n-1}",
|
||||||
@ -69,32 +80,20 @@ class LastVideo(TeacherStudentsScene):
|
|||||||
)
|
)
|
||||||
self.dither(2)
|
self.dither(2)
|
||||||
self.play(known_formulas.replace, last_video)
|
self.play(known_formulas.replace, last_video)
|
||||||
last_video.add(known_formulas)
|
self.play(last_video_brace.next_to, this_video, DOWN)
|
||||||
this_video_copy = this_video.copy()
|
|
||||||
self.play(
|
self.play(
|
||||||
early_videos.stretch_to_fit_width,
|
last_video.restore,
|
||||||
early_videos.get_width() - this_video_copy.get_width(),
|
|
||||||
early_videos.next_to, this_video_copy, LEFT, SMALL_BUFF, DOWN,
|
|
||||||
later_videos.stretch_to_fit_width,
|
|
||||||
later_videos.get_width() - this_video_copy.get_width(),
|
|
||||||
later_videos.next_to, this_video_copy, RIGHT, SMALL_BUFF, DOWN,
|
|
||||||
last_video_brace.stretch_to_fit_width,
|
|
||||||
this_video_copy.get_width(),
|
|
||||||
last_video_brace.next_to, this_video_copy, DOWN, SMALL_BUFF,
|
|
||||||
GrowFromCenter(this_video)
|
|
||||||
)
|
|
||||||
self.play(
|
|
||||||
last_video.highlight, last_video_color,
|
|
||||||
this_video.highlight, YELLOW
|
this_video.highlight, YELLOW
|
||||||
)
|
)
|
||||||
self.play(
|
self.play(
|
||||||
FadeOut(self.get_students()[-1].bubble),
|
|
||||||
exp_question.next_to, last_video_brace, DOWN,
|
exp_question.next_to, last_video_brace, DOWN,
|
||||||
*[
|
FadeOut(self.get_students()[-1].bubble),
|
||||||
ApplyMethod(pi.change_mode, "pondering")
|
|
||||||
for pi in self.get_students()
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
self.change_student_modes(
|
||||||
|
*["pondering"]*3,
|
||||||
|
look_at_arg = exp_question
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
class PopulationSizeGraphVsPopulationMassGraph(Scene):
|
class PopulationSizeGraphVsPopulationMassGraph(Scene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
@ -476,6 +475,131 @@ class DoublingPopulation(PiCreatureScene):
|
|||||||
|
|
||||||
return top_words, bottom_words
|
return top_words, bottom_words
|
||||||
|
|
||||||
|
class GraphOfTwoToT(GraphScene):
|
||||||
|
CONFIG = {
|
||||||
|
"x_axis_label" : "$t$",
|
||||||
|
"y_axis_label" : "$M$",
|
||||||
|
"x_labeled_nums" : range(1, 7),
|
||||||
|
"y_labeled_nums" : range(8, 40, 8),
|
||||||
|
"x_max" : 6,
|
||||||
|
"y_min" : 0,
|
||||||
|
"y_max" : 32,
|
||||||
|
"y_tick_frequency" : 2,
|
||||||
|
"graph_origin" : 2.5*DOWN + 5*LEFT,
|
||||||
|
}
|
||||||
|
def construct(self):
|
||||||
|
self.setup_axes()
|
||||||
|
example_t = 3
|
||||||
|
graph = self.get_graph(lambda t : 2**t, color = BLUE_C)
|
||||||
|
self.graph = graph
|
||||||
|
graph_label = self.get_graph_label(
|
||||||
|
graph, "M(t) = 2^t",
|
||||||
|
direction = LEFT,
|
||||||
|
)
|
||||||
|
label_group = self.get_label_group(example_t)
|
||||||
|
v_line, brace, height_label, ss_group, slope_label = label_group
|
||||||
|
self.animate_secant_slope_group_change(
|
||||||
|
ss_group,
|
||||||
|
target_dx = 1,
|
||||||
|
run_time = 0
|
||||||
|
)
|
||||||
|
self.remove(ss_group)
|
||||||
|
|
||||||
|
#Draw graph and revert to tangent
|
||||||
|
self.play(ShowCreation(graph))
|
||||||
|
self.play(Write(graph_label))
|
||||||
|
self.dither()
|
||||||
|
self.play(Write(ss_group))
|
||||||
|
self.dither()
|
||||||
|
for target_dx in 0.01, 1, 0.01:
|
||||||
|
self.animate_secant_slope_group_change(
|
||||||
|
ss_group,
|
||||||
|
target_dx = target_dx
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
#Mark up with values
|
||||||
|
|
||||||
|
self.play(ShowCreation(v_line))
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(brace),
|
||||||
|
Write(height_label, run_time = 1)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
FadeIn(
|
||||||
|
slope_label,
|
||||||
|
run_time = 4,
|
||||||
|
submobject_mode = "lagged_start"
|
||||||
|
),
|
||||||
|
ReplacementTransform(
|
||||||
|
height_label.copy(),
|
||||||
|
slope_label.get_part_by_tex("2^")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
#Vary value
|
||||||
|
threes = VGroup(height_label[1], slope_label[2][1])
|
||||||
|
ts = VGroup(*[
|
||||||
|
TexMobject("t").highlight(YELLOW).scale(0.75).move_to(three)
|
||||||
|
for three in threes
|
||||||
|
])
|
||||||
|
self.play(Transform(threes, ts))
|
||||||
|
|
||||||
|
alt_example_t = example_t+1
|
||||||
|
def update_label_group(group, alpha):
|
||||||
|
t = interpolate(example_t, alt_example_t, alpha)
|
||||||
|
new_group = self.get_label_group(t)
|
||||||
|
Transform(group, new_group).update(1)
|
||||||
|
for t, three in zip(ts, threes):
|
||||||
|
t.move_to(three)
|
||||||
|
Transform(threes, ts).update(1)
|
||||||
|
return group
|
||||||
|
|
||||||
|
self.play(UpdateFromAlphaFunc(
|
||||||
|
label_group, update_label_group,
|
||||||
|
run_time = 3,
|
||||||
|
))
|
||||||
|
self.play(UpdateFromAlphaFunc(
|
||||||
|
label_group, update_label_group,
|
||||||
|
run_time = 3,
|
||||||
|
rate_func = lambda t : 1 - 1.5*smooth(t)
|
||||||
|
))
|
||||||
|
|
||||||
|
def get_label_group(self, t):
|
||||||
|
graph = self.graph
|
||||||
|
|
||||||
|
v_line = self.get_vertical_line_to_graph(
|
||||||
|
t, graph,
|
||||||
|
color = YELLOW,
|
||||||
|
)
|
||||||
|
brace = Brace(v_line, RIGHT)
|
||||||
|
height_label = brace.get_text("$2^%d$"%t)
|
||||||
|
|
||||||
|
ss_group = self.get_secant_slope_group(
|
||||||
|
t, graph, dx = 0.01,
|
||||||
|
df_label = "dM",
|
||||||
|
dx_label = "dt",
|
||||||
|
dx_line_color = GREEN,
|
||||||
|
secant_line_color = RED,
|
||||||
|
)
|
||||||
|
slope_label = TexMobject(
|
||||||
|
"\\text{Slope}", "=",
|
||||||
|
"2^%d"%t,
|
||||||
|
"(%.7f\\dots)"%np.log(2)
|
||||||
|
)
|
||||||
|
slope_label.next_to(
|
||||||
|
ss_group.secant_line.point_from_proportion(0.65),
|
||||||
|
DOWN+RIGHT,
|
||||||
|
buff = 0
|
||||||
|
)
|
||||||
|
slope_label.highlight_by_tex("Slope", RED)
|
||||||
|
return VGroup(
|
||||||
|
v_line, brace, height_label,
|
||||||
|
ss_group, slope_label
|
||||||
|
)
|
||||||
|
|
||||||
class AnalyzeExponentRatio(PiCreatureScene):
|
class AnalyzeExponentRatio(PiCreatureScene):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"base" : 2,
|
"base" : 2,
|
||||||
@ -698,6 +822,12 @@ class AnalyzeExponentRatio(PiCreatureScene):
|
|||||||
self.change_mode("confused")
|
self.change_mode("confused")
|
||||||
self.dither()
|
self.dither()
|
||||||
|
|
||||||
|
#Indicate distinction between dt group and t group again
|
||||||
|
for mob in limit_term, extracted_two_to_t:
|
||||||
|
self.play(FocusOn(mob))
|
||||||
|
self.play(Indicate(mob))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
#hold_final_value
|
#hold_final_value
|
||||||
derivative = VGroup(
|
derivative = VGroup(
|
||||||
lhs, extracted_two_to_t, parens, constant
|
lhs, extracted_two_to_t, parens, constant
|
||||||
@ -765,8 +895,8 @@ class ExponentRatioWithThree(AnalyzeExponentRatio):
|
|||||||
|
|
||||||
class ExponentRatioWithSeven(AnalyzeExponentRatio):
|
class ExponentRatioWithSeven(AnalyzeExponentRatio):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"base" : 3,
|
"base" : 7,
|
||||||
"base_str" : "3",
|
"base_str" : "7",
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExponentRatioWithE(AnalyzeExponentRatio):
|
class ExponentRatioWithE(AnalyzeExponentRatio):
|
||||||
@ -904,6 +1034,67 @@ class NaturalLog(Scene):
|
|||||||
expression.add(brace, brace_text)
|
expression.add(brace, brace_text)
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
|
class NextVideo(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
series = VideoSeries()
|
||||||
|
series.to_edge(UP)
|
||||||
|
this_video = series[3]
|
||||||
|
next_video = series[4]
|
||||||
|
brace = Brace(this_video, DOWN)
|
||||||
|
this_video.save_state()
|
||||||
|
this_video.highlight(YELLOW)
|
||||||
|
|
||||||
|
this_tex = TexMobject(
|
||||||
|
"{d(", "a^t", ") \\over dt} = ", "a^t", "\\ln(a)"
|
||||||
|
)
|
||||||
|
this_tex[1][1].highlight(YELLOW)
|
||||||
|
this_tex[3][1].highlight(YELLOW)
|
||||||
|
this_tex.next_to(brace, DOWN)
|
||||||
|
|
||||||
|
next_tex = VGroup(*map(TextMobject, [
|
||||||
|
"Chain rule", "Product rule", "$\\vdots$"
|
||||||
|
]))
|
||||||
|
next_tex.arrange_submobjects(DOWN)
|
||||||
|
next_tex.next_to(brace, DOWN)
|
||||||
|
next_tex.shift(
|
||||||
|
next_video.get_center()[0]*RIGHT\
|
||||||
|
-next_tex.get_center()[0]*RIGHT
|
||||||
|
)
|
||||||
|
|
||||||
|
self.add(series, brace, *this_tex[:3])
|
||||||
|
self.change_student_modes(
|
||||||
|
"confused", "pondering", "erm",
|
||||||
|
look_at_arg = this_tex
|
||||||
|
)
|
||||||
|
self.play(ReplacementTransform(
|
||||||
|
this_tex[1].copy(), this_tex[3]
|
||||||
|
))
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
Write(this_tex[4]),
|
||||||
|
ReplacementTransform(
|
||||||
|
this_tex[3][0].copy(),
|
||||||
|
this_tex[4][3],
|
||||||
|
path_arc = np.pi,
|
||||||
|
remover = True
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
self.play(this_tex.replace, this_video)
|
||||||
|
self.play(
|
||||||
|
brace.next_to, next_video, DOWN,
|
||||||
|
this_video.restore,
|
||||||
|
Animation(this_tex),
|
||||||
|
next_video.highlight, YELLOW,
|
||||||
|
Write(next_tex),
|
||||||
|
self.get_teacher().change_mode, "raise_right_hand"
|
||||||
|
)
|
||||||
|
self.change_student_modes(
|
||||||
|
*["pondering"]*3,
|
||||||
|
look_at_arg = next_tex
|
||||||
|
)
|
||||||
|
self.dither(3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -237,7 +237,6 @@ class GraphScene(Scene):
|
|||||||
dx = None,
|
dx = None,
|
||||||
dx_line_color = None,
|
dx_line_color = None,
|
||||||
df_line_color = None,
|
df_line_color = None,
|
||||||
slope_line_color = None,
|
|
||||||
dx_label = None,
|
dx_label = None,
|
||||||
df_label = None,
|
df_label = None,
|
||||||
include_secant_line = True,
|
include_secant_line = True,
|
||||||
|
@ -44,9 +44,9 @@ class ParametricFunction(VMobject):
|
|||||||
t_values = np.linspace(
|
t_values = np.linspace(
|
||||||
self.t_min, self.t_max, self.num_anchor_points
|
self.t_min, self.t_max, self.num_anchor_points
|
||||||
)
|
)
|
||||||
points = self.function(t_values)
|
points = np.array(map(self.function, t_values))
|
||||||
okay_indices = np.apply_along_axis(np.all, 1, np.isfinite(points))
|
okay_indices = np.apply_along_axis(np.all, 1, np.isfinite(points))
|
||||||
point = point[okay_indices]
|
points = points[okay_indices]
|
||||||
self.set_anchor_points(points, mode = "smooth")
|
self.set_anchor_points(points, mode = "smooth")
|
||||||
|
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ class VideoIcon(SVGMobject):
|
|||||||
|
|
||||||
class VideoSeries(VGroup):
|
class VideoSeries(VGroup):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"num_videos" : 10,
|
"num_videos" : 11,
|
||||||
"gradient_colors" : [BLUE_B, BLUE_D],
|
"gradient_colors" : [BLUE_B, BLUE_D],
|
||||||
}
|
}
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
@ -161,6 +161,7 @@ class VideoSeries(VGroup):
|
|||||||
videos = [VideoIcon() for x in range(self.num_videos)]
|
videos = [VideoIcon() for x in range(self.num_videos)]
|
||||||
VGroup.__init__(self, *videos, **kwargs)
|
VGroup.__init__(self, *videos, **kwargs)
|
||||||
self.arrange_submobjects()
|
self.arrange_submobjects()
|
||||||
|
self.scale_to_fit_width(2*SPACE_WIDTH-MED_LARGE_BUFF)
|
||||||
self.gradient_highlight(*self.gradient_colors)
|
self.gradient_highlight(*self.gradient_colors)
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user