mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Start of chapter 10
This commit is contained in:
parent
c2301e282c
commit
0df8b73a87
4 changed files with 247 additions and 49 deletions
|
@ -65,9 +65,9 @@ class Write(ShowCreation):
|
||||||
mobject = TextMobject(mob_or_text)
|
mobject = TextMobject(mob_or_text)
|
||||||
else:
|
else:
|
||||||
mobject = mob_or_text
|
mobject = mob_or_text
|
||||||
if not hasattr(self, "run_time"):
|
if "run_time" not in kwargs:
|
||||||
self.establish_run_time(mobject)
|
self.establish_run_time(mobject)
|
||||||
if not hasattr(self, "lag_factor"):
|
if "lag_factor" not in kwargs:
|
||||||
self.lag_factor = self.run_time - 1
|
self.lag_factor = self.run_time - 1
|
||||||
ShowCreation.__init__(self, mobject, **kwargs)
|
ShowCreation.__init__(self, mobject, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -41,12 +41,247 @@ class OpeningQuote(Scene):
|
||||||
author.highlight(YELLOW)
|
author.highlight(YELLOW)
|
||||||
author.next_to(words, DOWN, buff = 0.5)
|
author.next_to(words, DOWN, buff = 0.5)
|
||||||
|
|
||||||
self.play(Write(words, run_time = 8))
|
self.play(Write(words, run_time = 10))
|
||||||
self.dither(2)
|
self.dither()
|
||||||
self.play(Write(author, run_time = 3))
|
self.play(FadeIn(author))
|
||||||
self.dither(2)
|
self.dither(3)
|
||||||
|
|
||||||
class NewSceneName(Scene):
|
class StudentsFindThisConfusing(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
title = TextMobject("Eigenvectors and Eigenvalues")
|
||||||
|
title.to_edge(UP)
|
||||||
|
students = self.get_students()
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
Write(title),
|
||||||
|
*[
|
||||||
|
ApplyMethod(pi.look_at, title)
|
||||||
|
for pi in self.get_everyone()
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
self.get_teacher().look_at, students[-1].eyes,
|
||||||
|
students[0].change_mode, "confused",
|
||||||
|
students[1].change_mode, "tired",
|
||||||
|
students[2].change_mode, "sassy",
|
||||||
|
)
|
||||||
|
self.random_blink()
|
||||||
|
self.student_says(
|
||||||
|
"Why are we doing this?",
|
||||||
|
student_index = 0,
|
||||||
|
run_time = 2,
|
||||||
|
)
|
||||||
|
question1 = students[0].bubble.content.copy()
|
||||||
|
self.student_says(
|
||||||
|
"What does this actually mean?",
|
||||||
|
student_index = 2,
|
||||||
|
added_anims = [
|
||||||
|
question1.scale_in_place, 0.8,
|
||||||
|
question1.to_edge, LEFT,
|
||||||
|
question1.shift, DOWN,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
question2 = students[2].bubble.content.copy()
|
||||||
|
question2.target = question2.copy()
|
||||||
|
question2.target.next_to(
|
||||||
|
question1, DOWN,
|
||||||
|
aligned_edge = LEFT,
|
||||||
|
buff = MED_BUFF
|
||||||
|
)
|
||||||
|
equation = TexMobject(
|
||||||
|
"\\det\\left( %s \\right)=0"%matrix_to_tex_string([
|
||||||
|
["a-\\lambda", "b"],
|
||||||
|
["c", "d-\\lambda"],
|
||||||
|
])
|
||||||
|
)
|
||||||
|
equation.highlight(YELLOW)
|
||||||
|
self.teacher_says(
|
||||||
|
equation,
|
||||||
|
added_anims = [MoveToTarget(question2)]
|
||||||
|
)
|
||||||
|
self.change_student_modes(*["confused"]*3)
|
||||||
|
self.random_blink(3)
|
||||||
|
|
||||||
|
class ShowComments(Scene):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class EigenThingsArentAllThatBad(TeacherStudentsScene):
|
||||||
|
def construct(self):
|
||||||
|
self.teacher_says(
|
||||||
|
"Eigen-things aren't \\\\ actually so bad",
|
||||||
|
pi_creature_target_mode = "hooray"
|
||||||
|
)
|
||||||
|
self.random_blink(5)
|
||||||
|
|
||||||
|
class ManyPrerequisites(Scene):
|
||||||
|
def construct(self):
|
||||||
|
title = TextMobject("Many prerequisites")
|
||||||
|
title.to_edge(UP)
|
||||||
|
h_line = Line(LEFT, RIGHT).scale(SPACE_WIDTH)
|
||||||
|
h_line.next_to(title, DOWN)
|
||||||
|
self.add(title)
|
||||||
|
self.play(ShowCreation(h_line))
|
||||||
|
|
||||||
|
rect = Rectangle(height = 9, width = 16, color = BLUE)
|
||||||
|
rect.scale_to_fit_width(SPACE_WIDTH-2)
|
||||||
|
rects = [rect]+[rect.copy() for i in range(3)]
|
||||||
|
words = [
|
||||||
|
"Linear transformations",
|
||||||
|
"Determinants",
|
||||||
|
"Linear systems",
|
||||||
|
"Change of basis",
|
||||||
|
]
|
||||||
|
for rect, word in zip(rects, words):
|
||||||
|
word_mob = TextMobject(word)
|
||||||
|
word_mob.next_to(rect, UP, buff = MED_BUFF)
|
||||||
|
rect.add(word_mob)
|
||||||
|
|
||||||
|
Matrix(np.array(rects).reshape((2, 2)))
|
||||||
|
rects = VGroup(*rects)
|
||||||
|
rects.scale_to_fit_height(2*SPACE_HEIGHT - 1.5)
|
||||||
|
rects.next_to(h_line, DOWN, buff = MED_BUFF)
|
||||||
|
|
||||||
|
self.play(Write(rects[0]))
|
||||||
|
self.dither()
|
||||||
|
self.play(*map(FadeIn, rects[1:]))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
class ExampleTranformationScene(LinearTransformationScene):
|
||||||
|
CONFIG = {
|
||||||
|
"t_matrix" : [[3, 0], [1, 2]]
|
||||||
|
}
|
||||||
|
def setup(self):
|
||||||
|
LinearTransformationScene.setup(self)
|
||||||
|
self.add_matrix()
|
||||||
|
|
||||||
|
def add_matrix(self):
|
||||||
|
matrix = Matrix(self.t_matrix.T)
|
||||||
|
matrix.highlight_columns(X_COLOR, Y_COLOR)
|
||||||
|
matrix.next_to(ORIGIN, LEFT, buff = MED_BUFF)
|
||||||
|
matrix.to_edge(UP)
|
||||||
|
matrix.rect = BackgroundRectangle(matrix)
|
||||||
|
matrix.add_to_back(matrix.rect)
|
||||||
|
self.add_foreground_mobject(matrix)
|
||||||
|
self.matrix = matrix
|
||||||
|
|
||||||
|
def remove_matrix(self):
|
||||||
|
self.remove(self.matrix)
|
||||||
|
self.foreground_mobjects.remove(self.matrix)
|
||||||
|
|
||||||
|
class IntroduceExampleTransformation(ExampleTranformationScene):
|
||||||
|
def construct(self):
|
||||||
|
self.remove_matrix()
|
||||||
|
i_coords = Matrix(self.t_matrix[0])
|
||||||
|
j_coords = Matrix(self.t_matrix[1])
|
||||||
|
|
||||||
|
self.apply_transposed_matrix(self.t_matrix)
|
||||||
|
for coords, vect in (i_coords, self.i_hat), (j_coords, self.j_hat):
|
||||||
|
coords.highlight(vect.get_color())
|
||||||
|
coords.scale(0.8)
|
||||||
|
coords.rect = BackgroundRectangle(coords)
|
||||||
|
coords.add_to_back(coords.rect)
|
||||||
|
coords.next_to(vect.get_end(), RIGHT)
|
||||||
|
self.play(Write(coords))
|
||||||
|
self.dither()
|
||||||
|
i_coords_copy = i_coords.copy()
|
||||||
|
self.play(*[
|
||||||
|
Transform(*pair)
|
||||||
|
for pair in [
|
||||||
|
(i_coords_copy.rect, self.matrix.rect),
|
||||||
|
(i_coords_copy.get_brackets(), self.matrix.get_brackets()),
|
||||||
|
(
|
||||||
|
i_coords_copy.get_entries(),
|
||||||
|
VGroup(*self.matrix.get_mob_matrix()[:,0])
|
||||||
|
)
|
||||||
|
]
|
||||||
|
])
|
||||||
|
self.play(Transform(
|
||||||
|
j_coords.copy().get_entries(),
|
||||||
|
VGroup(*self.matrix.get_mob_matrix()[:,1])
|
||||||
|
))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
class VectorKnockedOffSpan(ExampleTranformationScene):
|
||||||
|
def construct(self):
|
||||||
|
vector = Vector([2, 1])
|
||||||
|
line = Line(vector.get_end()*-4, vector.get_end()*4, color = MAROON_B)
|
||||||
|
vector.scale(0.7)
|
||||||
|
top_words, off, span_label = all_words = TextMobject(
|
||||||
|
"\\centering Vector gets knocked", "\\\\ off", "Span"
|
||||||
|
)
|
||||||
|
all_words.shift(
|
||||||
|
line.point_from_proportion(0.75) - \
|
||||||
|
span_label.get_corner(DOWN+RIGHT) + \
|
||||||
|
MED_BUFF*LEFT
|
||||||
|
)
|
||||||
|
for text in all_words:
|
||||||
|
text.add_to_back(BackgroundRectangle(text))
|
||||||
|
|
||||||
|
self.add_vector(vector)
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
ShowCreation(line),
|
||||||
|
Write(span_label),
|
||||||
|
Animation(vector),
|
||||||
|
)
|
||||||
|
self.add_foreground_mobject(span_label)
|
||||||
|
self.dither()
|
||||||
|
self.apply_transposed_matrix(self.t_matrix)
|
||||||
|
self.play(Animation(span_label.copy()), Write(all_words))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
class VectorRemainsOnSpan(ExampleTranformationScene):
|
||||||
|
def construct(self):
|
||||||
|
vector = Vector([1, -1])
|
||||||
|
v_end = vector.get_end()
|
||||||
|
line = Line(-4*v_end, 4*v_end, color = MAROON_B)
|
||||||
|
words = TextMobject("Vector remains on", "\\\\its own span")
|
||||||
|
words.next_to(ORIGIN, DOWN+LEFT)
|
||||||
|
for part in words:
|
||||||
|
part.add_to_back(BackgroundRectangle(part))
|
||||||
|
|
||||||
|
self.add_vector(vector)
|
||||||
|
self.play(ShowCreation(line), Animation(vector))
|
||||||
|
self.dither()
|
||||||
|
self.apply_transposed_matrix(self.t_matrix)
|
||||||
|
self.play(Write(words))
|
||||||
|
self.dither()
|
||||||
|
target_vectors = [
|
||||||
|
vector.copy().scale(scalar)
|
||||||
|
for scalar in 2, -2, 1
|
||||||
|
]
|
||||||
|
for target, time in zip(target_vectors, [1, 2, 2]):
|
||||||
|
self.play(Transform(vector, target, run_time = time))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
class IHatAsEigenVector(ExampleTranformationScene):
|
||||||
|
def construct(self):
|
||||||
|
# self.highlight_first_column()
|
||||||
|
def homotopy(x, y, z, t):
|
||||||
|
pass
|
||||||
|
x_axis = self.plane.axes[0]
|
||||||
|
self.play(
|
||||||
|
x_axis.highlight, GREEN_E,
|
||||||
|
Homotopy(plane_wave_homotopy, x_axis, run_time = 3)
|
||||||
|
)
|
||||||
|
|
||||||
|
def highlight_first_column(self):
|
||||||
|
faders = VGroup(self.plane, self.i_hat, self.j_hat)
|
||||||
|
faders.save_state()
|
||||||
|
column1 = VGroup(*self.matrix.get_mob_matrix()[:,0])
|
||||||
|
|
||||||
|
self.play(faders.fade, 0.7, Animation(self.matrix))
|
||||||
|
self.play(column1.scale_in_place, 1.3, rate_func = there_and_back)
|
||||||
|
self.dither()
|
||||||
|
self.play(faders.restore, Animation(self.matrix))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
|
class SneakierEigenVector(ExampleTranformationScene):
|
||||||
|
def construct(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class NameEigenvectorsAndEigenvalues(ExampleTranformationScene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -65,21 +300,6 @@ class NewSceneName(Scene):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ class TexMobject(SVGMobject):
|
||||||
"initial_scale_factor" : TEX_MOB_SCALE_FACTOR,
|
"initial_scale_factor" : TEX_MOB_SCALE_FACTOR,
|
||||||
"organize_left_to_right" : False,
|
"organize_left_to_right" : False,
|
||||||
"propogate_style_to_family" : True,
|
"propogate_style_to_family" : True,
|
||||||
|
"alignment" : "",
|
||||||
}
|
}
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
digest_config(self, kwargs, locals())
|
digest_config(self, kwargs, locals())
|
||||||
|
@ -72,6 +73,8 @@ class TexMobject(SVGMobject):
|
||||||
result = self.arg_separator.join(self.args)
|
result = self.arg_separator.join(self.args)
|
||||||
if self.enforce_new_line_structure:
|
if self.enforce_new_line_structure:
|
||||||
result = result.replace("\n", " \\\\ \n ")
|
result = result.replace("\n", " \\\\ \n ")
|
||||||
|
result = " ".join([self.alignment, result])
|
||||||
|
result = result.strip()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_tex_string(self):
|
def get_tex_string(self):
|
||||||
|
@ -120,6 +123,7 @@ class TextMobject(TexMobject):
|
||||||
"template_tex_file" : TEMPLATE_TEXT_FILE,
|
"template_tex_file" : TEMPLATE_TEXT_FILE,
|
||||||
"initial_scale_factor" : TEXT_MOB_SCALE_FACTOR,
|
"initial_scale_factor" : TEXT_MOB_SCALE_FACTOR,
|
||||||
"enforce_new_line_structure" : True,
|
"enforce_new_line_structure" : True,
|
||||||
|
"alignment" : "\\centering",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,7 @@ class PiCreature(SVGMobject):
|
||||||
else:
|
else:
|
||||||
point = point_or_mobject
|
point = point_or_mobject
|
||||||
self.look(point - self.eyes.get_center())
|
self.look(point - self.eyes.get_center())
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
def get_looking_direction(self):
|
def get_looking_direction(self):
|
||||||
|
@ -176,33 +177,6 @@ class Blink(ApplyMethod):
|
||||||
def __init__(self, pi_creature, **kwargs):
|
def __init__(self, pi_creature, **kwargs):
|
||||||
ApplyMethod.__init__(self, pi_creature.blink, **kwargs)
|
ApplyMethod.__init__(self, pi_creature.blink, **kwargs)
|
||||||
|
|
||||||
class DoTheWave(Transform):
|
|
||||||
CONFIG = {
|
|
||||||
"run_time" : 2
|
|
||||||
}
|
|
||||||
def __init__(self, pi_creature, **kwargs):
|
|
||||||
start_state = pi_creature.copy()
|
|
||||||
self.target_states = [
|
|
||||||
pi_creature.copy().change_mode("wave_%d"%x)
|
|
||||||
for x in 1, 2, 3
|
|
||||||
] + [
|
|
||||||
pi_creature.copy()
|
|
||||||
]
|
|
||||||
Transform.__init__(self, pi_creature, self.target_states[0], **kwargs)
|
|
||||||
|
|
||||||
def update_mobject(self, alpha):
|
|
||||||
scaled = alpha*len(self.target_states)
|
|
||||||
try:
|
|
||||||
if scaled-1 > 0:
|
|
||||||
self.starting_mobject = self.target_states[int(scaled)-1]
|
|
||||||
self.ending_mobject = self.target_states[int(scaled)]
|
|
||||||
except IndexError:
|
|
||||||
self.ending_mobject = self.target_states[-1]
|
|
||||||
Transform.update_mobject(self, scaled%1)
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Bubble(SVGMobject):
|
class Bubble(SVGMobject):
|
||||||
|
|
Loading…
Add table
Reference in a new issue