mirror of
https://github.com/3b1b/manim.git
synced 2025-08-20 05:14:12 +00:00
A nice small commit capturing one atomic change, as usual
This commit is contained in:
parent
15731dc9a2
commit
25efbbf0b0
9 changed files with 499 additions and 62 deletions
|
@ -123,6 +123,7 @@ class FadeIn(Transform):
|
||||||
mobject.fade(1)
|
mobject.fade(1)
|
||||||
if isinstance(mobject, VMobject):
|
if isinstance(mobject, VMobject):
|
||||||
mobject.set_stroke(width = 0)
|
mobject.set_stroke(width = 0)
|
||||||
|
mobject.set_fill(opacity = 0)
|
||||||
Transform.__init__(self, mobject, target, **kwargs)
|
Transform.__init__(self, mobject, target, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -780,7 +780,7 @@ class Symbolic2To1DTransform(Scene):
|
||||||
class RecommendChapter3(Scene):
|
class RecommendChapter3(Scene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
title = TextMobject("""
|
title = TextMobject("""
|
||||||
Definite watch Chapter 3
|
Definitely watch Chapter 3
|
||||||
if you haven't already
|
if you haven't already
|
||||||
""")
|
""")
|
||||||
title.to_edge(UP)
|
title.to_edge(UP)
|
||||||
|
@ -2316,7 +2316,56 @@ class NextVideo(Scene):
|
||||||
self.play(ShowCreation(rect))
|
self.play(ShowCreation(rect))
|
||||||
self.dither()
|
self.dither()
|
||||||
|
|
||||||
|
class CrossAndDualWords(Scene):
|
||||||
|
def construct(self):
|
||||||
|
from eola.chapter5 import get_det_text
|
||||||
|
|
||||||
|
v_tex, u_tex, w_tex = [
|
||||||
|
"\\vec{\\textbf{%s}}"%s
|
||||||
|
for s in "vuw"
|
||||||
|
]
|
||||||
|
vector_word = TextMobject("Vector:")
|
||||||
|
transform_word = TextMobject("Dual transform:")
|
||||||
|
|
||||||
|
cross = TexMobject(
|
||||||
|
v_tex, "=", u_tex, "\\times", w_tex
|
||||||
|
)
|
||||||
|
for tex, color in zip([v_tex, u_tex, w_tex], [V_COLOR, U_COLOR, W_COLOR]):
|
||||||
|
cross.highlight_by_tex(tex, color)
|
||||||
|
input_array_tex = matrix_to_tex_string(["x", "y", "z"])
|
||||||
|
func = TexMobject("L\\left(%s\\right) = "%input_array_tex)
|
||||||
|
matrix = Matrix(np.array([
|
||||||
|
["x", "y", "z"],
|
||||||
|
["u_1", "u_2", "u_3"],
|
||||||
|
["w_1", "w_2", "w_3"],
|
||||||
|
]).T)
|
||||||
|
matrix.highlight_columns(WHITE, U_COLOR, W_COLOR)
|
||||||
|
det_text = get_det_text(matrix)
|
||||||
|
det_text.add(matrix)
|
||||||
|
dot_with_cross = TexMobject(
|
||||||
|
"%s \\cdot ("%input_array_tex,
|
||||||
|
u_tex, "\\times", w_tex, ")"
|
||||||
|
)
|
||||||
|
dot_with_cross.highlight_by_tex(u_tex, U_COLOR)
|
||||||
|
dot_with_cross.highlight_by_tex(w_tex, W_COLOR)
|
||||||
|
transform = Group(func, det_text)
|
||||||
|
transform.arrange_submobjects()
|
||||||
|
|
||||||
|
Group(transform, dot_with_cross).scale(0.7)
|
||||||
|
vector_word.to_corner(UP+LEFT)
|
||||||
|
transform_word.next_to(vector_word, DOWN, buff = MED_BUFF, aligned_edge = LEFT)
|
||||||
|
cross.next_to(vector_word, buff = MED_BUFF)
|
||||||
|
transform.next_to(transform_word, DOWN, buff = MED_BUFF, aligned_edge = LEFT)
|
||||||
|
dot_with_cross.next_to(func, RIGHT)
|
||||||
|
|
||||||
|
self.add(vector_word)
|
||||||
|
self.play(Write(cross))
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeIn(transform_word))
|
||||||
|
self.play(Write(transform))
|
||||||
|
self.dither()
|
||||||
|
self.play(Transform(det_text, dot_with_cross))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
458
eola/chapter8.py
458
eola/chapter8.py
|
@ -22,66 +22,454 @@ from eola.two_d_space import *
|
||||||
from eola.chapter5 import get_det_text
|
from eola.chapter5 import get_det_text
|
||||||
|
|
||||||
|
|
||||||
V_COLOR = RED
|
|
||||||
U_COLOR = ORANGE
|
U_COLOR = ORANGE
|
||||||
|
V_COLOR = YELLOW
|
||||||
W_COLOR = MAROON_B
|
W_COLOR = MAROON_B
|
||||||
|
|
||||||
class OpeningQuote(Scene):
|
class OpeningQuote(Scene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
words = TextMobject(
|
words = TextMobject(
|
||||||
"To ask the",
|
"From [Grothendieck], I have also learned not"
|
||||||
"right question\\\\",
|
"to take glory in the ",
|
||||||
"is harder than to answer it."
|
"difficulty of a proof:",
|
||||||
|
"difficulty means we have not understood."
|
||||||
|
"The idea is to be able to",
|
||||||
|
"paint a landscape",
|
||||||
|
"in which the proof is obvious.",
|
||||||
|
arg_separator = " "
|
||||||
)
|
)
|
||||||
|
words.highlight_by_tex("difficulty of a proof:", RED)
|
||||||
|
words.highlight_by_tex("paint a landscape", GREEN)
|
||||||
|
words.scale_to_fit_width(2*SPACE_WIDTH - 2)
|
||||||
words.to_edge(UP)
|
words.to_edge(UP)
|
||||||
words[1].highlight(BLUE)
|
author = TextMobject("-Pierre Deligne")
|
||||||
author = TextMobject("-Georg Cantor")
|
|
||||||
author.highlight(YELLOW)
|
author.highlight(YELLOW)
|
||||||
author.next_to(words, DOWN, buff = 0.5)
|
author.next_to(words, DOWN, buff = 0.5)
|
||||||
|
|
||||||
self.play(FadeIn(words))
|
self.play(FadeIn(words))
|
||||||
self.dither(2)
|
self.dither(4)
|
||||||
self.play(Write(author, run_time = 3))
|
self.play(Write(author, run_time = 3))
|
||||||
self.dither()
|
self.dither()
|
||||||
|
|
||||||
class CrossAndDualWords(Scene):
|
class DoTheSameForCross(TeacherStudentsScene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
v_tex, u_tex, w_tex = [
|
words = TextMobject("Let's do the same \\\\ for", "cross products")
|
||||||
"\\vec{\\textbf{%s}}"%s
|
words.highlight_by_tex("cross products", YELLOW)
|
||||||
for s in "vuw"
|
self.teacher_says(words, pi_creature_target_mode = "surprised")
|
||||||
|
self.random_blink(2)
|
||||||
|
self.change_student_modes("pondering")
|
||||||
|
self.random_blink()
|
||||||
|
|
||||||
|
class ListSteps(RandolphScene):
|
||||||
|
CONFIG = {
|
||||||
|
"randy_corner" : DOWN+RIGHT
|
||||||
|
}
|
||||||
|
def construct(self):
|
||||||
|
title = TextMobject("Two parts")
|
||||||
|
title.highlight(YELLOW)
|
||||||
|
title.to_edge(UP)
|
||||||
|
h_line = Line(LEFT, RIGHT).scale(SPACE_WIDTH)
|
||||||
|
h_line.next_to(title, DOWN)
|
||||||
|
|
||||||
|
step_1 = TextMobject("1. Standard introduction")
|
||||||
|
step_2 = TextMobject("2. Deeper understanding with ", "linear transformations")
|
||||||
|
step_2.highlight_by_tex("linear transformations", BLUE)
|
||||||
|
steps = Group(step_1, step_2)
|
||||||
|
steps.arrange_submobjects(DOWN, aligned_edge = LEFT, buff = LARGE_BUFF)
|
||||||
|
steps.next_to(self.randy, UP)
|
||||||
|
steps.to_edge(LEFT)
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
FadeIn(step_1),
|
||||||
|
self.randy.change_mode, "happy"
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
Write(step_2),
|
||||||
|
self.randy.change_mode, "pondering"
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
class ContrastDotAndCross(Scene):
|
||||||
|
def construct(self):
|
||||||
|
self.add_t_chart()
|
||||||
|
self.add_dot_products()
|
||||||
|
self.add_cross_product()
|
||||||
|
self.add_2d_cross_product()
|
||||||
|
self.emphasize_output_type()
|
||||||
|
|
||||||
|
def add_t_chart(self):
|
||||||
|
for word, vect, color in ("Dot", LEFT, BLUE_C), ("Cross", RIGHT, YELLOW):
|
||||||
|
title = TextMobject("%s product"%word)
|
||||||
|
title.shift(vect*SPACE_WIDTH/2)
|
||||||
|
title.to_edge(UP)
|
||||||
|
title.highlight(color)
|
||||||
|
self.add(title)
|
||||||
|
v_line = Line(UP, DOWN).scale(SPACE_HEIGHT)
|
||||||
|
l_h_line = Line(LEFT, ORIGIN).scale(SPACE_WIDTH)
|
||||||
|
r_h_line = Line(ORIGIN, RIGHT).scale(SPACE_WIDTH)
|
||||||
|
r_h_line.next_to(title, DOWN)
|
||||||
|
l_h_line.next_to(r_h_line, LEFT, buff = 0)
|
||||||
|
self.add(v_line, l_h_line, r_h_line)
|
||||||
|
self.l_h_line, self.r_h_line = l_h_line, r_h_line
|
||||||
|
|
||||||
|
def add_dot_products(self, max_width = SPACE_WIDTH-1, dims = [2, 5]):
|
||||||
|
colors = [X_COLOR, Y_COLOR, Z_COLOR, MAROON_B, TEAL]
|
||||||
|
last_mob = self.l_h_line
|
||||||
|
for dim in dims:
|
||||||
|
arrays = [
|
||||||
|
[random.randint(0, 9) for in_count in range(dim)]
|
||||||
|
for out_count in range(2)
|
||||||
|
]
|
||||||
|
m1, m2 = map(Matrix, arrays)
|
||||||
|
for matrix in m1, m2:
|
||||||
|
for entry, color in zip(matrix.get_entries(), colors):
|
||||||
|
entry.highlight(color)
|
||||||
|
syms = map(TexMobject, ["="] + ["+"]*(dim-1))
|
||||||
|
result = Group(*it.chain(*zip(
|
||||||
|
syms,
|
||||||
|
[
|
||||||
|
Group(
|
||||||
|
e1, TexMobject("\\cdot"), e2
|
||||||
|
).arrange_submobjects()
|
||||||
|
for e1, e2 in zip(*[m.copy().get_entries() for m in m1, m2])
|
||||||
|
]
|
||||||
|
)))
|
||||||
|
result.arrange_submobjects(RIGHT)
|
||||||
|
dot_prod = Group(
|
||||||
|
m1, TexMobject("\\cdot"), m2, result
|
||||||
|
)
|
||||||
|
dot_prod.arrange_submobjects(RIGHT)
|
||||||
|
if dot_prod.get_width() > max_width:
|
||||||
|
dot_prod.scale_to_fit_width(max_width)
|
||||||
|
dot_prod.next_to(last_mob, DOWN, buff = MED_BUFF)
|
||||||
|
last_mob = dot_prod
|
||||||
|
dot_prod.to_edge(LEFT)
|
||||||
|
self.play(Write(dot_prod))
|
||||||
|
|
||||||
|
def add_cross_product(self):
|
||||||
|
colors = [X_COLOR, Y_COLOR, Z_COLOR]
|
||||||
|
|
||||||
|
arrays = [
|
||||||
|
[random.randint(0, 9) for in_count in range(3)]
|
||||||
|
for out_count in range(2)
|
||||||
]
|
]
|
||||||
vector_word = TextMobject("Vector:")
|
matrices = map(Matrix, arrays)
|
||||||
transform_word = TextMobject("Dual transform:")
|
for matrix in matrices:
|
||||||
|
for entry, color in zip(matrix.get_entries(), colors):
|
||||||
|
entry.highlight(color)
|
||||||
|
m1, m2 = matrices
|
||||||
|
cross_product = Group(m1, TexMobject("\\times"), m2)
|
||||||
|
cross_product.arrange_submobjects()
|
||||||
|
|
||||||
cross = TexMobject(
|
index_to_cross_enty = {}
|
||||||
v_tex, "=", u_tex, "\\times", w_tex
|
syms = Group()
|
||||||
|
movement_sets = []
|
||||||
|
for a, b, c in it.permutations(range(3)):
|
||||||
|
e1, e2 = m1.get_entries()[b], m2.get_entries()[c]
|
||||||
|
for e in e1, e2:
|
||||||
|
e.target = e.copy()
|
||||||
|
movement_sets.append([e1, e1.target, e2, e2.target])
|
||||||
|
dot = TexMobject("\\cdot")
|
||||||
|
syms.add(dot)
|
||||||
|
cross_entry = Group(e1.target, dot, e2.target)
|
||||||
|
cross_entry.arrange_submobjects()
|
||||||
|
if a not in index_to_cross_enty:
|
||||||
|
index_to_cross_enty[a] = []
|
||||||
|
index_to_cross_enty[a].append(cross_entry)
|
||||||
|
result_entries = []
|
||||||
|
for a in range(3):
|
||||||
|
prod1, prod2 = index_to_cross_enty[a]
|
||||||
|
if a == 1:
|
||||||
|
prod1, prod2 = prod2, prod1
|
||||||
|
prod2.arrange_submobjects(LEFT)
|
||||||
|
minus = TexMobject("-")
|
||||||
|
syms.add(minus)
|
||||||
|
entry = Group(prod1, minus, prod2)
|
||||||
|
entry.arrange_submobjects(RIGHT)
|
||||||
|
result_entries.append(entry)
|
||||||
|
|
||||||
|
result = Matrix(result_entries)
|
||||||
|
full_cross_product = Group(
|
||||||
|
cross_product, TexMobject("="), result
|
||||||
)
|
)
|
||||||
for tex, color in zip([v_tex, u_tex, w_tex], [V_COLOR, U_COLOR, W_COLOR]):
|
full_cross_product.arrange_submobjects()
|
||||||
cross.highlight_by_tex(tex, color)
|
full_cross_product.scale(0.75)
|
||||||
input_array_tex = matrix_to_tex_string(["x", "y", "z"])
|
full_cross_product.next_to(self.r_h_line, DOWN, buff = MED_BUFF/2)
|
||||||
func = TexMobject("f\\left(%s\\right) = "%input_array_tex)
|
full_cross_product.remove(result)
|
||||||
|
self.play(
|
||||||
|
Write(full_cross_product),
|
||||||
|
Write(syms)
|
||||||
|
)
|
||||||
|
movements = []
|
||||||
|
for e1, e1_target, e2, e2_target in movement_sets:
|
||||||
|
movements += [
|
||||||
|
e1.copy().move_to, e1_target,
|
||||||
|
e2.copy().move_to, e2_target,
|
||||||
|
]
|
||||||
|
self.play(
|
||||||
|
Write(result.get_brackets()),
|
||||||
|
*movements,
|
||||||
|
run_time = 2
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
brace = Brace(cross_product)
|
||||||
|
brace_text = brace.get_text("Only 3d")
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(brace),
|
||||||
|
Write(brace_text)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.cross_result = result
|
||||||
|
self.only_3d_text = brace_text
|
||||||
|
|
||||||
|
def add_2d_cross_product(self):
|
||||||
|
h_line = DashedLine(ORIGIN, SPACE_WIDTH*RIGHT)
|
||||||
|
h_line.next_to(self.only_3d_text, DOWN, buff = MED_BUFF/2)
|
||||||
|
h_line.to_edge(RIGHT, buff = 0)
|
||||||
|
arrays = np.random.randint(0, 9, (2, 2))
|
||||||
|
m1, m2 = matrices = map(Matrix, arrays)
|
||||||
|
for m in matrices:
|
||||||
|
for e, color in zip(m.get_entries(), [X_COLOR, Y_COLOR]):
|
||||||
|
e.highlight(color)
|
||||||
|
cross_product = Group(m1, TexMobject("\\times"), m2)
|
||||||
|
cross_product.arrange_submobjects()
|
||||||
|
(x1, x2), (x3, x4) = tuple(m1.get_entries()), tuple(m2.get_entries())
|
||||||
|
entries = [x1, x2, x3, x4]
|
||||||
|
for entry in entries:
|
||||||
|
entry.target = entry.copy()
|
||||||
|
eq, dot1, minus, dot2 = syms = map(TexMobject,
|
||||||
|
["=", "\\cdot", "-", "\\cdot"]
|
||||||
|
)
|
||||||
|
result = Group(
|
||||||
|
eq, x1.target, dot1, x4.target,
|
||||||
|
minus, x3.target, dot2, x2.target,
|
||||||
|
)
|
||||||
|
result.arrange_submobjects(RIGHT)
|
||||||
|
full_cross_product = Group(cross_product, result)
|
||||||
|
full_cross_product.arrange_submobjects(RIGHT)
|
||||||
|
full_cross_product.next_to(h_line, DOWN, buff = MED_BUFF/2)
|
||||||
|
|
||||||
|
self.play(ShowCreation(h_line))
|
||||||
|
self.play(Write(cross_product))
|
||||||
|
self.play(
|
||||||
|
Write(Group(*syms)),
|
||||||
|
*[
|
||||||
|
Transform(entry.copy(), entry.target)
|
||||||
|
for entry in entries
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.two_d_result = Group(*result[1:])
|
||||||
|
|
||||||
|
def emphasize_output_type(self):
|
||||||
|
three_d_brace = Brace(self.cross_result)
|
||||||
|
two_d_brace = Brace(self.two_d_result)
|
||||||
|
vector = three_d_brace.get_text("Vector")
|
||||||
|
number = two_d_brace.get_text("Number")
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(three_d_brace),
|
||||||
|
Write(vector)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(two_d_brace),
|
||||||
|
Write(number)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
class PrereqDeterminant(Scene):
|
||||||
|
def construct(self):
|
||||||
|
title = TextMobject("""
|
||||||
|
Prerequisite: Understanding determinants
|
||||||
|
""")
|
||||||
|
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 Define2dCrossProduct(LinearTransformationScene):
|
||||||
|
CONFIG = {
|
||||||
|
"show_basis_vectors" : False,
|
||||||
|
"v_coords" : [3, 1],
|
||||||
|
"w_coords" : [2, -1],
|
||||||
|
}
|
||||||
|
def construct(self):
|
||||||
|
self.initial_definition()
|
||||||
|
self.show_transformation()
|
||||||
|
self.transform_square()
|
||||||
|
self.show_orientation_rule()
|
||||||
|
|
||||||
|
|
||||||
|
def initial_definition(self):
|
||||||
|
self.plane.save_state()
|
||||||
|
self.plane.fade()
|
||||||
|
v = self.add_vector(self.v_coords, color = V_COLOR)
|
||||||
|
w = self.add_vector(self.w_coords, color = W_COLOR)
|
||||||
|
self.moving_vectors.remove(v)
|
||||||
|
self.moving_vectors.remove(w)
|
||||||
|
for vect, name in (v, "v"), (w, "w"):
|
||||||
|
color = vect.get_color()
|
||||||
|
vect.label = self.label_vector(vect, name, color = color)
|
||||||
|
vect.coord_array = self.write_vector_coordinates(
|
||||||
|
vect, color = color
|
||||||
|
)
|
||||||
|
vect.coords = vect.coord_array.get_entries()
|
||||||
|
movers = [v.label, w.label, v.coords, w.coords]
|
||||||
|
for mover in movers:
|
||||||
|
mover.target = mover.copy()
|
||||||
|
times = TexMobject("\\times")
|
||||||
|
cross_product = Group(
|
||||||
|
v.label.target, times, w.label.target
|
||||||
|
)
|
||||||
|
|
||||||
|
cross_product.arrange_submobjects()
|
||||||
matrix = Matrix(np.array([
|
matrix = Matrix(np.array([
|
||||||
["x", "y", "z"],
|
list(v.coords.target),
|
||||||
["u_1", "u_2", "u_3"],
|
list(w.coords.target)
|
||||||
["w_1", "w_2", "w_3"],
|
|
||||||
]).T)
|
]).T)
|
||||||
matrix.highlight_columns(WHITE, U_COLOR, W_COLOR)
|
|
||||||
det_text = get_det_text(matrix)
|
det_text = get_det_text(matrix)
|
||||||
det_text.add(matrix)
|
full_det = Group(det_text, matrix)
|
||||||
equals_dot = TexMobject(
|
equals = TexMobject("=")
|
||||||
"= %s \\cdot"%input_array_tex, v_tex
|
equation = Group(cross_product, equals, full_det)
|
||||||
|
equation.arrange_submobjects()
|
||||||
|
equation.to_corner(UP+LEFT)
|
||||||
|
|
||||||
|
matrix_background = BackgroundRectangle(matrix)
|
||||||
|
cross_background = BackgroundRectangle(cross_product)
|
||||||
|
|
||||||
|
disclaimer = TextMobject("$^*$ See ``Note on conventions'' in description")
|
||||||
|
disclaimer.scale(0.7)
|
||||||
|
disclaimer.highlight(RED)
|
||||||
|
disclaimer.next_to(
|
||||||
|
det_text.get_corner(UP+RIGHT), RIGHT, buff = 0
|
||||||
)
|
)
|
||||||
equals_dot.highlight_by_tex(v_tex, V_COLOR)
|
disclaimer.add_background_rectangle()
|
||||||
transform = Group(func, det_text)
|
|
||||||
transform.arrange_submobjects()
|
self.play(
|
||||||
|
FadeIn(cross_background),
|
||||||
|
Transform(v.label.copy(), v.label.target),
|
||||||
|
Transform(w.label.copy(), w.label.target),
|
||||||
|
Write(times),
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(Transform(v.coords.copy(), v.coords.target))
|
||||||
|
self.play(Transform(w.coords.copy(), w.coords.target))
|
||||||
|
self.play(
|
||||||
|
ShowCreation(matrix_background),
|
||||||
|
Write(matrix.get_brackets()),
|
||||||
|
Animation(matrix.get_entries()),
|
||||||
|
run_time = 1
|
||||||
|
)
|
||||||
|
matrix.add_to_back(matrix_background)
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
Write(equals),
|
||||||
|
Write(det_text),
|
||||||
|
Animation(matrix),
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeIn(disclaimer))
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeOut(disclaimer))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
self.matrix = matrix
|
||||||
|
self.det_text = det_text
|
||||||
|
|
||||||
|
def show_transformation(self):
|
||||||
|
matrix = self.matrix
|
||||||
|
everything = self.get_mobjects()
|
||||||
|
everything.remove(self.plane)
|
||||||
|
everything.remove(self.background_plane)
|
||||||
|
everything.remove(matrix)
|
||||||
|
self.play(
|
||||||
|
*map(FadeOut, everything) + [
|
||||||
|
Animation(self.background_plane),
|
||||||
|
self.plane.restore,
|
||||||
|
Animation(matrix),
|
||||||
|
])
|
||||||
|
side_brace = Brace(matrix, RIGHT)
|
||||||
|
transform_words = side_brace.get_text("Linear transformation")
|
||||||
|
transform_words.add_background_rectangle()
|
||||||
|
|
||||||
|
col1, col2 = [
|
||||||
|
Group(*matrix.get_mob_matrix()[:,i])
|
||||||
|
for i in 0, 1
|
||||||
|
]
|
||||||
|
|
||||||
|
both_words = []
|
||||||
|
for char, color, col in ("i", X_COLOR, col1), ("j", Y_COLOR, col2):
|
||||||
|
words = TextMobject("Where $\\hat\\%smath$ lands"%char)
|
||||||
|
words.highlight(color)
|
||||||
|
words.add_background_rectangle()
|
||||||
|
words.next_to(col, DOWN, buff = LARGE_BUFF)
|
||||||
|
words.arrow = Arrow(words.get_top(), col.get_bottom(), color = color)
|
||||||
|
both_words.append(words)
|
||||||
|
i_words, j_words = both_words
|
||||||
|
|
||||||
|
self.play(
|
||||||
|
GrowFromCenter(side_brace),
|
||||||
|
Write(transform_words)
|
||||||
|
)
|
||||||
|
self.play(
|
||||||
|
Write(i_words),
|
||||||
|
ShowCreation(i_words.arrow),
|
||||||
|
col1.highlight, X_COLOR
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(
|
||||||
|
Transform(i_words, j_words),
|
||||||
|
Transform(i_words.arrow, j_words.arrow),
|
||||||
|
col2.highlight, Y_COLOR
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(*map(FadeOut, [i_words, i_words.arrow]))
|
||||||
|
|
||||||
|
i_hat, j_hat = self.get_basis_vectors()
|
||||||
|
basis_labels = self.get_basis_vector_labels()
|
||||||
|
self.play(
|
||||||
|
ShowCreation(i_hat),
|
||||||
|
ShowCreation(j_hat),
|
||||||
|
Write(basis_labels)
|
||||||
|
)
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeOut(basis_labels))
|
||||||
|
self.add_vector(i_hat)
|
||||||
|
self.add_vector(j_hat)
|
||||||
|
self.play(*map(FadeOut, [side_brace, transform_words]))
|
||||||
|
self.add_foreground_mobject(matrix)
|
||||||
|
self.apply_transposed_matrix([self.v_coords, self.w_coords])
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
|
def transform_square(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def show_orientation_rule(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vector_word.next_to(transform_word, UP, buff = LARGE_BUFF, aligned_edge = LEFT)
|
|
||||||
cross.next_to(vector_word, buff = MED_BUFF)
|
|
||||||
transform.next_to(transform_word, buff = MED_BUFF)
|
|
||||||
equals_dot.next_to(det_text, DOWN, aligned_edge = LEFT)
|
|
||||||
|
|
||||||
self.add_mobjects_among(locals().values())
|
|
||||||
self.show_frame()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import numpy as np
|
||||||
|
|
||||||
from scene import Scene
|
from scene import Scene
|
||||||
from mobject import Mobject
|
from mobject import Mobject
|
||||||
from mobject.vectorized_mobject import VMobject
|
from mobject.vectorized_mobject import VMobject, Group
|
||||||
from mobject.tex_mobject import TexMobject, TextMobject
|
from mobject.tex_mobject import TexMobject, TextMobject
|
||||||
from animation import Animation
|
from animation import Animation
|
||||||
from animation.transform import ApplyPointwiseFunction, Transform, \
|
from animation.transform import ApplyPointwiseFunction, Transform, \
|
||||||
|
@ -75,7 +75,7 @@ class VectorScene(Scene):
|
||||||
|
|
||||||
def get_basis_vector_labels(self, **kwargs):
|
def get_basis_vector_labels(self, **kwargs):
|
||||||
i_hat, j_hat = self.get_basis_vectors()
|
i_hat, j_hat = self.get_basis_vectors()
|
||||||
return [
|
return Group(*[
|
||||||
self.get_vector_label(
|
self.get_vector_label(
|
||||||
vect, label, color = color,
|
vect, label, color = color,
|
||||||
label_scale_factor = 1,
|
label_scale_factor = 1,
|
||||||
|
@ -85,7 +85,7 @@ class VectorScene(Scene):
|
||||||
(i_hat, "\\hat{\\imath}", X_COLOR),
|
(i_hat, "\\hat{\\imath}", X_COLOR),
|
||||||
(j_hat, "\\hat{\\jmath}", Y_COLOR),
|
(j_hat, "\\hat{\\jmath}", Y_COLOR),
|
||||||
]
|
]
|
||||||
]
|
])
|
||||||
|
|
||||||
def get_vector_label(self, vector, label,
|
def get_vector_label(self, vector, label,
|
||||||
direction = "left",
|
direction = "left",
|
||||||
|
|
|
@ -79,7 +79,8 @@ def get_configuration(sys_argv):
|
||||||
#By default, write to file
|
#By default, write to file
|
||||||
actions = ["write", "preview", "save_image"]
|
actions = ["write", "preview", "save_image"]
|
||||||
if not any([config[key] for key in actions]):
|
if not any([config[key] for key in actions]):
|
||||||
config["write"] = True
|
config["write"] = True
|
||||||
|
config["skip_animations"] = config["save_image"] and not config["write"]
|
||||||
|
|
||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
print HELP_MESSAGE
|
print HELP_MESSAGE
|
||||||
|
@ -197,7 +198,8 @@ def main():
|
||||||
)
|
)
|
||||||
config["movie_prefix"] = config["file"].replace(".py", "")
|
config["movie_prefix"] = config["file"].replace(".py", "")
|
||||||
scene_kwargs = {
|
scene_kwargs = {
|
||||||
"camera_config" : config["camera_config"]
|
"camera_config" : config["camera_config"],
|
||||||
|
"skip_animations" : config["skip_animations"],
|
||||||
}
|
}
|
||||||
for SceneClass in get_scene_classes(scene_names_to_classes, config):
|
for SceneClass in get_scene_classes(scene_names_to_classes, config):
|
||||||
for args in get_scene_args(SceneClass, config):
|
for args in get_scene_args(SceneClass, config):
|
||||||
|
|
|
@ -20,9 +20,10 @@ from animation.transform import ApplyMethod
|
||||||
|
|
||||||
class Scene(object):
|
class Scene(object):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"camera_config" : {},
|
"camera_config" : {},
|
||||||
"frame_duration" : DEFAULT_FRAME_DURATION,
|
"frame_duration" : DEFAULT_FRAME_DURATION,
|
||||||
"construct_args" : [],
|
"construct_args" : [],
|
||||||
|
"skip_animations" : False,
|
||||||
}
|
}
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
digest_config(self, kwargs)
|
digest_config(self, kwargs)
|
||||||
|
@ -214,6 +215,9 @@ class Scene(object):
|
||||||
def play(self, *args, **kwargs):
|
def play(self, *args, **kwargs):
|
||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
raise Exception("Called Scene.play with no animations")
|
raise Exception("Called Scene.play with no animations")
|
||||||
|
if self.skip_animations:
|
||||||
|
kwargs["run_time"] = 0
|
||||||
|
|
||||||
animations = self.compile_play_args_to_animation_list(*args)
|
animations = self.compile_play_args_to_animation_list(*args)
|
||||||
self.num_plays += 1
|
self.num_plays += 1
|
||||||
|
|
||||||
|
@ -274,6 +278,8 @@ class Scene(object):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def dither(self, duration = DEFAULT_DITHER_TIME):
|
def dither(self, duration = DEFAULT_DITHER_TIME):
|
||||||
|
if self.skip_animations:
|
||||||
|
return self
|
||||||
self.update_frame()
|
self.update_frame()
|
||||||
self.frames += [self.get_frame()]*int(duration / self.frame_duration)
|
self.frames += [self.get_frame()]*int(duration / self.frame_duration)
|
||||||
return self
|
return self
|
||||||
|
|
|
@ -296,11 +296,14 @@ class ThoughtBubble(Bubble):
|
||||||
|
|
||||||
class RandolphScene(Scene):
|
class RandolphScene(Scene):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"randy_mode" : "plain"
|
"randy_kwargs" : {},
|
||||||
|
"randy_corner" : DOWN+LEFT
|
||||||
}
|
}
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self.randy = Randolph(mode = self.randy_mode)
|
self.randy = Randolph(**self.randy_kwargs)
|
||||||
self.randy.to_corner()
|
self.randy.to_corner(self.randy_corner)
|
||||||
|
if self.randy_corner[0] > 0:
|
||||||
|
self.randy.flip()
|
||||||
self.add(self.randy)
|
self.add(self.randy)
|
||||||
|
|
||||||
def dither(self, time = 1, blink = True):
|
def dither(self, time = 1, blink = True):
|
||||||
|
|
|
@ -313,28 +313,16 @@ class BackgroundRectangle(Rectangle):
|
||||||
"fill_opacity" : 0.75,
|
"fill_opacity" : 0.75,
|
||||||
}
|
}
|
||||||
def __init__(self, mobject, **kwargs):
|
def __init__(self, mobject, **kwargs):
|
||||||
self.lock_style = False
|
|
||||||
Rectangle.__init__(self, **kwargs)
|
Rectangle.__init__(self, **kwargs)
|
||||||
self.lock_style = True
|
|
||||||
self.replace(mobject, stretch = True)
|
self.replace(mobject, stretch = True)
|
||||||
self.original_fill_opacity = self.fill_opacity
|
self.original_fill_opacity = self.fill_opacity
|
||||||
|
|
||||||
def pointwise_become_partial(self, mobject, a, b):
|
def pointwise_become_partial(self, mobject, a, b):
|
||||||
self.lock_style = False
|
|
||||||
self.set_fill(opacity = b*self.original_fill_opacity)
|
self.set_fill(opacity = b*self.original_fill_opacity)
|
||||||
self.lock_style = True
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def fade_to(self, *args, **kwargs):
|
def get_fill_color(self):
|
||||||
self.lock_style = False
|
return Color(self.color)
|
||||||
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
|
|
||||||
return Rectangle.set_style_data(self, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class Grid(VMobject):
|
class Grid(VMobject):
|
||||||
|
|
Loading…
Add table
Reference in a new issue