mirror of
https://github.com/3b1b/manim.git
synced 2025-07-30 13:34:19 +08:00
Starting chapter 4
This commit is contained in:
@ -137,9 +137,9 @@ COLOR_MAP = {
|
||||
"GREEN_SCREEN": "#00FF00",
|
||||
}
|
||||
PALETTE = COLOR_MAP.values()
|
||||
globals().update(COLOR_MAP)
|
||||
locals().update(COLOR_MAP)
|
||||
for name in filter(lambda s : s.endswith("_C"), COLOR_MAP.keys()):
|
||||
globals()[name.replace("_C", "")] = globals()[name]
|
||||
locals()[name.replace("_C", "")] = locals()[name]
|
||||
|
||||
|
||||
|
||||
|
167
eola/chapter3.py
167
eola/chapter3.py
@ -35,7 +35,7 @@ class OpeningQuote(Scene):
|
||||
words.scale_to_fit_width(2*SPACE_WIDTH - 2)
|
||||
words.to_edge(UP)
|
||||
words.split()[1].highlight(GREEN)
|
||||
words.split()[3].highlight(GREEN)
|
||||
words.split()[3].highlight(BLUE)
|
||||
author = TextMobject("-Morpheus")
|
||||
author.highlight(YELLOW)
|
||||
author.next_to(words, DOWN, buff = 0.5)
|
||||
@ -43,7 +43,6 @@ class OpeningQuote(Scene):
|
||||
(Surprisingly apt words on the importance
|
||||
of understanding matrix operations visually.)
|
||||
""")
|
||||
comment.scale(0.7)
|
||||
comment.next_to(author, DOWN, buff = 1)
|
||||
|
||||
self.play(FadeIn(words))
|
||||
@ -173,9 +172,25 @@ class WhyConfuseWithTerminology(TeacherStudentsScene):
|
||||
def construct(self):
|
||||
self.setup()
|
||||
self.student_says("Why confuse us with \\\\ redundant terminology?")
|
||||
other_students = [self.get_students()[i] for i in 0, 2]
|
||||
self.play(*[
|
||||
ApplyMethod(self.get_students()[i].change_mode, "confused")
|
||||
for i in 0, 2
|
||||
ApplyMethod(student.change_mode, "confused")
|
||||
for student in other_students
|
||||
])
|
||||
self.random_blink()
|
||||
self.dither()
|
||||
statement = TextMobject([
|
||||
"The word",
|
||||
"``transformation''",
|
||||
"suggests \\\\ that you think using",
|
||||
"movement",
|
||||
])
|
||||
statement.split()[1].highlight(BLUE)
|
||||
statement.split()[-1].highlight(YELLOW)
|
||||
self.teacher_says(statement, width = 10)
|
||||
self.play(*[
|
||||
ApplyMethod(student.change_mode, "happy")
|
||||
for student in other_students
|
||||
])
|
||||
self.random_blink()
|
||||
self.dither()
|
||||
@ -242,7 +257,7 @@ class TransformJustOneVector(VectorScene):
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class TransformManyVectors(VectorScene):
|
||||
class TransformManyVectors(LinearTransformationScene):
|
||||
CONFIG = {
|
||||
"transposed_matrix" : [[2, 1], [1, 2]],
|
||||
"use_dots" : False,
|
||||
@ -546,10 +561,11 @@ class YetAnotherLinearTransformation(SimpleLinearTransformationScene):
|
||||
words.add_background_rectangle()
|
||||
words.to_edge(UP)
|
||||
words.highlight(GREEN)
|
||||
formula = TexMobject(
|
||||
matrix_to_tex_string(["x", "y"]) + "\\rightarrow" + \
|
||||
matrix_to_tex_string(["-1x+3y", "1x + 2y"])
|
||||
)
|
||||
formula = TexMobject([
|
||||
matrix_to_tex_string(["x_\\text{in}", "y_\\text{in}"]),
|
||||
"\\rightarrow ???? \\rightarrow",
|
||||
matrix_to_tex_string(["x_\\text{out}", "y_{\\text{out}}"])
|
||||
])
|
||||
formula.add_background_rectangle()
|
||||
|
||||
self.play(Write(words))
|
||||
@ -569,9 +585,17 @@ class FollowIHatJHat(LinearTransformationScene):
|
||||
def construct(self):
|
||||
self.setup()
|
||||
i_hat = self.add_vector([1, 0], color = X_COLOR)
|
||||
i_label = self.label_vector(i_hat, "\\hat{\\imath}")
|
||||
i_label = self.label_vector(
|
||||
i_hat, "\\hat{\\imath}",
|
||||
color = X_COLOR,
|
||||
label_scale_val = 1
|
||||
)
|
||||
j_hat = self.add_vector([0, 1], color = Y_COLOR)
|
||||
j_label = self.label_vector(j_hat, "\\hat{\\jmath}")
|
||||
j_label = self.label_vector(
|
||||
j_hat, "\\hat{\\jmath}",
|
||||
color = Y_COLOR,
|
||||
label_scale_val = 1
|
||||
)
|
||||
|
||||
self.dither()
|
||||
self.play(*map(FadeOut, [i_label, j_label]))
|
||||
@ -742,17 +766,91 @@ class TrackBasisVectorsExample(LinearTransformationScene):
|
||||
self.play(Write(result))
|
||||
self.dither()
|
||||
|
||||
class TrackBasisVectorsExampleGenerally(TrackBasisVectorsExample):
|
||||
CONFIG = {
|
||||
"v_coord_strings" : ["x", "y"],
|
||||
"result_coords_string" : """
|
||||
=
|
||||
\\left[ \\begin{array}{c}
|
||||
1x + 3y \\\\
|
||||
-2x + 0y
|
||||
\\end{arary}\\right]
|
||||
"""
|
||||
}
|
||||
class WatchManyVectorsMove(TransformManyVectors):
|
||||
def construct(self):
|
||||
self.setup()
|
||||
vectors = VMobject(*[
|
||||
Vector([x, y])
|
||||
for x in np.arange(-int(SPACE_WIDTH)+0.5, int(SPACE_WIDTH)+0.5)
|
||||
for y in np.arange(-int(SPACE_HEIGHT)+0.5, int(SPACE_HEIGHT)+0.5)
|
||||
])
|
||||
vectors.submobject_gradient_highlight(PINK, YELLOW)
|
||||
dots = self.vectors_to_dots(vectors)
|
||||
self.play(ShowCreation(dots, submobject_mode = "lagged_start"))
|
||||
self.play(Transform(
|
||||
dots, vectors,
|
||||
submobject_mode = "lagged_start",
|
||||
run_time = 2
|
||||
))
|
||||
self.remove(dots)
|
||||
for v in vectors.split():
|
||||
self.add_vector(v, animate = False)
|
||||
self.apply_transposed_matrix([[1, -2], [3, 0]])
|
||||
self.dither()
|
||||
self.play(
|
||||
ApplyMethod(self.plane.fade),
|
||||
FadeOut(vectors),
|
||||
Animation(self.i_hat),
|
||||
Animation(self.j_hat),
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class NowWithoutWatching(Scene):
|
||||
def construct(self):
|
||||
text = TextMobject("Now without watching...")
|
||||
text.to_edge(UP)
|
||||
randy = Randolph(mode = "pondering")
|
||||
self.add(randy)
|
||||
self.play(Write(text, run_time = 1))
|
||||
self.play(ApplyMethod(randy.blink))
|
||||
self.dither(2)
|
||||
|
||||
class DeduceResultWithGeneralCoordinates(Scene):
|
||||
def construct(self):
|
||||
i_hat_to = TexMobject("\\hat{\\imath} \\rightarrow")
|
||||
j_hat_to = TexMobject("\\hat{\\jmath} \\rightarrow")
|
||||
i_coords = Matrix([1, -2])
|
||||
j_coords = Matrix([3, 0])
|
||||
i_coords.next_to(i_hat_to, RIGHT, buff = 0.1)
|
||||
j_coords.next_to(j_hat_to, RIGHT, buff = 0.1)
|
||||
i_group = VMobject(i_hat_to, i_coords)
|
||||
j_group = VMobject(j_hat_to, j_coords)
|
||||
i_group.highlight(X_COLOR)
|
||||
j_group.highlight(Y_COLOR)
|
||||
i_group.next_to(ORIGIN, LEFT, buff = 1).to_edge(UP)
|
||||
j_group.next_to(ORIGIN, RIGHT, buff = 1).to_edge(UP)
|
||||
|
||||
vect = Matrix(["x", "y"])
|
||||
x, y = vect.get_mob_matrix().flatten()
|
||||
VMobject(x, y).highlight(YELLOW)
|
||||
rto = TexMobject("\\rightarrow")
|
||||
equals = TexMobject("=")
|
||||
plus = TexMobject("+")
|
||||
row1 = TexMobject("1x + 3y")
|
||||
row2 = TexMobject("-2x + 0y")
|
||||
VMobject(
|
||||
row1.split()[0], row2.split()[0], row2.split()[1]
|
||||
).highlight(X_COLOR)
|
||||
VMobject(
|
||||
row1.split()[1], row1.split()[4], row2.split()[2], row2.split()[5]
|
||||
).highlight(YELLOW)
|
||||
VMobject(
|
||||
row1.split()[3], row2.split()[4]
|
||||
).highlight(Y_COLOR)
|
||||
result = Matrix([row1, row2])
|
||||
result.show()
|
||||
vect_group = VMobject(
|
||||
vect, rto,
|
||||
x.copy(), i_coords.copy(), plus,
|
||||
y.copy(), j_coords.copy(), equals,
|
||||
result
|
||||
)
|
||||
vect_group.arrange_submobjects(RIGHT, buff = 0.1)
|
||||
|
||||
self.add(i_group, j_group)
|
||||
for mob in vect_group.split():
|
||||
self.play(Write(mob))
|
||||
self.dither()
|
||||
|
||||
class MatrixVectorMultiplication(LinearTransformationScene):
|
||||
CONFIG = {
|
||||
@ -774,8 +872,8 @@ class MatrixVectorMultiplication(LinearTransformationScene):
|
||||
if self.abstract:
|
||||
new_i_coords = Matrix(["a", "c"])
|
||||
new_j_coords = Matrix(["b", "d"])
|
||||
new_i_coords.scale(0.7).move_to(i_coords)
|
||||
new_j_coords.scale(0.7).move_to(j_coords)
|
||||
new_i_coords.move_to(i_coords)
|
||||
new_j_coords.move_to(j_coords)
|
||||
i_coords = new_i_coords
|
||||
j_coords = new_j_coords
|
||||
i_coords.highlight(X_COLOR)
|
||||
@ -796,6 +894,9 @@ class MatrixVectorMultiplication(LinearTransformationScene):
|
||||
add_background_rectangles = True
|
||||
)
|
||||
concrete_matrix.to_edge(UP)
|
||||
if self.abstract:
|
||||
m = concrete_matrix.get_mob_matrix()[1, 0]
|
||||
m.shift(m.get_height()*DOWN/2)
|
||||
matrix_brackets = concrete_matrix.get_brackets()
|
||||
|
||||
self.play(ShowCreation(i_coords.rect), Write(i_coords))
|
||||
@ -916,7 +1017,6 @@ class MatrixVectorMultiplication(LinearTransformationScene):
|
||||
row2 = VMobject(*map(TexMobject, row2))
|
||||
for row in row1, row2:
|
||||
row.arrange_submobjects(RIGHT, buff = 0.1)
|
||||
row.scale(0.7)
|
||||
final_sum = Matrix([row1, row2])
|
||||
row1, row2 = final_sum.get_mob_matrix().flatten()
|
||||
row1.split()[0].highlight(X_COLOR)
|
||||
@ -933,6 +1033,7 @@ class MatrixVectorMultiplication(LinearTransformationScene):
|
||||
)
|
||||
self.dither()
|
||||
|
||||
|
||||
def reposition_matrix_and_vector(self, matrix, vector, formula):
|
||||
start_state = VMobject(matrix, vector)
|
||||
end_state = start_state.copy()
|
||||
@ -940,6 +1041,10 @@ class MatrixVectorMultiplication(LinearTransformationScene):
|
||||
equals = TexMobject("=")
|
||||
equals.next_to(formula, LEFT)
|
||||
end_state.next_to(equals, LEFT)
|
||||
brace = Brace(formula, DOWN)
|
||||
brace_words = TextMobject("Where all the intuition is")
|
||||
brace_words.next_to(brace, DOWN)
|
||||
brace_words.highlight(YELLOW)
|
||||
|
||||
self.play(
|
||||
Transform(
|
||||
@ -949,6 +1054,12 @@ class MatrixVectorMultiplication(LinearTransformationScene):
|
||||
Write(equals, run_time = 1)
|
||||
)
|
||||
self.dither()
|
||||
self.play(
|
||||
FadeIn(brace),
|
||||
FadeIn(brace_words),
|
||||
submobject_mode = "lagged_start"
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class MatrixVectorMultiplicationAbstract(MatrixVectorMultiplication):
|
||||
CONFIG = {
|
||||
@ -1128,6 +1239,11 @@ class DescribeShear(Describe90DegreeRotation):
|
||||
"title" : "``Shear''",
|
||||
}
|
||||
|
||||
class OtherWayAround(Scene):
|
||||
def construct(self):
|
||||
self.play(Write("What about the other way around?"))
|
||||
self.dither(2)
|
||||
|
||||
class DeduceTransformationFromMatrix(ColumnsToBasisVectors):
|
||||
def construct(self):
|
||||
self.setup()
|
||||
@ -1159,7 +1275,6 @@ class NextVideo(Scene):
|
||||
self.play(ShowCreation(rect))
|
||||
self.dither()
|
||||
|
||||
|
||||
class FinalSlide(Scene):
|
||||
def construct(self):
|
||||
text = TextMobject("""
|
||||
|
311
eola/chapter4.py
Normal file
311
eola/chapter4.py
Normal file
@ -0,0 +1,311 @@
|
||||
from mobject.tex_mobject import TexMobject
|
||||
from mobject import Mobject
|
||||
from mobject.image_mobject import ImageMobject
|
||||
from mobject.vectorized_mobject import VMobject
|
||||
|
||||
from animation.animation import Animation
|
||||
from animation.transform import *
|
||||
from animation.simple_animations import *
|
||||
from topics.geometry import *
|
||||
from topics.characters import *
|
||||
from topics.functions import *
|
||||
from topics.number_line import *
|
||||
from topics.numerals import *
|
||||
from scene import Scene
|
||||
from camera import Camera
|
||||
from mobject.svg_mobject import *
|
||||
from mobject.tex_mobject import *
|
||||
from mobject.vectorized_mobject import *
|
||||
|
||||
from eola.matrix import *
|
||||
from eola.two_d_space import *
|
||||
from eola.chapter3 import MatrixVectorMultiplicationAbstract
|
||||
|
||||
|
||||
class OpeningQuote(Scene):
|
||||
def construct(self):
|
||||
words = TextMobject([
|
||||
"It is my experience that proofs involving",
|
||||
"matrices",
|
||||
"can be shortened by 50\\% if one",
|
||||
"throws the matrices out."
|
||||
])
|
||||
words.scale_to_fit_width(2*SPACE_WIDTH - 2)
|
||||
words.to_edge(UP)
|
||||
words.split()[1].highlight(GREEN)
|
||||
words.split()[3].highlight(BLUE)
|
||||
author = TextMobject("-Emil Artin")
|
||||
author.highlight(YELLOW)
|
||||
author.next_to(words, DOWN, buff = 0.5)
|
||||
|
||||
self.play(FadeIn(words))
|
||||
self.dither(2)
|
||||
self.play(Write(author, run_time = 3))
|
||||
self.dither()
|
||||
|
||||
class MatrixToBlank(Scene):
|
||||
def construct(self):
|
||||
matrix = Matrix([[3, 1], [0, 2]])
|
||||
arrow = Arrow(LEFT, RIGHT)
|
||||
matrix.to_edge(LEFT)
|
||||
arrow.next_to(matrix, LEFT)
|
||||
matrix.add(arrow)
|
||||
self.play(Write(matrix))
|
||||
self.dither()
|
||||
|
||||
class RecapTime(TeacherStudentsScene):
|
||||
def construct(self):
|
||||
self.setup()
|
||||
self.teacher_says("Quick recap time!")
|
||||
self.random_blink()
|
||||
self.dither()
|
||||
student = self.get_students()[0]
|
||||
everyone = self.get_mobjects()
|
||||
everyone.remove(student)
|
||||
everyone = VMobject(*everyone)
|
||||
self.play(
|
||||
ApplyMethod(everyone.fade, 0.7),
|
||||
ApplyMethod(student.change_mode, "confused")
|
||||
)
|
||||
self.play(Blink(student))
|
||||
self.dither()
|
||||
self.play(ApplyFunction(
|
||||
lambda m : m.change_mode("pondering").look(LEFT),
|
||||
student
|
||||
))
|
||||
self.play(Blink(student))
|
||||
self.dither()
|
||||
|
||||
class DeterminedByTwoBasisVectors(LinearTransformationScene):
|
||||
CONFIG = {
|
||||
"show_basis_vectors" : False
|
||||
}
|
||||
def construct(self):
|
||||
self.setup()
|
||||
i_hat = self.add_vector([1, 0], color = X_COLOR)
|
||||
self.add_transformable_label(
|
||||
i_hat, "\\hat{\\imath}", "\\hat{\\imath}",
|
||||
color = X_COLOR
|
||||
)
|
||||
j_hat = self.add_vector([0, 1], color = Y_COLOR)
|
||||
self.add_transformable_label(
|
||||
j_hat, "\\hat{\\jmath}", "\\hat{\\jmath}",
|
||||
color = Y_COLOR
|
||||
)
|
||||
|
||||
t_matrix = np.array([[2, 2], [-2, 1]])
|
||||
matrix = t_matrix.transpose()
|
||||
matrix1 = np.array(matrix)
|
||||
matrix1[:,1] = [0, 1]
|
||||
matrix2 = np.dot(matrix, np.linalg.inv(matrix1))
|
||||
|
||||
self.dither()
|
||||
self.apply_transposed_matrix(matrix1.transpose())
|
||||
self.apply_transposed_matrix(matrix2.transpose())
|
||||
self.dither()
|
||||
|
||||
class FollowLinearCombination(LinearTransformationScene):
|
||||
def construct(self):
|
||||
vect_coords = [-1, 2]
|
||||
t_matrix = np.array([[2, 2], [-2, 1]])
|
||||
|
||||
#Draw vectors
|
||||
self.setup()
|
||||
i_label = self.add_transformable_label(
|
||||
self.i_hat, "\\hat{\\imath}", animate = False,
|
||||
direction = "right", color = X_COLOR
|
||||
)
|
||||
j_label = self.add_transformable_label(
|
||||
self.j_hat, "\\hat{\\jmath}", animate = False,
|
||||
direction = "right", color = Y_COLOR
|
||||
)
|
||||
vect = self.add_vector(vect_coords)
|
||||
vect_array = Matrix(["x", "y"], add_background_rectangles = True)
|
||||
v_equals = TexMobject(["\\vec{\\textbf{v}}", "="])
|
||||
v_equals.split()[0].highlight(YELLOW)
|
||||
v_equals.next_to(vect_array, LEFT)
|
||||
vect_array.add(v_equals)
|
||||
vect_array.to_edge(UP, buff = 0.2)
|
||||
background_rect = BackgroundRectangle(vect_array)
|
||||
vect_array.get_entries().highlight(YELLOW)
|
||||
self.play(ShowCreation(background_rect), Write(vect_array))
|
||||
self.add_foreground_mobject(background_rect, vect_array)
|
||||
|
||||
#Show scaled vectors
|
||||
x, y = vect_array.get_entries().split()
|
||||
scaled_i_label = VMobject(x.copy(), i_label)
|
||||
scaled_j_label = VMobject(y.copy(), j_label)
|
||||
scaled_i = self.i_hat.copy().scale(vect_coords[0])
|
||||
scaled_j = self.j_hat.copy().scale(vect_coords[1])
|
||||
for mob in scaled_i, scaled_j:
|
||||
mob.fade(0.3)
|
||||
scaled_i_label_target = scaled_i_label.copy()
|
||||
scaled_i_label_target.arrange_submobjects(buff = 0.1)
|
||||
scaled_i_label_target.next_to(scaled_i, DOWN)
|
||||
scaled_j_label_target = scaled_j_label.copy()
|
||||
scaled_j_label_target.arrange_submobjects(buff = 0.1)
|
||||
scaled_j_label_target.next_to(scaled_j, LEFT)
|
||||
|
||||
self.show_scaled_vectors(vect_array, vect_coords, i_label, j_label)
|
||||
self.apply_transposed_matrix(t_matrix)
|
||||
self.show_scaled_vectors(vect_array, vect_coords, i_label, j_label)
|
||||
self.record_basis_coordinates(vect_array, vect)
|
||||
|
||||
def show_scaled_vectors(self, vect_array, vect_coords, i_label, j_label):
|
||||
x, y = vect_array.get_entries().split()
|
||||
scaled_i_label = VMobject(x.copy(), i_label.copy())
|
||||
scaled_j_label = VMobject(y.copy(), j_label.copy())
|
||||
scaled_i = self.i_hat.copy().scale(vect_coords[0])
|
||||
scaled_j = self.j_hat.copy().scale(vect_coords[1])
|
||||
for mob in scaled_i, scaled_j:
|
||||
mob.fade(0.3)
|
||||
scaled_i_label_target = scaled_i_label.copy()
|
||||
scaled_i_label_target.arrange_submobjects(buff = 0.1)
|
||||
scaled_i_label_target.next_to(scaled_i.get_center(), DOWN)
|
||||
scaled_j_label_target = scaled_j_label.copy()
|
||||
scaled_j_label_target.arrange_submobjects(buff = 0.1)
|
||||
scaled_j_label_target.next_to(scaled_j.get_center(), LEFT)
|
||||
|
||||
self.play(
|
||||
Transform(self.i_hat.copy(), scaled_i),
|
||||
Transform(scaled_i_label, scaled_i_label_target)
|
||||
)
|
||||
scaled_i = self.get_mobjects_from_last_animation()[0]
|
||||
self.play(
|
||||
Transform(self.j_hat.copy(), scaled_j),
|
||||
Transform(scaled_j_label, scaled_j_label_target)
|
||||
)
|
||||
scaled_j = self.get_mobjects_from_last_animation()[0]
|
||||
self.play(*[
|
||||
ApplyMethod(mob.shift, scaled_i.get_end())
|
||||
for mob in scaled_j, scaled_j_label
|
||||
])
|
||||
self.dither()
|
||||
self.play(*map(FadeOut, [
|
||||
scaled_i, scaled_j, scaled_i_label, scaled_j_label,
|
||||
]))
|
||||
|
||||
def record_basis_coordinates(self, vect_array, vect):
|
||||
i_label = vector_coordinate_label(self.i_hat)
|
||||
i_label.highlight(X_COLOR)
|
||||
j_label = vector_coordinate_label(self.j_hat)
|
||||
j_label.highlight(Y_COLOR)
|
||||
for mob in i_label, j_label:
|
||||
mob.scale_in_place(0.8)
|
||||
background = BackgroundRectangle(mob)
|
||||
self.play(ShowCreation(background), Write(mob))
|
||||
|
||||
self.dither()
|
||||
x, y = vect_array.get_entries().split()
|
||||
pre_formula = VMobject(
|
||||
x, i_label, TexMobject("+"),
|
||||
y, j_label
|
||||
)
|
||||
post_formula = pre_formula.copy()
|
||||
pre_formula.split()[2].fade(1)
|
||||
post_formula.arrange_submobjects(buff = 0.1)
|
||||
post_formula.next_to(vect, DOWN)
|
||||
background = BackgroundRectangle(post_formula)
|
||||
everything = self.get_mobjects()
|
||||
everything.remove(vect)
|
||||
self.play(*[
|
||||
ApplyMethod(m.fade) for m in everything
|
||||
] + [
|
||||
ShowCreation(background, run_time = 2, rate_func = squish_rate_func(smooth, 0.5, 1)),
|
||||
Transform(pre_formula.copy(), post_formula, run_time = 2),
|
||||
ApplyMethod(vect.set_stroke, width = 7)
|
||||
])
|
||||
self.dither()
|
||||
|
||||
class MatrixVectorMultiplicationCopy(MatrixVectorMultiplicationAbstract):
|
||||
pass ## Here just for stage_animations.py purposes
|
||||
|
||||
class RecapOver(TeacherStudentsScene):
|
||||
def construct(self):
|
||||
self.setup()
|
||||
self.teacher_says("Recap over!")
|
||||
|
||||
class TwoSuccessiveTransformations(LinearTransformationScene):
|
||||
def construct(self):
|
||||
self.setup()
|
||||
self.apply_transposed_matrix([[2, 1],[1, 2]])
|
||||
self.apply_transposed_matrix([[-1, -0.5],[0, -0.5]])
|
||||
self.dither()
|
||||
|
||||
class RotationThenShear(LinearTransformationScene):
|
||||
CONFIG = {
|
||||
"foreground_plane_kwargs" : {
|
||||
"x_radius" : SPACE_WIDTH,
|
||||
"y_radius" : 2*SPACE_WIDTH,
|
||||
"secondary_line_ratio" : 0
|
||||
},
|
||||
}
|
||||
def construct(self):
|
||||
self.setup()
|
||||
rot_words = TextMobject("$90^\\circ$ rotation counterclockwise")
|
||||
shear_words = TextMobject("followed by a shear")
|
||||
rot_words.highlight(YELLOW)
|
||||
shear_words.highlight(PINK)
|
||||
VMobject(rot_words, shear_words).arrange_submobjects(DOWN).to_edge(UP)
|
||||
for words in rot_words, shear_words:
|
||||
words.add_background_rectangle()
|
||||
|
||||
self.play(Write(rot_words, run_time = 1))
|
||||
self.add_foreground_mobject(rot_words)
|
||||
self.apply_transposed_matrix([[0, 1], [-1, 0]])
|
||||
|
||||
self.play(Write(shear_words, run_time = 1))
|
||||
self.add_foreground_mobject(shear_words)
|
||||
self.apply_transposed_matrix([[1, 0], [1, 1]])
|
||||
self.dither()
|
||||
|
||||
class IntroduceIdeaOfComposition(RotationThenShear):
|
||||
def construct(self):
|
||||
self.setup()
|
||||
self.show_composition()
|
||||
self.track_basis_vectors()
|
||||
|
||||
def show_composition(self):
|
||||
words = TextMobject([
|
||||
"``Composition''",
|
||||
"of a",
|
||||
"rotation",
|
||||
"and a",
|
||||
"shear"
|
||||
])
|
||||
words.split()[0].submobject_gradient_highlight(YELLOW, PINK, use_color_range_to = False)
|
||||
words.split()[2].highlight(YELLOW)
|
||||
words.split()[4].highlight(PINK)
|
||||
words.add_background_rectangle()
|
||||
words.to_edge(UP)
|
||||
|
||||
self.apply_transposed_matrix([[0, 1], [-1, 0]], run_time = 2)
|
||||
self.apply_transposed_matrix([[1, 0], [1, 1]], run_time = 2)
|
||||
self.play(Write(words))
|
||||
self.dither()
|
||||
|
||||
def track_basis_vectors(self):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -12,7 +12,7 @@ from topics.geometry import Vector, Line, Circle, Arrow, Dot
|
||||
|
||||
from helpers import *
|
||||
|
||||
VECTOR_LABEL_SCALE_VAL = 0.7
|
||||
VECTOR_LABEL_SCALE_VAL = 1.0
|
||||
|
||||
def matrix_to_tex_string(matrix):
|
||||
matrix = np.array(matrix).astype("string")
|
||||
@ -107,6 +107,9 @@ class Matrix(VMobject):
|
||||
def get_mob_matrix(self):
|
||||
return self.mob_matrix
|
||||
|
||||
def get_entries(self):
|
||||
return VMobject(*self.get_mob_matrix().flatten())
|
||||
|
||||
def get_brackets(self):
|
||||
return self.brackets
|
||||
|
||||
|
@ -311,6 +311,8 @@ class LinearTransformationScene(VectorScene):
|
||||
label_mob.target_text = "L(%s)"%label_mob.expression
|
||||
label_mob.vector = vector
|
||||
label_mob.kwargs = kwargs
|
||||
if "animate" in label_mob.kwargs:
|
||||
label_mob.kwargs.pop("animate")
|
||||
self.transformable_labels.append(label_mob)
|
||||
return label_mob
|
||||
|
||||
|
@ -297,9 +297,16 @@ class Mobject(object):
|
||||
def gradient_highlight(self, start_color, end_color):
|
||||
raise Exception("Not implemented")
|
||||
|
||||
def submobject_gradient_highlight(self, start_color, end_color):
|
||||
def submobject_gradient_highlight(self, start_color, end_color, use_color_range_to = False):
|
||||
mobs = self.family_members_with_points()
|
||||
if use_color_range_to:
|
||||
colors = Color(start_color).range_to(end_color, len(mobs))
|
||||
else:
|
||||
rgb1, rgb2 = map(color_to_rgb, [start_color, end_color])
|
||||
colors = [
|
||||
Color(rgb = interpolate(rgb1, rgb2, alpha))
|
||||
for alpha in np.linspace(0, 1, len(mobs))
|
||||
]
|
||||
for mob, color in zip(mobs, colors):
|
||||
mob.highlight(color, family = False)
|
||||
return self
|
||||
|
@ -286,6 +286,12 @@ class BackgroundRectangle(Rectangle):
|
||||
self.lock_style = True
|
||||
return self
|
||||
|
||||
def fade_to(self, *args, **kwargs):
|
||||
self.lock_style = False
|
||||
Rectangle.fade_to(self, *args, **kwargs)
|
||||
self.lock_style = True
|
||||
return self
|
||||
|
||||
def set_style_data(self, *args, **kwargs):
|
||||
if self.lock_style:
|
||||
return self #Do nothing
|
||||
|
Reference in New Issue
Block a user