mirror of
https://github.com/3b1b/manim.git
synced 2025-07-30 13:34:19 +08:00
Starting chapter 7
This commit is contained in:
@ -29,8 +29,12 @@ SPACE_HEIGHT = 4.0
|
||||
SPACE_WIDTH = SPACE_HEIGHT * DEFAULT_WIDTH / DEFAULT_HEIGHT
|
||||
|
||||
|
||||
DEFAULT_MOBJECT_TO_EDGE_BUFFER = 0.5
|
||||
DEFAULT_MOBJECT_TO_MOBJECT_BUFFER = 0.2
|
||||
SMALL_BUFF = 0.1
|
||||
MED_BUFF = 0.5
|
||||
LARGE_BUFF = 1
|
||||
|
||||
DEFAULT_MOBJECT_TO_EDGE_BUFFER = MED_BUFF
|
||||
DEFAULT_MOBJECT_TO_MOBJECT_BUFFER = MED_BUFF
|
||||
|
||||
|
||||
#All in seconds
|
||||
|
69
eola/chapter7.py
Normal file
69
eola/chapter7.py
Normal file
@ -0,0 +1,69 @@
|
||||
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 ka_playgrounds.circuits import Resistor, Source, LongResistor
|
||||
|
||||
class OpeningQuote(Scene):
|
||||
def construct(self):
|
||||
words = TextMobject(
|
||||
"\\small Calvin:",
|
||||
"You know, I don't think math is a science, I think it's a religion.",
|
||||
"\\\\Hobbes:",
|
||||
"A religion?",
|
||||
"\\\\Calvin:" ,
|
||||
"Yeah. All these equations are like miracles."
|
||||
"You take two numbers and when you add them, "
|
||||
"they magically become one NEW number!"
|
||||
)
|
||||
words.scale_to_fit_width(2*SPACE_WIDTH - 1)
|
||||
words.to_edge(UP)
|
||||
words[0].highlight(YELLOW)
|
||||
words[2].highlight("#fd9c2b")
|
||||
words[4].highlight(YELLOW)
|
||||
|
||||
self.play(FadeIn(words))
|
||||
self.dither(2)
|
||||
|
||||
class TraditionalOrdering(RandolphScene):
|
||||
def construct(self):
|
||||
title = TextMobject("Traditional ordering:")
|
||||
title.highlight(YELLOW).to_edge(UP)
|
||||
topics = VMobject(*map(TextMobject, [
|
||||
"Topic 1: Vectors",
|
||||
"Topic 2: Dot product",
|
||||
"\\vdots",
|
||||
"(everything else)",
|
||||
"\\vdots",
|
||||
]))
|
||||
topics.arrange_submobjects(DOWN)
|
||||
topics.next_to(title, DOWN)
|
||||
|
||||
self.play(
|
||||
Write(title),
|
||||
FadeIn(topics, submobject_mode = "lagged_start")
|
||||
)
|
||||
self.play(topics[1].highlight, PINK)
|
||||
self.dither()
|
||||
|
||||
class ThisSeriesOrdering(RandolphScene):
|
||||
def construct(self):
|
||||
pass
|
@ -63,9 +63,14 @@ class ColumnsRepresentBasisVectors(Scene):
|
||||
i_hat_words.next_to(ORIGIN, LEFT).to_edge(UP)
|
||||
j_hat_words.highlight(Y_COLOR)
|
||||
j_hat_words.next_to(ORIGIN, RIGHT).to_edge(UP)
|
||||
question = TextMobject("How to interpret?")
|
||||
question.next_to(matrix, UP)
|
||||
question.highlight(YELLOW)
|
||||
|
||||
self.add(matrix)
|
||||
self.play(Write(question, run_time = 2))
|
||||
self.dither()
|
||||
self.play(FadeOut(question))
|
||||
for i, words in enumerate([i_hat_words, j_hat_words]):
|
||||
arrow = Arrow(
|
||||
words.get_bottom(),
|
||||
@ -80,6 +85,557 @@ class ColumnsRepresentBasisVectors(Scene):
|
||||
for m in matrix.get_mob_matrix()[:,i]
|
||||
]
|
||||
)
|
||||
self.dither(2)
|
||||
self.put_in_thought_bubble()
|
||||
|
||||
def put_in_thought_bubble(self):
|
||||
everything = VMobject(*self.get_mobjects())
|
||||
randy = Randolph().to_corner()
|
||||
bubble = randy.get_bubble()
|
||||
|
||||
self.play(FadeIn(randy))
|
||||
self.play(
|
||||
ApplyFunction(
|
||||
lambda m : bubble.position_mobject_inside(
|
||||
m.scale_to_fit_height(2.5)
|
||||
),
|
||||
everything
|
||||
),
|
||||
ShowCreation(bubble),
|
||||
randy.change_mode, "pondering"
|
||||
)
|
||||
self.play(Blink(randy))
|
||||
self.dither()
|
||||
self.play(randy.change_mode, "surprised")
|
||||
self.dither()
|
||||
|
||||
class Symbolic2To3DTransform(Scene):
|
||||
def construct(self):
|
||||
func = TexMobject("L(", "\\vec{\\textbf{v}}", ")")
|
||||
input_array = Matrix([2, 7])
|
||||
input_array.highlight(YELLOW)
|
||||
in_arrow = Arrow(LEFT, RIGHT, color = input_array.get_color())
|
||||
func[1].highlight(input_array.get_color())
|
||||
output_array = Matrix([1, 8, 2])
|
||||
output_array.highlight(PINK)
|
||||
out_arrow = Arrow(LEFT, RIGHT, color = output_array.get_color())
|
||||
VMobject(
|
||||
input_array, in_arrow, func, out_arrow, output_array
|
||||
).arrange_submobjects(RIGHT, buff = SMALL_BUFF)
|
||||
|
||||
input_brace = Brace(input_array, DOWN)
|
||||
input_words = input_brace.get_text("2d input")
|
||||
output_brace = Brace(output_array, UP)
|
||||
output_words = output_brace.get_text("3d output")
|
||||
input_words.highlight(input_array.get_color())
|
||||
output_words.highlight(output_array.get_color())
|
||||
|
||||
|
||||
self.add(func, input_array)
|
||||
self.play(
|
||||
GrowFromCenter(input_brace),
|
||||
Write(input_words)
|
||||
)
|
||||
mover = input_array.copy()
|
||||
self.play(
|
||||
Transform(mover, Dot().move_to(func)),
|
||||
ShowCreation(in_arrow),
|
||||
rate_func = rush_into
|
||||
)
|
||||
self.play(
|
||||
Transform(mover, output_array),
|
||||
ShowCreation(out_arrow),
|
||||
rate_func = rush_from
|
||||
)
|
||||
self.play(
|
||||
GrowFromCenter(output_brace),
|
||||
Write(output_words)
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class PlaneStartState(LinearTransformationScene):
|
||||
def construct(self):
|
||||
self.add_title("Input space")
|
||||
labels = self.get_basis_vector_labels()
|
||||
self.play(*map(Write, labels))
|
||||
self.dither()
|
||||
|
||||
class OutputIn3dWords(Scene):
|
||||
def construct(self):
|
||||
words = TextMobject("Output in 3d")
|
||||
words.scale(1.5)
|
||||
self.play(Write(words))
|
||||
self.dither()
|
||||
|
||||
class OutputIn3d(Scene):
|
||||
pass
|
||||
|
||||
class ShowSideBySide2dTo3d(Scene):
|
||||
pass
|
||||
|
||||
class AnimationLaziness(Scene):
|
||||
def construct(self):
|
||||
self.add(TextMobject("But there is some animation laziness..."))
|
||||
|
||||
class DescribeColumnsInSpecificTransformation(Scene):
|
||||
def construct(self):
|
||||
matrix = Matrix([
|
||||
[2, 0],
|
||||
[-1, 1],
|
||||
[-2, 1],
|
||||
])
|
||||
matrix.highlight_columns(X_COLOR, Y_COLOR)
|
||||
mob_matrix = matrix.get_mob_matrix()
|
||||
i_col, j_col = [VMobject(*mob_matrix[:,i]) for i in 0, 1]
|
||||
for col, char, vect in zip([i_col, j_col], ["i", "j"], [UP, DOWN]):
|
||||
color = col[0].get_color()
|
||||
col.words = TextMobject("Where $\\hat\\%smath$ lands"%char)
|
||||
col.words.next_to(matrix, vect, buff = LARGE_BUFF)
|
||||
col.words.highlight(color)
|
||||
col.arrow = Arrow(
|
||||
col.words.get_edge_center(-vect),
|
||||
col.get_edge_center(vect),
|
||||
color = color
|
||||
)
|
||||
|
||||
self.play(Write(matrix.get_brackets()))
|
||||
self.dither()
|
||||
for col in i_col, j_col:
|
||||
self.play(
|
||||
Write(col),
|
||||
ShowCreation(col.arrow),
|
||||
Write(col.words, run_time = 1)
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class CountRowsAndColumns(Scene):
|
||||
def construct(self):
|
||||
matrix = Matrix([
|
||||
[2, 0],
|
||||
[-1, 1],
|
||||
[-2, 1],
|
||||
])
|
||||
matrix.highlight_columns(X_COLOR, Y_COLOR)
|
||||
rows_brace = Brace(matrix, LEFT)
|
||||
rows_words = rows_brace.get_text("3", "rows")
|
||||
rows_words.highlight(PINK)
|
||||
cols_brace = Brace(matrix, UP)
|
||||
cols_words = cols_brace.get_text("2", "columns")
|
||||
cols_words.highlight(TEAL)
|
||||
title = TexMobject("3", "\\times", "2", "\\text{ matrix}")
|
||||
title.to_edge(UP)
|
||||
|
||||
self.add(matrix)
|
||||
self.play(
|
||||
GrowFromCenter(rows_brace),
|
||||
Write(rows_words, run_time = 2)
|
||||
)
|
||||
self.play(
|
||||
GrowFromCenter(cols_brace),
|
||||
Write(cols_words, run_time = 2)
|
||||
)
|
||||
self.dither()
|
||||
self.play(
|
||||
rows_words[0].copy().move_to, title[0],
|
||||
cols_words[0].copy().move_to, title[2],
|
||||
Write(VMobject(title[1], title[3]))
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class WriteColumnSpaceDefinition(Scene):
|
||||
def construct(self):
|
||||
matrix = Matrix([
|
||||
[2, 0],
|
||||
[-1, 1],
|
||||
[-2, 1],
|
||||
])
|
||||
matrix.highlight_columns(X_COLOR, Y_COLOR)
|
||||
|
||||
brace = Brace(matrix)
|
||||
words = VMobject(
|
||||
TextMobject("Span", "of columns"),
|
||||
TexMobject("\\Updownarrow"),
|
||||
TextMobject("``Column space''")
|
||||
)
|
||||
words.arrange_submobjects(DOWN, buff = 0.1)
|
||||
words.next_to(brace, DOWN)
|
||||
words[0][0].highlight(PINK)
|
||||
words[2].highlight(TEAL)
|
||||
words[0].add_background_rectangle()
|
||||
words[2].add_background_rectangle()
|
||||
VMobject(matrix, brace, words).center()
|
||||
|
||||
self.add(matrix)
|
||||
self.play(
|
||||
GrowFromCenter(brace),
|
||||
Write(words, run_time = 2)
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class MatrixInTheWild(Scene):
|
||||
def construct(self):
|
||||
randy = Randolph(color = PINK)
|
||||
randy.look(LEFT)
|
||||
randy.to_corner()
|
||||
matrix = Matrix([
|
||||
[3, 1],
|
||||
[4, 1],
|
||||
[5, 9],
|
||||
])
|
||||
matrix.next_to(randy, RIGHT, buff = LARGE_BUFF, aligned_edge = DOWN)
|
||||
bubble = randy.get_bubble(height = 4)
|
||||
bubble.make_green_screen()
|
||||
VMobject(randy, bubble, matrix).to_corner(UP+LEFT, buff = MED_BUFF)
|
||||
|
||||
self.add(randy)
|
||||
self.play(Write(matrix))
|
||||
self.play(randy.look, RIGHT, run_time = 0.5)
|
||||
self.play(randy.change_mode, "sassy")
|
||||
self.play(Blink(randy))
|
||||
self.play(
|
||||
ShowCreation(bubble),
|
||||
randy.change_mode, "pondering"
|
||||
)
|
||||
# self.play(matrix.highlight_columns, X_COLOR, Y_COLOR)
|
||||
self.dither()
|
||||
for x in range(3):
|
||||
self.play(Blink(randy))
|
||||
self.dither(2)
|
||||
new_matrix = Matrix([[3, 1, 4], [1, 5, 9]])
|
||||
new_matrix.move_to(matrix, side_to_align = UP+LEFT)
|
||||
self.play(
|
||||
Transform(matrix, new_matrix),
|
||||
FadeOut(bubble)
|
||||
)
|
||||
self.remove(matrix)
|
||||
matrix = new_matrix
|
||||
self.add(matrix)
|
||||
self.play(randy.look, DOWN+RIGHT, run_time = 0.5)
|
||||
self.play(randy.change_mode, "confused")
|
||||
self.dither()
|
||||
self.play(Blink(randy))
|
||||
self.dither()
|
||||
|
||||
top_brace = Brace(matrix, UP)
|
||||
top_words = top_brace.get_text("3 basis vectors")
|
||||
top_words.submobject_gradient_highlight(GREEN, RED, BLUE)
|
||||
side_brace = Brace(matrix, RIGHT)
|
||||
side_words = side_brace.get_text("""
|
||||
2 coordinates for
|
||||
each landing spots
|
||||
""")
|
||||
side_words.highlight(YELLOW)
|
||||
|
||||
self.play(
|
||||
GrowFromCenter(top_brace),
|
||||
Write(top_words),
|
||||
matrix.highlight_columns, X_COLOR, Y_COLOR, Z_COLOR
|
||||
)
|
||||
self.play(randy.change_mode, "happy")
|
||||
self.play(
|
||||
GrowFromCenter(side_brace),
|
||||
Write(side_words, run_time = 2)
|
||||
)
|
||||
self.play(Blink(randy))
|
||||
self.dither()
|
||||
|
||||
class ThreeDToTwoDInput(Scene):
|
||||
pass
|
||||
|
||||
class ThreeDToTwoDInputWords(Scene):
|
||||
def construct(self):
|
||||
words = TextMobject("3d input")
|
||||
words.scale(2)
|
||||
self.play(Write(words))
|
||||
self.dither()
|
||||
|
||||
class ThreeDToTwoDOutput(LinearTransformationScene):
|
||||
CONFIG = {
|
||||
"show_basis_vectors" : False,
|
||||
"foreground_plane_kwargs" : {
|
||||
"color" : GREY,
|
||||
"x_radius" : SPACE_WIDTH,
|
||||
"y_radius" : SPACE_HEIGHT,
|
||||
"secondary_line_ratio" : 0
|
||||
},
|
||||
}
|
||||
def construct(self):
|
||||
title = TextMobject("Output in 2d")
|
||||
title.to_edge(UP, buff = SMALL_BUFF)
|
||||
subwords = TextMobject("""
|
||||
(only showing basis vectors,
|
||||
full 3d grid would be a mess)
|
||||
""")
|
||||
subwords.scale(0.75)
|
||||
subwords.next_to(title, DOWN)
|
||||
for words in title, subwords:
|
||||
words.add_background_rectangle()
|
||||
|
||||
self.add(title)
|
||||
i, j, k = it.starmap(self.add_vector, [
|
||||
([3, 1], X_COLOR),
|
||||
([1, 2], Y_COLOR),
|
||||
([-2, -2], Z_COLOR)
|
||||
])
|
||||
pairs = [
|
||||
(i, "L(\\hat\\imath)"),
|
||||
(j, "L(\\hat\\jmath)"),
|
||||
(k, "L(\\hat k)")
|
||||
]
|
||||
for v, tex in pairs:
|
||||
self.label_vector(v, tex)
|
||||
self.play(Write(subwords))
|
||||
self.dither()
|
||||
|
||||
class ThreeDToTwoDSideBySide(Scene):
|
||||
pass
|
||||
|
||||
class Symbolic2To1DTransform(Scene):
|
||||
def construct(self):
|
||||
func = TexMobject("L(", "\\vec{\\textbf{v}}", ")")
|
||||
input_array = Matrix([2, 7])
|
||||
input_array.highlight(YELLOW)
|
||||
in_arrow = Arrow(LEFT, RIGHT, color = input_array.get_color())
|
||||
func[1].highlight(input_array.get_color())
|
||||
output_array = Matrix([1.8])
|
||||
output_array.highlight(PINK)
|
||||
out_arrow = Arrow(LEFT, RIGHT, color = output_array.get_color())
|
||||
VMobject(
|
||||
input_array, in_arrow, func, out_arrow, output_array
|
||||
).arrange_submobjects(RIGHT, buff = SMALL_BUFF)
|
||||
|
||||
input_brace = Brace(input_array, DOWN)
|
||||
input_words = input_brace.get_text("2d input")
|
||||
output_brace = Brace(output_array, UP)
|
||||
output_words = output_brace.get_text("1d output")
|
||||
input_words.highlight(input_array.get_color())
|
||||
output_words.highlight(output_array.get_color())
|
||||
|
||||
|
||||
self.add(func, input_array)
|
||||
self.play(
|
||||
GrowFromCenter(input_brace),
|
||||
Write(input_words)
|
||||
)
|
||||
mover = input_array.copy()
|
||||
self.play(
|
||||
Transform(mover, Dot().move_to(func)),
|
||||
ShowCreation(in_arrow),
|
||||
rate_func = rush_into,
|
||||
run_time = 0.5
|
||||
)
|
||||
self.play(
|
||||
Transform(mover, output_array),
|
||||
ShowCreation(out_arrow),
|
||||
rate_func = rush_from,
|
||||
run_time = 0.5
|
||||
)
|
||||
self.play(
|
||||
GrowFromCenter(output_brace),
|
||||
Write(output_words)
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class TwoDTo1DTransform(LinearTransformationScene):
|
||||
CONFIG = {
|
||||
"include_background_plane" : False,
|
||||
"foreground_plane_kwargs" : {
|
||||
"x_radius" : SPACE_WIDTH,
|
||||
"y_radius" : SPACE_HEIGHT,
|
||||
"secondary_line_ratio" : 1
|
||||
},
|
||||
"t_matrix" : [[1, 0], [2, 0]],
|
||||
}
|
||||
def construct(self):
|
||||
line = NumberLine()
|
||||
plane_words = TextMobject("2d space")
|
||||
plane_words.next_to(self.j_hat, UP, buff = MED_BUFF)
|
||||
plane_words.add_background_rectangle()
|
||||
line_words = TextMobject("1d space (number line)")
|
||||
line_words.next_to(line, UP)
|
||||
|
||||
|
||||
self.play(Write(plane_words))
|
||||
self.dither()
|
||||
self.remove(plane_words)
|
||||
mobjects = self.get_mobjects()
|
||||
self.play(
|
||||
*map(FadeOut, mobjects) + [ShowCreation(line)]
|
||||
)
|
||||
self.play(Write(line_words))
|
||||
self.dither()
|
||||
self.remove(line_words)
|
||||
self.play(*map(FadeIn, mobjects))
|
||||
self.apply_transposed_matrix(self.t_matrix)
|
||||
self.play(Write(VMobject(*line.get_number_mobjects())))
|
||||
self.dither()
|
||||
self.show_matrix()
|
||||
|
||||
def show_matrix(self):
|
||||
for vect, char in zip([self.i_hat, self.j_hat], ["i", "j"]):
|
||||
vect.words = TextMobject(
|
||||
"$\\hat\\%smath$ lands on"%char,
|
||||
str(int(vect.get_end()[0]))
|
||||
)
|
||||
direction = UP if vect is self.i_hat else DOWN
|
||||
vect.words.next_to(vect.get_end(), direction, buff = LARGE_BUFF)
|
||||
vect.words.highlight(vect.get_color())
|
||||
matrix = Matrix([[1, 2]])
|
||||
matrix_words = TextMobject("Transformation matrix: ")
|
||||
matrix_group = VMobject(matrix_words, matrix)
|
||||
matrix_group.arrange_submobjects(buff = MED_BUFF)
|
||||
matrix_group.to_edge(UP)
|
||||
entries = matrix.get_entries()
|
||||
|
||||
self.play(Write(matrix_words), Write(matrix.get_brackets()))
|
||||
for i, vect in enumerate([self.i_hat, self.j_hat]):
|
||||
self.play(vect.rotate, np.pi/12, rate_func = wiggle)
|
||||
self.play(Write(vect.words))
|
||||
self.dither()
|
||||
self.play(vect.words[1].copy().move_to, entries[i])
|
||||
self.dither()
|
||||
|
||||
class TwoDTo1DTransformWithDots(TwoDTo1DTransform):
|
||||
def construct(self):
|
||||
line = NumberLine()
|
||||
self.add(line, *self.get_mobjects())
|
||||
offset = LEFT+DOWN
|
||||
vect = 2*RIGHT+UP
|
||||
dots = VMobject(*[
|
||||
Dot(offset + a*vect, radius = 0.075)
|
||||
for a in np.linspace(-2, 3, 18)
|
||||
])
|
||||
dots.submobject_gradient_highlight(YELLOW_B, YELLOW_C)
|
||||
func = self.get_matrix_transformation(self.t_matrix)
|
||||
new_dots = VMobject(*[
|
||||
Dot(
|
||||
func(dot.get_center()),
|
||||
color = dot.get_color(),
|
||||
radius = dot.radius
|
||||
)
|
||||
for dot in dots
|
||||
])
|
||||
|
||||
self.play(Write(dots))
|
||||
self.apply_transposed_matrix(
|
||||
self.t_matrix,
|
||||
added_anims = [Transform(dots, new_dots)]
|
||||
)
|
||||
self.dither()
|
||||
|
||||
class NextVideo(Scene):
|
||||
def construct(self):
|
||||
title = TextMobject("""
|
||||
Next video: Dot products and duality
|
||||
""")
|
||||
title.scale_to_fit_width(2*SPACE_WIDTH - 2)
|
||||
title.to_edge(UP)
|
||||
rect = Rectangle(width = 16, height = 9, color = BLUE)
|
||||
rect.scale_to_fit_height(6)
|
||||
rect.next_to(title, DOWN)
|
||||
|
||||
self.add(title)
|
||||
self.play(ShowCreation(rect))
|
||||
self.dither()
|
||||
|
||||
class DotProductPreview(VectorScene):
|
||||
CONFIG = {
|
||||
"v_coords" : [3, 1],
|
||||
"w_coords" : [2, -1],
|
||||
"v_color" : YELLOW,
|
||||
"w_color" : MAROON_C,
|
||||
|
||||
}
|
||||
def construct(self):
|
||||
self.lock_in_faded_grid()
|
||||
self.add_symbols()
|
||||
self.add_vectors()
|
||||
self.grow_number_line()
|
||||
self.project_w()
|
||||
self.show_scaling()
|
||||
|
||||
|
||||
def add_symbols(self):
|
||||
v = matrix_to_mobject(self.v_coords).highlight(self.v_color)
|
||||
w = matrix_to_mobject(self.w_coords).highlight(self.w_color)
|
||||
v.add_background_rectangle()
|
||||
w.add_background_rectangle()
|
||||
dot = TexMobject("\\cdot")
|
||||
eq = VMobject(v, dot, w)
|
||||
eq.arrange_submobjects(RIGHT, buff = SMALL_BUFF)
|
||||
eq.to_corner(UP+LEFT)
|
||||
self.play(Write(eq), run_time = 1)
|
||||
|
||||
def add_vectors(self):
|
||||
self.v = Vector(self.v_coords, color = self.v_color)
|
||||
self.w = Vector(self.w_coords, color = self.w_color)
|
||||
self.play(ShowCreation(self.v))
|
||||
self.play(ShowCreation(self.w))
|
||||
|
||||
def grow_number_line(self):
|
||||
line = NumberLine(stroke_width = 2).add_numbers()
|
||||
line.rotate(self.v.get_angle())
|
||||
self.play(Write(line), Animation(self.v))
|
||||
self.play(
|
||||
line.highlight, self.v.get_color(),
|
||||
Animation(self.v),
|
||||
rate_func = there_and_back
|
||||
)
|
||||
self.dither()
|
||||
|
||||
def project_w(self):
|
||||
dot_product = np.dot(self.v.get_end(), self.w.get_end())
|
||||
v_norm, w_norm = [
|
||||
np.linalg.norm(vect.get_end())
|
||||
for vect in self.v, self.w
|
||||
]
|
||||
projected_w = Vector(
|
||||
self.v.get_end()*dot_product/(v_norm**2),
|
||||
color = self.w.get_color()
|
||||
)
|
||||
projection_line = Line(
|
||||
self.w.get_end(), projected_w.get_end(),
|
||||
color = GREY
|
||||
)
|
||||
|
||||
self.play(ShowCreation(projection_line))
|
||||
self.add(self.w.copy().fade())
|
||||
self.play(Transform(self.w, projected_w))
|
||||
self.dither()
|
||||
|
||||
def show_scaling(self):
|
||||
dot_product = np.dot(self.v.get_end(), self.w.get_end())
|
||||
start_brace, interim_brace, final_brace = braces = [
|
||||
Brace(
|
||||
Line(ORIGIN, norm*RIGHT),
|
||||
UP
|
||||
)
|
||||
for norm in 1, self.v.get_length(), dot_product
|
||||
]
|
||||
length_texs = list(it.starmap(TexMobject, [
|
||||
("1",),
|
||||
("\\text{Scale by }", "||\\vec{\\textbf{v}}||",),
|
||||
("\\text{Length of}", "\\text{ scaled projection}",),
|
||||
]))
|
||||
length_texs[1][1].highlight(self.v_color)
|
||||
length_texs[2][1].highlight(self.w_color)
|
||||
for brace, tex_mob in zip(braces, length_texs):
|
||||
tex_mob.add_background_rectangle()
|
||||
brace.put_at_tip(tex_mob, buff = SMALL_BUFF)
|
||||
brace.add(tex_mob)
|
||||
brace.rotate(self.v.get_angle())
|
||||
new_w = self.w.copy().scale(self.v.get_length())
|
||||
|
||||
self.play(Write(start_brace))
|
||||
self.dither()
|
||||
self.play(
|
||||
Transform(start_brace, interim_brace),
|
||||
Transform(self.w, new_w)
|
||||
)
|
||||
self.dither()
|
||||
self.play(
|
||||
Transform(start_brace, final_brace)
|
||||
)
|
||||
self.dither()
|
||||
|
||||
|
||||
@ -92,3 +648,10 @@ class ColumnsRepresentBasisVectors(Scene):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -90,12 +90,14 @@ class VectorScene(Scene):
|
||||
def get_vector_label(self, vector, label,
|
||||
direction = "left",
|
||||
rotate = False,
|
||||
color = WHITE,
|
||||
color = None,
|
||||
label_scale_factor = VECTOR_LABEL_SCALE_FACTOR):
|
||||
if not isinstance(label, TexMobject):
|
||||
if len(label) == 1:
|
||||
label = "\\vec{\\textbf{%s}}"%label
|
||||
label = TexMobject(label)
|
||||
if color is None:
|
||||
color = vector.get_color()
|
||||
label.highlight(color)
|
||||
label.scale(label_scale_factor)
|
||||
label.add_background_rectangle()
|
||||
@ -257,7 +259,7 @@ class LinearTransformationScene(VectorScene):
|
||||
"i_hat_color" : X_COLOR,
|
||||
"j_hat_color" : Y_COLOR,
|
||||
"leave_ghost_vectors" : False,
|
||||
"t_matrix" : np.array([[3, 0], [1, 2]]),
|
||||
"t_matrix" : [[3, 0], [1, 2]],
|
||||
}
|
||||
def setup(self):
|
||||
if hasattr(self, "has_setup"):
|
||||
|
@ -294,6 +294,22 @@ class ThoughtBubble(Bubble):
|
||||
return self
|
||||
|
||||
|
||||
class RandolphScene(Scene):
|
||||
CONFIG = {
|
||||
"randy_mode" : "plain"
|
||||
}
|
||||
def setup(self):
|
||||
self.randy = Randolph(mode = self.randy_mode)
|
||||
self.randy.to_corner()
|
||||
self.add(self.randy)
|
||||
|
||||
def dither(self, blink = True):
|
||||
if blink:
|
||||
self.play(Blink(self.randy))
|
||||
else:
|
||||
Scene.dither(self)
|
||||
return self
|
||||
|
||||
class TeacherStudentsScene(Scene):
|
||||
def setup(self):
|
||||
self.teacher = Mortimer()
|
||||
|
@ -13,7 +13,7 @@ class NumberLine(VMobject):
|
||||
"x_max" : SPACE_WIDTH,
|
||||
"space_unit_to_num" : 1,
|
||||
"tick_size" : 0.1,
|
||||
"tick_frequency" : 0.5,
|
||||
"tick_frequency" : 1,
|
||||
"leftmost_tick" : None, #Defaults to ceil(x_min)
|
||||
"numbers_with_elongated_ticks" : [0],
|
||||
"longer_tick_multiple" : 2,
|
||||
@ -63,7 +63,7 @@ class NumberLine(VMobject):
|
||||
return self.x_min + dist_from_left
|
||||
|
||||
def default_numbers_to_display(self):
|
||||
return self.get_tick_numbers()[::2]
|
||||
return np.arange(self.leftmost_tick, self.x_max, 1)
|
||||
|
||||
def get_vertical_number_offset(self, direction = DOWN):
|
||||
return 4*direction*self.tick_size
|
||||
@ -75,7 +75,7 @@ class NumberLine(VMobject):
|
||||
result = []
|
||||
for number in numbers:
|
||||
mob = TexMobject(str(int(number)))
|
||||
mob.scale_to_fit_height(2*self.tick_size)
|
||||
mob.scale_to_fit_height(3*self.tick_size)
|
||||
mob.shift(
|
||||
self.number_to_point(number),
|
||||
self.get_vertical_number_offset(**kwargs)
|
||||
@ -128,7 +128,6 @@ class NumberPlane(VMobject):
|
||||
"written_coordinate_nudge" : 0.1*(DOWN+RIGHT),
|
||||
"num_pair_at_center" : (0, 0),
|
||||
"propogate_style_to_family" : False,
|
||||
"submobject_partial_creation_mode" : "smoothed_lagged_start",
|
||||
}
|
||||
|
||||
def generate_points(self):
|
||||
|
Reference in New Issue
Block a user