Up to patron-posted draft of eoc/chapter1.py

This commit is contained in:
Grant Sanderson
2016-11-14 15:06:44 -08:00
parent 4d60a245f6
commit c7f7f3c596
2 changed files with 444 additions and 64 deletions

View File

@ -202,13 +202,42 @@ class CircleScene(PiCreatureScene):
######################
class PatronsOnly(Scene):
def construct(self):
morty = Mortimer()
morty.shift(2*DOWN)
title = TextMobject("""
This is a draft
for patrons only
""")
title.highlight(RED)
title.scale(2)
title.to_edge(UP)
self.add(morty)
self.play(
Write(title),
morty.change_mode, "wave_1"
)
self.play(Blink(morty))
self.play(
morty.change_mode, "pondering",
morty.look_at, title
)
self.play(Blink(morty))
self.dither()
class OpeningQuote(Scene):
CONFIG = {
"quote" : """
The art of doing mathematics is finding
that special case that contains all the
germs of generality.
""",
"quote" : [
"""The art of doing mathematics is finding
that """, "special case",
"""that contains all the
germs of generality."""
],
"highlighted_quote_terms" : {
"special case" : BLUE
},
"author" : "David Hilbert"
}
def construct(self):
@ -218,17 +247,25 @@ class OpeningQuote(Scene):
self.play(FadeIn(
quote,
submobject_mode = "lagged_start",
run_time = 2
run_time = 4
))
self.dither(2)
self.play(Write(author, run_time = 4))
self.play(Write(author, run_time = 3))
self.dither()
def get_quote(self):
if isinstance(self.quote, str):
quote = TextMobject(
"``%s''"%self.quote.strip(),
alignment = "",
)
else:
words = list(self.quote)
words[0] = "``%s"%words[0]
words[-1] += "''"
quote = TextMobject(*words, alignment = "")
for term, color in self.highlighted_quote_terms.items():
quote.highlight_by_tex(term, color)
quote.to_edge(UP)
return quote
@ -1170,11 +1207,11 @@ class BuildToDADR(CircleScene):
self.play(self.pi_creature.change_mode, "guilty")
self.dither()
new_bubble = self.pi_creature.get_bubble("speech", height = 6)
new_bubble = self.pi_creature.get_bubble("speech")
new_bubble.set_fill(BLACK, opacity = 0.8)
new_bubble.write("But it gets \\\\ less wrong!")
new_bubble.resize_to_content()
new_bubble.pin_to(self.pi_creature)
new_bubble.write("But it gets \\\\ less wrong!")
self.play(
FadeOut(bubble),
@ -1193,8 +1230,8 @@ class NameDerivative(IntroduceTinyChangeInArea):
self.change_nudge_label()
self.name_derivative_for_cricle()
self.interpret_geometrically()
self.replace_words()
self.show_limiting_process()
self.reference_approximation()
self.emphasize_equality()
def change_nudge_label(self):
@ -1255,6 +1292,7 @@ class NameDerivative(IntroduceTinyChangeInArea):
self.dither()
self.dArea_fom = dArea_fom
self.words = words
self.two_pi_R = two_pi_R
def interpret_geometrically(self):
target_formula = TexMobject(
@ -1298,21 +1336,9 @@ class NameDerivative(IntroduceTinyChangeInArea):
self.play(Transform(circum_circle.copy(), circum_form))
self.change_mode("happy")
def replace_words(self):
new_words = TextMobject(
"Ask what this\\\\",
"ratio approaches."
)
new_words.move_to(self.words)
self.play(
Transform(self.words, new_words),
self.pi_creature.change_mode, "pondering"
)
self.dither()
def show_limiting_process(self):
big_dR = 0.3
small_dR = 0.05
small_dR = 0.01
big_ring = self.get_ring(self.radius, big_dR)
small_ring = self.get_ring(self.radius, small_dR)
big_nudge_line = self.nudge_line.copy().scale_to_fit_width(big_dR)
@ -1322,42 +1348,73 @@ class NameDerivative(IntroduceTinyChangeInArea):
new_nudge_arrow = Arrow(self.nudge_label, big_nudge_line)
small_nudge_arrow = Arrow(self.nudge_label, small_nudge_line)
ring_group = VGroup(self.outer_ring, self.nudge_line, self.nudge_arrow)
ring_group.save_state()
big_group = VGroup(big_ring, big_nudge_line, new_nudge_arrow)
small_group = VGroup(small_ring, small_nudge_line, small_nudge_arrow)
fracs = VGroup()
sample_dRs = [0.3, 0.1, 0.01]
for dR in sample_dRs:
dA = 2*np.pi*dR + np.pi*(dR**2)
frac = TexMobject("\\frac{%.3f}{%.2f}"%(dA, dR))
VGroup(*frac[:5]).highlight(self.outer_ring.get_color())
VGroup(*frac[6:]).highlight(self.dR_color)
fracs.add(frac)
fracs.add(TexMobject("\\cdots \\rightarrow"))
fracs.add(TexMobject("???"))
fracs[-1].gradient_highlight(self.dR_color, self.outer_ring.get_color())
fracs.arrange_submobjects(RIGHT, buff = 2*MED_BUFF)
fracs.to_corner(DOWN+LEFT)
arrows = VGroup()
for frac in fracs[:len(sample_dRs)] + [fracs[-1]]:
arrow = Arrow(self.words.get_bottom(), frac.get_top())
arrow.highlight(WHITE)
if frac is fracs[-1]:
check = TexMobject("\\checkmark")
check.highlight(GREEN)
check.next_to(arrow.get_center(), UP+RIGHT, SMALL_BUFF)
arrow.add(check)
else:
cross = TexMobject("\\times")
cross.highlight(RED)
cross.move_to(arrow.get_center())
cross.set_stroke(RED, width = 5)
arrow.add(cross)
arrows.add(arrow)
self.play(
Transform(self.outer_ring, big_ring),
Transform(self.nudge_line, big_nudge_line),
Transform(self.nudge_arrow, new_nudge_arrow),
self.pi_creature.change_mode, "pondering"
Transform(ring_group, big_group),
self.pi_creature.change_mode, "sassy"
)
big_trap = self.outer_ring.copy()
big_trap.dR = big_dR
small_trap = self.get_unwrapped(small_ring.copy())
for trap in big_trap, small_trap:
trap.set_fill(opacity = 0.5)
self.unwrap_ring(big_trap)
small_trap.move_to(big_trap)
big_rect, small_rect = [
Rectangle(
height = trap.get_height(),
width = 2*np.pi*self.radius,
stroke_width = 0,
fill_color = BLUE,
fill_opacity = 0.5
).move_to(trap)
for trap in big_trap, small_trap
]
self.play(FadeIn(big_rect))
for n, frac in enumerate(fracs):
anims = [FadeIn(frac)]
num_fracs = len(sample_dRs)
if n < num_fracs:
anims.append(ShowCreation(arrows[n]))
anims.append(Transform(
ring_group, small_group,
rate_func = lambda t : t*(1./(num_fracs-n)),
run_time = 2
))
elif n > num_fracs:
anims.append(ShowCreation(arrows[-1]))
self.play(*anims)
self.dither(2)
self.play(
Transform(self.outer_ring, small_ring),
Transform(self.nudge_line, small_nudge_line),
Transform(self.nudge_arrow, small_nudge_arrow),
Transform(big_trap, small_trap),
Transform(big_rect, small_rect),
run_time = 6,
rate_func = None
FadeOut(arrows),
ring_group.restore,
self.pi_creature.change_mode, "happy",
)
self.change_mode("happy")
self.dither()
self.last_mover = VGroup(big_trap, big_rect)
def reference_approximation(self):
ring_copy = self.outer_ring.copy()
self.unwrap_ring(ring_copy)
self.dither()
self.last_mover = ring_copy
def emphasize_equality(self):
equals = self.dArea_fom[-2]
@ -1366,9 +1423,15 @@ class NameDerivative(IntroduceTinyChangeInArea):
self.remove(self.last_mover)
self.play(
equals.scale_in_place, 1.5,
equals.highlight, GREEN
equals.highlight, GREEN,
rate_func = there_and_back,
run_time = 2
)
self.play(
self.two_pi_R.set_stroke, YELLOW, 3,
rate_func = there_and_back,
run_time = 2
)
self.play(equals.scale_in_place, 1./1.5)
self.dither()
new_words = TextMobject(
@ -1392,6 +1455,7 @@ class DerivativeAsTangentLine(ZoomedScene):
self.setup_axes()
self.show_zoomed_in_steps()
self.show_tangent_lines()
self.state_commonality()
def setup_axes(self):
x_axis = NumberLine(
@ -1408,6 +1472,7 @@ class DerivativeAsTangentLine(ZoomedScene):
x_axis.add_numbers(1, 2, 3, 4)
x_label = TexMobject("R")
x_label.next_to(x_axis, RIGHT+UP, buff = SMALL_BUFF)
self.x_axis_label = x_label
y_axis = NumberLine(
x_min = -2,
@ -1559,6 +1624,7 @@ class DerivativeAsTangentLine(ZoomedScene):
self.play(ShowCreation(line))
self.dither()
self.note_R_value_of_point()
alphas = np.arange(0, 1, 0.01)
graph_points = map(self.graph.point_from_proportion, alphas)
@ -1588,6 +1654,65 @@ class DerivativeAsTangentLine(ZoomedScene):
shift_everything_to_alpha(0.8, 4)
self.dither()
def note_R_value_of_point(self):
R = self.R_to_zoom_in_on
point = self.graph_point(R)
R_axis_point = point[0]*RIGHT + 2.5*DOWN
dashed_line = DashedLine(point, R_axis_point, color = RED)
dot = Dot(R_axis_point, color = RED)
arrow = Arrow(
self.x_axis_label.get_left(),
dot,
buff = SMALL_BUFF
)
self.play(ShowCreation(dashed_line))
self.play(ShowCreation(dot))
self.play(ShowCreation(arrow))
self.play(dot.scale_in_place, 2, rate_func = there_and_back)
self.dither()
self.play(*map(FadeOut, [dashed_line, dot, arrow]))
def state_commonality(self):
morty = Mortimer()
morty.scale(0.7)
morty.to_edge(DOWN).shift(2*RIGHT)
bubble = morty.get_bubble("speech", height = 2)
bubble.set_fill(BLACK, opacity = 0.8)
bubble.shift(0.5*DOWN)
bubble.write("This is the standard view")
self.play(FadeIn(morty))
self.play(
ShowCreation(bubble),
Write(bubble.content),
morty.change_mode, "surprised"
)
self.play(Blink(morty))
self.dither()
new_words = TextMobject("Which is...fine...")
new_words.move_to(bubble.content, RIGHT)
self.play(
bubble.stretch_to_fit_width, 5,
bubble.shift, RIGHT,
Transform(bubble.content, new_words),
morty.change_mode, "hesitant"
)
self.play(Blink(morty))
self.dither()
class SimpleConfusedPi(Scene):
def construct(self):
randy = Randolph()
confused = Randolph(mode = "confused")
for pi in randy, confused:
pi.flip()
pi.look(UP+LEFT)
pi.scale(2)
pi.rotate(np.pi/2)
self.play(Transform(randy, confused))
self.dither()
class TangentLinesAreNotEverything(TeacherStudentsScene):
def construct(self):
self.teacher_says("""
@ -1687,6 +1812,7 @@ class IntroduceConcentricRings(CircleScene):
area_sum.to_edge(RIGHT)
area_sum.to_edge(UP, buff = MED_BUFF)
dots_equals_area[-1].shift(0.1*UP)
self.area_sum_rhs = dots_equals_area[-1]
# start_rings.set_fill(opacity = 0.3)
self.play(
@ -1797,6 +1923,31 @@ class IntroduceConcentricRings(CircleScene):
self.pi_creature.change_mode, "pondering"
)
self.dither(2)
last = VMobject()
last.save_state()
for ring in self.rings:
ring.save_state()
target = ring.copy()
target.set_fill(opacity = 1)
self.play(
last.restore,
Transform(ring, target),
Animation(self.foreground_group),
run_time = 0.5
)
last = ring
self.play(last.restore)
self.dither()
ghost = self.rings.copy()
for mob in self.area_sum_rhs, self.two_pi_r:
ghost.set_fill(opacity = 0.1)
self.play(Transform(ghost, mob))
self.dither()
self.remove(ghost)
self.dither()
self.play(FadeOut(formula_q))
self.play(Write(int_sym))
self.dither()
@ -1824,6 +1975,13 @@ class IntroduceConcentricRings(CircleScene):
self.play(Write(equals_pi_R_squared))
self.dither()
self.equals = equals_pi_R_squared[0]
self.integral_terms = VGroup(
self.integral_expression[1],
self.integral_expression[2],
self.int_lower_bound,
self.int_upper_bound,
VGroup(*equals_pi_R_squared[1:])
)
def grow_and_shrink_r_line(self, zero_target, R_target):
self.radial_line.get_center = self.circle.get_center
@ -1870,6 +2028,7 @@ class IntroduceConcentricRings(CircleScene):
self.r_label.restore,
FadeOut(equals_0)
)
self.int_lower_bound, self.int_upper_bound = zero_target, R_target
def ask_about_approx(self):
approx = TexMobject("\\approx").replace(self.equals)
@ -1912,7 +2071,12 @@ class IntroduceConcentricRings(CircleScene):
GrowFromCenter(int_brace),
Write(integral_word)
)
self.dither(4)
self.dither()
for term in self.integral_terms:
term.save_state()
self.play(term.highlight, YELLOW)
self.play(term.restore)
self.dither(3)
class AskAboutGeneralCircles(TeacherStudentsScene):
def construct(self):
@ -1947,16 +2111,35 @@ class GraphIntegral(GraphScene):
"R" : 3.5,
}
def construct(self):
self.func = lambda r : 2*np.pi*r
integral = TexMobject("\\int_0^R 2\\pi r \\, dr")
integral.to_edge(UP).shift(LEFT)
self.little_r = integral[5]
self.play(Write(integral))
self.dither()
self.setup_axes()
self.show_horizontal_axis()
self.add_rectangles()
self.thinner_rectangles()
self.ask_about_area()
def show_horizontal_axis(self):
arrows = [
Arrow(self.little_r, self.coords_to_point(*coords))
for coords in (0, 0), (self.x_max, 0)
]
moving_arrow = arrows[0].copy()
self.play(
ShowCreation(moving_arrow),
self.little_r.highlight, YELLOW
)
for arrow in reversed(arrows):
self.play(Transform(moving_arrow, arrow, run_time = 4))
self.play(
FadeOut(moving_arrow),
self.little_r.highlight, WHITE
)
def add_rectangles(self):
tick_height = 0.2
@ -2076,6 +2259,24 @@ class GraphIntegral(GraphScene):
0, self.R, dr, stroke_width = stroke_width
)
class MoreOnThisLater(TeacherStudentsScene):
def construct(self):
self.teacher_says("""
More details on
integrals later
""")
self.change_student_modes(
"raise_right_hand",
"raise_left_hand",
"raise_left_hand",
)
self.random_blink(2)
self.teacher_says("""
This is just
a preview
""")
self.random_blink(2)
class FundamentalTheorem(CircleScene):
CONFIG = {
"circle_corner" : ORIGIN,
@ -2293,9 +2494,184 @@ class NameTheFundamentalTheorem(TeacherStudentsScene):
self.change_student_modes(*["happy"]*3)
self.dither(2)
class CalculusInANutshell(CircleScene):
CONFIG = {
"circle_corner" : ORIGIN,
"radius" : 3,
}
def construct(self):
self.clear()
self.morph_word()
self.show_remainder_of_series()
def morph_word(self):
calculus = TextMobject("Calculus")
calculus.scale(1.5)
calculus.to_edge(UP)
dR = self.radius/float(len(calculus.split()))
rings = VGroup(*[
self.get_ring(rad, 0.95*dR)
for rad in np.arange(0, self.radius, dR)
])
for ring in rings:
ring.add(ring.copy().rotate(np.pi))
for mob in calculus, rings:
mob.gradient_highlight(BLUE, GREEN)
rings.set_stroke(width = 0)
self.play(Write(calculus))
self.dither()
self.play(Transform(
calculus, rings,
submobject_mode = "lagged_start",
run_time = 5
))
self.dither()
def show_remainder_of_series(self):
series = VideoSeries()
first = series[0]
first.set_fill(YELLOW)
first.save_state()
first.center()
first.scale_to_fit_height(SPACE_HEIGHT*2)
first.set_fill(opacity = 0)
everything = VGroup(*self.get_mobjects())
everything.generate_target()
everything.target.scale(series[1].get_height()/first.get_height())
everything.target.shift(first.saved_state.get_center())
everything.target.set_fill(opacity = 0.1)
second = series[1]
brace = Brace(second)
derivatives = brace.get_text("Derivatives")
self.play(
MoveToTarget(everything),
first.restore,
run_time = 2
)
self.play(FadeIn(
VGroup(*series[1:]),
submobject_mode = "lagged_start",
run_time = 2,
))
self.dither()
self.play(
GrowFromCenter(brace),
Write(derivatives)
)
self.dither()
class PatreonThanks(Scene):
CONFIG = {
"specific_patrons" : [
"Ali Yahya",
"Cryptic Swarm",
"Juan Batiz-Benet",
"Yu Jun",
"Othman Alikhan",
"Joseph John Cox",
"Luc Ritchie",
"Einar Johansen",
"Rish Kundalia",
"Achille Brighton",
"Kirk Werklund",
"Ripta Pasay",
"Felipe Diniz",
]
}
def construct(self):
morty = Mortimer()
morty.next_to(ORIGIN, DOWN)
n_patrons = len(self.specific_patrons)
special_thanks = TextMobject("Special thanks to:")
special_thanks.highlight(YELLOW)
special_thanks.shift(2*UP)
left_patrons = VGroup(*map(TextMobject,
self.specific_patrons[:n_patrons/2]
))
right_patrons = VGroup(*map(TextMobject,
self.specific_patrons[n_patrons/2:]
))
for patrons, vect in (left_patrons, LEFT), (right_patrons, RIGHT):
patrons.arrange_submobjects(DOWN, aligned_edge = LEFT)
patrons.next_to(special_thanks, DOWN)
patrons.to_edge(vect, buff = LARGE_BUFF)
self.play(morty.change_mode, "gracious")
self.play(Write(special_thanks, run_time = 1))
self.play(
Write(left_patrons),
morty.look_at, left_patrons
)
self.play(
Write(right_patrons),
morty.look_at, right_patrons
)
self.play(Blink(morty))
for patrons in left_patrons, right_patrons:
for index in 0, -1:
self.play(morty.look_at, patrons[index])
self.dither()
class Thumbnail(CircleScene):
CONFIG = {
"radius" : 2,
"circle_corner" : ORIGIN
}
def construct(self):
self.clear()
title = TextMobject("Essence of \\\\ calculus")
title.scale(2)
title.to_edge(UP)
area_circle = Circle(
fill_color = BLUE,
fill_opacity = 0.5,
stroke_width = 0,
)
circum_circle = Circle(
color = YELLOW
)
deriv_eq = TexMobject("\\frac{d \\quad}{dR} = ")
int_eq = TexMobject("\\int_0^R \\quad = ")
target_height = deriv_eq[0].get_height()*2
area_circle.scale_to_fit_height(target_height)
circum_circle.scale_to_fit_height(target_height)
area_circle.next_to(deriv_eq[0], buff = SMALL_BUFF)
circum_circle.next_to(deriv_eq)
deriv_eq.add(area_circle.copy(), circum_circle.copy())
area_circle.next_to(int_eq)
circum_circle.next_to(int_eq[-1], LEFT)
int_eq.add(area_circle, circum_circle)
for mob in deriv_eq, int_eq:
mob.scale(1.5)
arrow = TexMobject("\\Leftrightarrow").scale(2)
arrow.shift(DOWN)
deriv_eq.next_to(arrow, LEFT)
int_eq.next_to(arrow, RIGHT)
self.add(title, arrow, deriv_eq, int_eq)
# dR = 0.25
# rings = VGroup(*[
# self.get_ring(rad, 0.9*dR)
# for rad in np.arange(0, self.radius, dR)
# ])
# for ring in rings:
# ring.add(ring.copy().rotate(np.pi))
# rings.gradient_highlight(BLUE, GREEN_E)
# rings.next_to(title, DOWN)
# self.add(title, rings)

View File

@ -45,6 +45,8 @@ class GraphScene(Scene):
x_axis.add_numbers(*self.x_labeled_nums)
x_label = TexMobject(self.x_axis_label)
x_label.next_to(x_axis, RIGHT+UP, buff = SMALL_BUFF)
x_axis.add(x_label)
self.x_axis_label_mob = x_label
y_num_range = float(self.y_max - self.y_min)
y_axis = NumberLine(
@ -63,6 +65,8 @@ class GraphScene(Scene):
y_axis.numbers.shift(self.y_axis_numbers_nudge)
y_label = TexMobject(self.y_axis_label)
y_label.next_to(y_axis.get_top(), RIGHT, buff = 2*MED_BUFF)
y_axis.add(y_label)
self.y_axis_label_mob = y_label
if animate:
self.play(Write(VGroup(x_axis, y_axis)))