mirror of
https://github.com/3b1b/manim.git
synced 2025-08-01 17:29:06 +08:00
Preliminary end to eoc8
This commit is contained in:
@ -99,10 +99,15 @@ class Car(SVGMobject):
|
|||||||
return VGroup(self[1][1], self[1][3])
|
return VGroup(self[1][1], self[1][3])
|
||||||
|
|
||||||
class MoveCar(ApplyMethod):
|
class MoveCar(ApplyMethod):
|
||||||
|
CONFIG = {
|
||||||
|
"moving_forward" : True,
|
||||||
|
}
|
||||||
def __init__(self, car, target_point, **kwargs):
|
def __init__(self, car, target_point, **kwargs):
|
||||||
ApplyMethod.__init__(self, car.move_to, target_point, **kwargs)
|
ApplyMethod.__init__(self, car.move_to, target_point, **kwargs)
|
||||||
displacement = self.target_mobject.get_right()-self.starting_mobject.get_right()
|
displacement = self.target_mobject.get_right()-self.starting_mobject.get_right()
|
||||||
distance = np.linalg.norm(displacement)
|
distance = np.linalg.norm(displacement)
|
||||||
|
if not self.moving_forward:
|
||||||
|
distance *= -1
|
||||||
tire_radius = car.get_tires()[0].get_width()/2
|
tire_radius = car.get_tires()[0].get_width()/2
|
||||||
self.total_tire_radians = -distance/tire_radius
|
self.total_tire_radians = -distance/tire_radius
|
||||||
|
|
||||||
|
249
eoc/chapter8.py
249
eoc/chapter8.py
@ -1429,6 +1429,15 @@ class LessWrongCarJourneyApproximation(CarJourneyApproximation):
|
|||||||
"n_jumps" : 20,
|
"n_jumps" : 20,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TellMeThatsNotSurprising(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
self.teacher_says(
|
||||||
|
"Tell me that's \\\\ not surprising!",
|
||||||
|
target_mode = "hooray",
|
||||||
|
run_time = 1
|
||||||
|
)
|
||||||
|
self.dither(3)
|
||||||
|
|
||||||
class HowDoesThisHelp(TeacherStudentsScene):
|
class HowDoesThisHelp(TeacherStudentsScene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
self.student_says(
|
self.student_says(
|
||||||
@ -1763,7 +1772,6 @@ class AreaIsDerivative(PlotVelocity, ReconfigurableScene):
|
|||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class DirectInterpretationOfDsDt(TeacherStudentsScene):
|
class DirectInterpretationOfDsDt(TeacherStudentsScene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
equation = TexMobject("{ds", "\\over\\,", "dT}", "(T)", "=", "v(T)")
|
equation = TexMobject("{ds", "\\over\\,", "dT}", "(T)", "=", "v(T)")
|
||||||
@ -2473,12 +2481,239 @@ class FundamentalTheorem(GraphScene):
|
|||||||
self.play(self.integral.set_fill, None, 1)
|
self.play(self.integral.set_fill, None, 1)
|
||||||
self.dither(3)
|
self.dither(3)
|
||||||
|
|
||||||
|
class LetsRecap(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
self.teacher_says(
|
||||||
|
"Let's recap",
|
||||||
|
target_mode = "hesitant",
|
||||||
|
)
|
||||||
|
self.change_student_modes(*["happy"]*3)
|
||||||
|
self.dither(3)
|
||||||
|
|
||||||
|
class NegativeArea(GraphScene):
|
||||||
|
CONFIG = {
|
||||||
|
"x_axis_label" : "Time",
|
||||||
|
"y_axis_label" : "Velocity",
|
||||||
|
"graph_origin" : 1.5*DOWN + 5*LEFT,
|
||||||
|
"y_min" : -3,
|
||||||
|
"y_max" : 7,
|
||||||
|
"small_dx" : 0.01,
|
||||||
|
"sample_input" : 5,
|
||||||
|
}
|
||||||
|
def construct(self):
|
||||||
|
self.setup_axes()
|
||||||
|
self.add_graph_and_area()
|
||||||
|
self.write_negative_area()
|
||||||
|
self.show_negative_point()
|
||||||
|
self.show_car_going_backwards()
|
||||||
|
self.write_v_dt()
|
||||||
|
self.show_rectangle()
|
||||||
|
self.write_signed_area()
|
||||||
|
|
||||||
|
def add_graph_and_area(self):
|
||||||
|
graph = self.get_graph(
|
||||||
|
lambda x : -0.02*(x+1)*(x-3)*(x-7)*(x-10),
|
||||||
|
x_min = 0,
|
||||||
|
x_max = 8,
|
||||||
|
color = VELOCITY_COLOR
|
||||||
|
)
|
||||||
|
area = self.get_riemann_rectangles(
|
||||||
|
graph,
|
||||||
|
x_min = 0,
|
||||||
|
x_max = 8,
|
||||||
|
dx = self.small_dx,
|
||||||
|
start_color = BLUE_D,
|
||||||
|
end_color = BLUE_D,
|
||||||
|
fill_opacity = 0.75,
|
||||||
|
stroke_width = 0,
|
||||||
|
)
|
||||||
|
|
||||||
|
self .play(
|
||||||
|
ShowCreation(graph),
|
||||||
|
FadeIn(
|
||||||
|
area,
|
||||||
|
run_time = 2,
|
||||||
|
submobject_mode = "lagged_start",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.graph = graph
|
||||||
|
self.area = area
|
||||||
|
|
||||||
|
def write_negative_area(self):
|
||||||
|
words = TextMobject("Negative area")
|
||||||
|
words.highlight(RED)
|
||||||
|
words.next_to(
|
||||||
|
self.coords_to_point(7, -2),
|
||||||
|
RIGHT,
|
||||||
|
)
|
||||||
|
arrow = Arrow(words, self.coords_to_point(
|
||||||
|
self.sample_input, -1,
|
||||||
|
))
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
Write(words, run_time = 2),
|
||||||
|
ShowCreation(arrow)
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
self.play(*map(FadeOut, [self.area, arrow]))
|
||||||
|
|
||||||
|
self.negative_area_words = words
|
||||||
|
|
||||||
|
def show_negative_point(self):
|
||||||
|
v_line = self.get_vertical_line_to_graph(
|
||||||
|
self.sample_input, self.graph,
|
||||||
|
color = RED
|
||||||
|
)
|
||||||
|
self.play(ShowCreation(v_line))
|
||||||
|
self.dither()
|
||||||
|
self.v_line = v_line
|
||||||
|
|
||||||
|
def show_car_going_backwards(self):
|
||||||
|
car = Car()
|
||||||
|
start_point = 3*RIGHT + 2*UP
|
||||||
|
end_point = start_point + LEFT
|
||||||
|
nudged_end_point = end_point + MED_SMALL_BUFF*LEFT
|
||||||
|
car.move_to(start_point)
|
||||||
|
arrow = Arrow(RIGHT, LEFT, color = RED)
|
||||||
|
arrow.next_to(car, UP+LEFT)
|
||||||
|
arrow.shift(MED_LARGE_BUFF*RIGHT)
|
||||||
|
|
||||||
|
self.play(FadeIn(car))
|
||||||
|
self.play(ShowCreation(arrow))
|
||||||
|
self.play(MoveCar(
|
||||||
|
car, end_point,
|
||||||
|
moving_forward = False,
|
||||||
|
run_time = 3
|
||||||
|
))
|
||||||
|
self.dither()
|
||||||
|
ghost_car = car.copy().fade()
|
||||||
|
right_nose_line = self.get_car_nose_line(car)
|
||||||
|
self.play(ShowCreation(right_nose_line))
|
||||||
|
self.add(ghost_car)
|
||||||
|
self.play(MoveCar(
|
||||||
|
car, nudged_end_point,
|
||||||
|
moving_forward = False
|
||||||
|
))
|
||||||
|
left_nose_line = self.get_car_nose_line(car)
|
||||||
|
self.play(ShowCreation(left_nose_line))
|
||||||
|
|
||||||
|
self.nose_lines = VGroup(left_nose_line, right_nose_line)
|
||||||
|
self.car = car
|
||||||
|
self.ghost_car = ghost_car
|
||||||
|
|
||||||
|
def write_v_dt(self):
|
||||||
|
brace = Brace(self.nose_lines, DOWN, buff = 0)
|
||||||
|
equation = TexMobject("ds", "=", "v(t)", "dt")
|
||||||
|
equation.next_to(brace, DOWN, SMALL_BUFF, LEFT)
|
||||||
|
equation.highlight_by_tex("ds", DISTANCE_COLOR)
|
||||||
|
equation.highlight_by_tex("dt", TIME_COLOR)
|
||||||
|
|
||||||
|
negative = TextMobject("Negative")
|
||||||
|
negative.highlight(RED)
|
||||||
|
negative.next_to(equation.get_corner(UP+RIGHT), UP, LARGE_BUFF)
|
||||||
|
ds_arrow, v_arrow = arrows = VGroup(*[
|
||||||
|
Arrow(
|
||||||
|
negative.get_bottom(),
|
||||||
|
equation.get_part_by_tex(tex).get_top(),
|
||||||
|
color = RED,
|
||||||
|
)
|
||||||
|
for tex in "ds", "v(t)"
|
||||||
|
])
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(brace),
|
||||||
|
Write(equation)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeIn(negative))
|
||||||
|
self.play(ShowCreation(v_arrow))
|
||||||
|
self.dither(2)
|
||||||
|
self.play(ReplacementTransform(
|
||||||
|
v_arrow.copy(),
|
||||||
|
ds_arrow
|
||||||
|
))
|
||||||
|
self.dither(2)
|
||||||
|
|
||||||
|
self.ds_equation = equation
|
||||||
|
self.negative_word = negative
|
||||||
|
self.negative_word_arrows = arrows
|
||||||
|
|
||||||
|
def show_rectangle(self):
|
||||||
|
rect_list = self.get_riemann_rectangles_list(
|
||||||
|
self.graph, x_min = 0, x_max = 8,
|
||||||
|
n_iterations = 6,
|
||||||
|
start_color = BLUE_D,
|
||||||
|
end_color = BLUE_D,
|
||||||
|
fill_opacity = 0.75,
|
||||||
|
)
|
||||||
|
rects = rect_list[0]
|
||||||
|
rect = rects[len(rects)*self.sample_input//8]
|
||||||
|
|
||||||
|
dt_brace = Brace(rect, UP, buff = 0)
|
||||||
|
v_brace = Brace(rect, LEFT, buff = 0)
|
||||||
|
dt_label = dt_brace.get_text("$dt$", buff = SMALL_BUFF)
|
||||||
|
dt_label.highlight(YELLOW)
|
||||||
|
v_label = v_brace.get_text("$v(t)$", buff = SMALL_BUFF)
|
||||||
|
v_label.add_background_rectangle()
|
||||||
|
|
||||||
|
self.play(FadeOut(self.v_line), FadeIn(rect))
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(dt_brace),
|
||||||
|
GrowFromCenter(v_brace),
|
||||||
|
Write(dt_label),
|
||||||
|
Write(v_label),
|
||||||
|
)
|
||||||
|
self.dither(2)
|
||||||
|
self.play(*it.chain(
|
||||||
|
[FadeIn(r) for r in rects if r is not rect],
|
||||||
|
map(FadeOut, [
|
||||||
|
dt_brace, v_brace, dt_label, v_label
|
||||||
|
])
|
||||||
|
))
|
||||||
|
self.dither()
|
||||||
|
for new_rects in rect_list[1:]:
|
||||||
|
self.transform_between_riemann_rects(rects, new_rects)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
def write_signed_area(self):
|
||||||
|
words = TextMobject("``Signed area''")
|
||||||
|
words.next_to(self.coords_to_point(self.sample_input, 0), UP)
|
||||||
|
symbols = VGroup(*[
|
||||||
|
TexMobject(sym).move_to(self.coords_to_point(*coords))
|
||||||
|
for sym, coords in [
|
||||||
|
("+", (1, 2)),
|
||||||
|
("-", (5, -1)),
|
||||||
|
("+", (7.6, 0.5)),
|
||||||
|
]
|
||||||
|
])
|
||||||
|
self.play(Write(words))
|
||||||
|
self.play(Write(symbols))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
####
|
||||||
|
|
||||||
|
def get_car_nose_line(self, car):
|
||||||
|
line = DashedLine(car.get_top(), car.get_bottom())
|
||||||
|
line.move_to(car.get_right())
|
||||||
|
return line
|
||||||
|
|
||||||
|
class NextVideo(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
series = VideoSeries()
|
||||||
|
series.to_edge(UP)
|
||||||
|
next_video = series[8]
|
||||||
|
integral = TexMobject("\\int")
|
||||||
|
integral.next_to(next_video, DOWN, LARGE_BUFF)
|
||||||
|
|
||||||
|
self.play(FadeIn(series, submobject_mode = "lagged_start"))
|
||||||
|
self.play(
|
||||||
|
next_video.highlight, YELLOW,
|
||||||
|
next_video.shift, next_video.get_height()*DOWN/2,
|
||||||
|
self.teacher.change_mode, "raise_right_hand"
|
||||||
|
)
|
||||||
|
self.play(Write(integral))
|
||||||
|
self.dither(5)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -196,11 +196,15 @@ class GraphScene(Scene):
|
|||||||
stroke_width = 1,
|
stroke_width = 1,
|
||||||
fill_opacity = 1,
|
fill_opacity = 1,
|
||||||
start_color = BLUE,
|
start_color = BLUE,
|
||||||
end_color = GREEN):
|
end_color = GREEN,
|
||||||
|
show_signed_area = True,
|
||||||
|
):
|
||||||
x_min = x_min if x_min is not None else self.x_min
|
x_min = x_min if x_min is not None else self.x_min
|
||||||
x_max = x_max if x_max is not None else self.x_max
|
x_max = x_max if x_max is not None else self.x_max
|
||||||
rectangles = VGroup()
|
rectangles = VGroup()
|
||||||
for x in np.arange(x_min, x_max, dx):
|
x_range = np.arange(x_min, x_max, dx)
|
||||||
|
colors = color_gradient([start_color, end_color], len(x_range))
|
||||||
|
for x, color in zip(x_range, colors):
|
||||||
if input_sample_type == "left":
|
if input_sample_type == "left":
|
||||||
sample_input = x
|
sample_input = x
|
||||||
elif input_sample_type == "right":
|
elif input_sample_type == "right":
|
||||||
@ -216,10 +220,13 @@ class GraphScene(Scene):
|
|||||||
|
|
||||||
rect = Rectangle()
|
rect = Rectangle()
|
||||||
rect.replace(points, stretch = True)
|
rect.replace(points, stretch = True)
|
||||||
rect.set_fill(opacity = fill_opacity)
|
if graph_point[1] < self.graph_origin[1] and show_signed_area:
|
||||||
|
fill_color = invert_color(color)
|
||||||
|
else:
|
||||||
|
fill_color = color
|
||||||
|
rect.set_fill(fill_color, opacity = fill_opacity)
|
||||||
|
rect.set_stroke(BLACK, width = stroke_width)
|
||||||
rectangles.add(rect)
|
rectangles.add(rect)
|
||||||
rectangles.gradient_highlight(start_color, end_color)
|
|
||||||
rectangles.set_stroke(BLACK, width = stroke_width)
|
|
||||||
return rectangles
|
return rectangles
|
||||||
|
|
||||||
def get_riemann_rectangles_list(
|
def get_riemann_rectangles_list(
|
||||||
|
@ -118,6 +118,9 @@ def rgb_to_color(rgb):
|
|||||||
except:
|
except:
|
||||||
return Color(WHITE)
|
return Color(WHITE)
|
||||||
|
|
||||||
|
def invert_color(color):
|
||||||
|
return rgb_to_color(1.0 - color_to_rgb(color))
|
||||||
|
|
||||||
def color_to_int_rgb(color):
|
def color_to_int_rgb(color):
|
||||||
return (255*color_to_rgb(color)).astype('uint8')
|
return (255*color_to_rgb(color)).astype('uint8')
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user