Up to graphed integral in eoc chapter1

This commit is contained in:
Grant Sanderson
2016-11-11 14:42:40 -08:00
parent 781216f5cf
commit f7f2384eca
2 changed files with 309 additions and 3 deletions

View File

@ -24,6 +24,8 @@ 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 eoc.graph_scene import GraphScene
class CircleScene(PiCreatureScene): class CircleScene(PiCreatureScene):
CONFIG = { CONFIG = {
"radius" : 1.5, "radius" : 1.5,
@ -1839,9 +1841,177 @@ class IntroduceConcentricRings(CircleScene):
) )
self.dither(4) self.dither(4)
class AskAboutGeneralCircles(TeacherStudentsScene):
def construct(self):
self.student_says("""
What about integrals
beyond this circle
example?
""")
self.change_student_modes("confused")
self.random_blink(2)
self.teacher_says(
"All in due time",
)
self.change_student_modes(*["happy"]*3)
self.random_blink(2)
class GraphIntegral(GraphScene):
CONFIG = {
"x_min" : -0.25,
"x_max" : 4,
"x_tick_frequency" : 0.25,
"x_leftmost_tick" : -0.25,
"x_labeled_nums" : range(1, 5),
"x_axis_label" : "r",
"y_min" : -2,
"y_max" : 25,
"y_tick_frequency" : 2.5,
"y_bottom_tick" : 0,
"y_labeled_nums" : range(5, 30, 5),
"y_axis_label" : "",
"dr" : 0.125,
"R" : 3.5,
}
def construct(self):
integral = TexMobject("\\int_0^R 2\\pi r \\, dr")
integral.to_edge(UP).shift(LEFT)
self.play(Write(integral))
self.dither()
self.setup_axes()
self.add_rectangles()
self.thinner_rectangles()
self.ask_about_area()
def add_rectangles(self):
tick_height = 0.2
special_tick_index = 12
ticks = VGroup(*[
Line(UP, DOWN).move_to(self.coords_to_point(x, 0))
for x in np.arange(0, self.R+self.dr, self.dr)
])
ticks.stretch_to_fit_height(tick_height)
ticks.highlight(YELLOW)
R_label = TexMobject("R")
R_label.next_to(self.coords_to_point(self.R, 0), DOWN)
values_words = TextMobject("Values of $r$")
values_words.shift(UP)
arrows = VGroup(*[
Arrow(
values_words.get_bottom(),
tick.get_center(),
tip_length = 0.15
)
for tick in ticks
])
dr_brace = Brace(
VGroup(*ticks[special_tick_index:special_tick_index+2]),
buff = SMALL_BUFF
)
dr_text = dr_brace.get_text("$dr$", buff = SMALL_BUFF)
# dr_text.highlight(YELLOW)
rectangles = self.get_rectangles(self.dr)
special_rect = rectangles[special_tick_index]
left_brace = Brace(special_rect, LEFT)
height_label = left_brace.get_text("$2\\pi r$")
self.play(
ShowCreation(ticks, submobject_mode = "lagged_start"),
Write(R_label)
)
self.play(
Write(values_words),
ShowCreation(arrows)
)
self.dither()
self.play(
GrowFromCenter(dr_brace),
Write(dr_text)
)
self.dither()
rectangles.save_state()
rectangles.stretch_to_fit_height(0)
rectangles.move_to(self.graph_origin, DOWN+LEFT)
self.play(*map(FadeOut, [arrows, values_words]))
self.play(
rectangles.restore,
Animation(ticks),
run_time = 2
)
self.dither()
self.play(*[
ApplyMethod(rect.fade, 0.7)
for rect in rectangles
if rect is not special_rect
] + [Animation(ticks)])
self.play(
GrowFromCenter(left_brace),
Write(height_label)
)
self.dither()
graph = self.graph_function(
lambda r : 2*np.pi*r,
animate = False
)
graph_label = self.label_graph(
self.graph, "f(r) = 2\\pi r",
proportion = 0.5,
direction = LEFT,
animate = False
)
self.play(
rectangles.restore,
Animation(ticks),
FadeOut(left_brace),
Transform(height_label, graph_label),
ShowCreation(graph)
)
self.dither(3)
self.play(*map(FadeOut, [ticks, dr_brace, dr_text]))
self.rectangles = rectangles
def thinner_rectangles(self):
for x in range(2, 8):
new_rects = self.get_rectangles(
dr = self.dr/x, stroke_width = 1./x
)
self.play(Transform(self.rectangles, new_rects))
self.dither()
def ask_about_area(self):
question = TextMobject("What's this \\\\ area")
question.to_edge(RIGHT).shift(2*UP)
arrow = Arrow(
question.get_bottom(),
self.rectangles,
buff = SMALL_BUFF
)
self.play(
Write(question),
ShowCreation(arrow)
)
self.dither()
def get_rectangles(self, dr, stroke_width = 1):
rectangles = VGroup()
for r in np.arange(0, self.R, dr):
points = VGroup(
VectorizedPoint(self.coords_to_point(r, 0)),
VectorizedPoint(self.coords_to_point(r+dr, 2*np.pi*r)),
)
rect = Rectangle()
rect.replace(points, stretch = True)
rect.set_fill(opacity = 1)
rectangles.add(rect)
rectangles.gradient_highlight(BLUE, GREEN)
rectangles.set_stroke(BLACK, width = stroke_width)
return rectangles

136
eoc/graph_scene.py Normal file
View File

@ -0,0 +1,136 @@
from helpers import *
from scene import Scene
# from topics.geometry import
from mobject.tex_mobject import TexMobject
from mobject.vectorized_mobject import VGroup
from animation.simple_animations import Write, ShowCreation
from topics.number_line import NumberLine
from topics.functions import ParametricFunction
class GraphScene(Scene):
CONFIG = {
"x_min" : -1,
"x_max" : 10,
"x_axis_width" : 9,
"x_tick_frequency" : 1,
"x_leftmost_tick" : -1,
"x_labeled_nums" : range(1, 10),
"x_axis_label" : "x",
"y_min" : -1,
"y_max" : 10,
"y_axis_height" : 6,
"y_tick_frequency" : 1,
"y_bottom_tick" : -1,
"y_labeled_nums" : range(1, 10),
"y_axis_label" : "y",
"axes_color" : GREY,
"graph_origin" : 2.5*DOWN + 4*LEFT,
"y_axis_numbers_nudge" : 0.4*UP+0.5*LEFT,
}
def setup_axes(self, animate = True):
x_num_range = float(self.x_max - self.x_min)
x_axis = NumberLine(
x_min = self.x_min,
x_max = self.x_max,
space_unit_to_num = self.x_axis_width/x_num_range,
tick_frequency = self.x_tick_frequency,
leftmost_tick = self.x_leftmost_tick,
numbers_with_elongated_ticks = self.x_labeled_nums,
color = self.axes_color
)
x_axis.shift(self.graph_origin - x_axis.number_to_point(0))
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)
y_num_range = float(self.y_max - self.y_min)
y_axis = NumberLine(
x_min = self.y_min,
x_max = self.y_max,
space_unit_to_num = self.y_axis_height/y_num_range,
tick_frequency = self.y_tick_frequency,
leftmost_tick = self.y_bottom_tick,
numbers_with_elongated_ticks = self.y_labeled_nums,
color = self.axes_color
)
y_axis.shift(self.graph_origin-y_axis.number_to_point(0))
y_axis.rotate(np.pi/2, about_point = y_axis.number_to_point(0))
y_axis.add_numbers(*self.y_labeled_nums)
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)
if animate:
self.play(Write(VGroup(x_axis, y_axis)))
else:
selfe.add(x_axis, y_axis_label)
self.x_axis, self.y_axis = x_axis, y_axis
def coords_to_point(self, x, y):
assert(hasattr(self, "x_axis") and hasattr(self, "y_axis"))
result = self.x_axis.number_to_point(x)[0]*RIGHT
result += self.y_axis.number_to_point(y)[1]*UP
return result
def graph_function(self, func,
color = BLUE,
animate = True,
is_main_graph = True,
):
def parameterized_graph(alpha):
x = interpolate(self.x_min, self.x_max, alpha)
return self.coords_to_point(x, func(x))
graph = ParametricFunction(parameterized_graph, color = color)
if is_main_graph:
self.graph = graph
if animate:
self.play(ShowCreation(graph))
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)
return angle_of_vector(vect)
def label_graph(self, graph, label = "f(x)",
proportion = 0.7,
direction = LEFT,
buff = 2*MED_BUFF,
animate = True
):
label = TexMobject(label)
label.highlight(graph.get_color())
label.next_to(
graph.point_from_proportion(proportion),
direction,
buff = buff
)
if animate:
self.play(Write(label))
self.add(label)
return label