mirror of
https://github.com/3b1b/manim.git
synced 2025-07-30 05:24:22 +08:00
Beginning eola chapter 1
This commit is contained in:
@ -132,6 +132,9 @@ COLOR_MAP = {
|
|||||||
"GREY" : "#888888",
|
"GREY" : "#888888",
|
||||||
"DARK_GREY" : "#444444",
|
"DARK_GREY" : "#444444",
|
||||||
"DARK_GRAY" : "#444444",
|
"DARK_GRAY" : "#444444",
|
||||||
|
"GREY_BROWN" : "#736357",
|
||||||
|
"PINK" : "#D147BD",
|
||||||
|
"GREEN_SCREEN": "#00FF00",
|
||||||
}
|
}
|
||||||
PALETTE = COLOR_MAP.values()
|
PALETTE = COLOR_MAP.values()
|
||||||
globals().update(COLOR_MAP)
|
globals().update(COLOR_MAP)
|
||||||
|
125
eola/chapter0.py
125
eola/chapter0.py
@ -23,6 +23,29 @@ from eola.utils import *
|
|||||||
EXAMPLE_TRANFORM = [[0, 1], [-1, 1]]
|
EXAMPLE_TRANFORM = [[0, 1], [-1, 1]]
|
||||||
TRANFORMED_VECTOR = [[1], [2]]
|
TRANFORMED_VECTOR = [[1], [2]]
|
||||||
|
|
||||||
|
def matrix_multiplication():
|
||||||
|
return TexMobject("""
|
||||||
|
\\left[
|
||||||
|
\\begin{array}{cc}
|
||||||
|
a & b \\\\
|
||||||
|
c & d
|
||||||
|
\\end{array}
|
||||||
|
\\right]
|
||||||
|
\\left[
|
||||||
|
\\begin{array}{cc}
|
||||||
|
e & f \\\\
|
||||||
|
g & h
|
||||||
|
\\end{array}
|
||||||
|
\\right]
|
||||||
|
=
|
||||||
|
\\left[
|
||||||
|
\\begin{array}{cc}
|
||||||
|
ae + bg & af + bh \\\\
|
||||||
|
ce + dg & cf + dh
|
||||||
|
\\end{array}
|
||||||
|
\\right]
|
||||||
|
""")
|
||||||
|
|
||||||
class OpeningQuote(Scene):
|
class OpeningQuote(Scene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
words = TextMobject(
|
words = TextMobject(
|
||||||
@ -173,27 +196,7 @@ class AboutLinearAlgebra(Scene):
|
|||||||
|
|
||||||
|
|
||||||
def get_matrix_multiplication(self):
|
def get_matrix_multiplication(self):
|
||||||
return TexMobject("""
|
return matrix_multiplication()
|
||||||
\\left[
|
|
||||||
\\begin{array}{cc}
|
|
||||||
a & b \\\\
|
|
||||||
c & d
|
|
||||||
\\end{array}
|
|
||||||
\\right]
|
|
||||||
\\left[
|
|
||||||
\\begin{array}{cc}
|
|
||||||
e & f \\\\
|
|
||||||
g & h
|
|
||||||
\\end{array}
|
|
||||||
\\right]
|
|
||||||
=
|
|
||||||
\\left[
|
|
||||||
\\begin{array}{cc}
|
|
||||||
ae + bg & af + bh \\\\
|
|
||||||
ce + dg & cf + dh
|
|
||||||
\\end{array}
|
|
||||||
\\right]
|
|
||||||
""")
|
|
||||||
|
|
||||||
def get_determinant(self):
|
def get_determinant(self):
|
||||||
return TexMobject("""
|
return TexMobject("""
|
||||||
@ -447,22 +450,38 @@ class LinAlgPyramid(Scene):
|
|||||||
self.dither()
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
class IndimidatingProf(Scene):
|
class IntimidatingProf(Scene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
randy = Randolph().to_corner()
|
randy = Randolph().to_corner()
|
||||||
morty = Mortimer().to_corner(DOWN+RIGHT)
|
morty = Mortimer().to_corner(DOWN+RIGHT)
|
||||||
morty.shift(3*LEFT)
|
morty.shift(3*LEFT)
|
||||||
|
morty_name1 = TextMobject("Professor")
|
||||||
|
morty_name2 = TextMobject("Coworker")
|
||||||
|
for name in morty_name1, morty_name2:
|
||||||
|
name.to_edge(RIGHT)
|
||||||
|
name.shift(2*UP)
|
||||||
|
arrow = Arrow(morty_name1.get_bottom(), morty)
|
||||||
speech_bubble = SpeechBubble(height = 3).flip()
|
speech_bubble = SpeechBubble(height = 3).flip()
|
||||||
speech_bubble.pin_to(morty)
|
speech_bubble.pin_to(morty)
|
||||||
speech_bubble.shift(RIGHT)
|
speech_bubble.shift(RIGHT)
|
||||||
speech_bubble.write("And of course $B^{-1}AB$ will \\\\ also have positive eigenvalues...")
|
speech_bubble.write("And of course $B^{-1}AB$ will \\\\ also have positive eigenvalues...")
|
||||||
thought_bubble = ThoughtBubble(width = 4, height = 4)
|
thought_bubble = ThoughtBubble(width = 6, height = 5)
|
||||||
thought_bubble.next_to(morty, UP)
|
thought_bubble.next_to(morty, UP)
|
||||||
thought_bubble.to_edge(RIGHT)
|
thought_bubble.to_edge(RIGHT, buff = -1)
|
||||||
|
thought_bubble.make_green_screen()
|
||||||
q_marks = TextMobject("???")
|
q_marks = TextMobject("???")
|
||||||
q_marks.next_to(randy, UP)
|
q_marks.next_to(randy, UP)
|
||||||
|
randy_bubble = randy.get_bubble()
|
||||||
|
randy_bubble.add_content(matrix_multiplication())
|
||||||
|
|
||||||
self.add(randy, morty)
|
self.add(randy, morty)
|
||||||
|
self.play(
|
||||||
|
FadeIn(morty_name1),
|
||||||
|
ShowCreation(arrow, submobject_mode = "one_at_a_time")
|
||||||
|
)
|
||||||
|
self.play(Transform(morty_name1, morty_name2))
|
||||||
|
self.dither()
|
||||||
|
self.play(FadeOut(morty_name1), FadeOut(arrow))
|
||||||
self.play(
|
self.play(
|
||||||
FadeIn(speech_bubble),
|
FadeIn(speech_bubble),
|
||||||
ApplyMethod(morty.change_mode, "speaking")
|
ApplyMethod(morty.change_mode, "speaking")
|
||||||
@ -473,6 +492,8 @@ class IndimidatingProf(Scene):
|
|||||||
ApplyMethod(randy.change_mode, "confused"),
|
ApplyMethod(randy.change_mode, "confused"),
|
||||||
Write(q_marks, run_time = 1)
|
Write(q_marks, run_time = 1)
|
||||||
)
|
)
|
||||||
|
self.play(FadeOut(VMobject(speech_bubble, thought_bubble)))
|
||||||
|
self.play(FadeIn(randy_bubble))
|
||||||
self.dither()
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
@ -605,10 +626,10 @@ class PhysicsExample(Scene):
|
|||||||
v_label = TexMobject("\\vec{v}")
|
v_label = TexMobject("\\vec{v}")
|
||||||
v_label.shift(p1 + RIGHT*vector[0]/4 + UP*vector[1]/2)
|
v_label.shift(p1 + RIGHT*vector[0]/4 + UP*vector[1]/2)
|
||||||
v_label.highlight(v_mob.get_color())
|
v_label.highlight(v_mob.get_color())
|
||||||
vx_label = TexMobject("\\vec{v} \\cos(\\theta)")
|
vx_label = TexMobject("||\\vec{v}|| \\cos(\\theta)")
|
||||||
vx_label.next_to(vx, UP)
|
vx_label.next_to(vx, UP)
|
||||||
vx_label.highlight(vx.get_color())
|
vx_label.highlight(vx.get_color())
|
||||||
vy_label = TexMobject("\\vec{v} \\sin(\\theta)")
|
vy_label = TexMobject("||\\vec{v}|| \\sin(\\theta)")
|
||||||
vy_label.next_to(vy, RIGHT)
|
vy_label.next_to(vy, RIGHT)
|
||||||
vy_label.highlight(vy.get_color())
|
vy_label.highlight(vy.get_color())
|
||||||
|
|
||||||
@ -782,6 +803,7 @@ class ProfessorsTry(Scene):
|
|||||||
thought_bubble = ThoughtBubble(width = 4, height = 3.5)
|
thought_bubble = ThoughtBubble(width = 4, height = 3.5)
|
||||||
thought_bubble.next_to(morty, UP)
|
thought_bubble.next_to(morty, UP)
|
||||||
thought_bubble.to_edge(RIGHT)
|
thought_bubble.to_edge(RIGHT)
|
||||||
|
thought_bubble.make_green_screen()
|
||||||
randy = Randolph()
|
randy = Randolph()
|
||||||
randy.scale(0.8)
|
randy.scale(0.8)
|
||||||
randy.to_corner()
|
randy.to_corner()
|
||||||
@ -793,7 +815,7 @@ class ProfessorsTry(Scene):
|
|||||||
FadeIn(words)
|
FadeIn(words)
|
||||||
)
|
)
|
||||||
self.play(Blink(randy))
|
self.play(Blink(randy))
|
||||||
self.play(FadeIn(thought_bubble ))
|
self.play(FadeIn(thought_bubble))
|
||||||
self.play(Blink(morty))
|
self.play(Blink(morty))
|
||||||
|
|
||||||
|
|
||||||
@ -890,6 +912,8 @@ class TableOfContents(Scene):
|
|||||||
ShowCreation(bubble),
|
ShowCreation(bubble),
|
||||||
Transform(icons, new_icons)
|
Transform(icons, new_icons)
|
||||||
)
|
)
|
||||||
|
self.remove(icons)
|
||||||
|
bubble.make_green_screen()
|
||||||
self.dither()
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
@ -915,6 +939,53 @@ class ResourceForTeachers(Scene):
|
|||||||
self.play(Blink(randy))
|
self.play(Blink(randy))
|
||||||
self.dither()
|
self.dither()
|
||||||
|
|
||||||
|
class AboutPacing(Scene):
|
||||||
|
def construct(self):
|
||||||
|
words = TextMobject("About pacing...")
|
||||||
|
dots = words.split()[-3:]
|
||||||
|
words.remove(*dots)
|
||||||
|
self.play(FadeIn(words))
|
||||||
|
self.play(Write(VMobject(*dots)))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
class DifferingBackgrounds(Scene):
|
||||||
|
def construct(self):
|
||||||
|
words = map(TextMobject, [
|
||||||
|
"Just brushing up",
|
||||||
|
"Has yet to take the course",
|
||||||
|
"Supplementing course concurrently",
|
||||||
|
])
|
||||||
|
students = VMobject(*[
|
||||||
|
Randolph(color = c)
|
||||||
|
for c in BLUE_D, BLUE_C, BLUE_E
|
||||||
|
])
|
||||||
|
modes = ["pondering", "speaking_looking_left", "sassy"]
|
||||||
|
students.arrange_submobjects(RIGHT)
|
||||||
|
students.scale(0.8)
|
||||||
|
students.center().to_edge(DOWN)
|
||||||
|
|
||||||
|
last_word, last_arrow = None, None
|
||||||
|
for word, student, mode in zip(words, students.split(), modes):
|
||||||
|
word.shift(2*UP)
|
||||||
|
arrow = Arrow(word, student)
|
||||||
|
if last_word:
|
||||||
|
word_anim = Transform(last_word, word)
|
||||||
|
arrow_anim = Transform(last_arrow, arrow)
|
||||||
|
else:
|
||||||
|
word_anim = Write(word, run_time = 1)
|
||||||
|
arrow_anim = ShowCreation(arrow, submobject_mode = "one_at_a_time")
|
||||||
|
last_word = word
|
||||||
|
last_arrow = arrow
|
||||||
|
self.play(
|
||||||
|
word_anim, arrow_anim,
|
||||||
|
ApplyMethod(student.change_mode, mode)
|
||||||
|
)
|
||||||
|
self.play(Blink(student))
|
||||||
|
self.dither()
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PauseAndPonder(Scene):
|
class PauseAndPonder(Scene):
|
||||||
def construct(self):
|
def construct(self):
|
||||||
pause = TexMobject("=").rotate(np.pi/2)
|
pause = TexMobject("=").rotate(np.pi/2)
|
||||||
|
149
eola/chapter1.py
Normal file
149
eola/chapter1.py
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
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 animation.playground import *
|
||||||
|
from topics.geometry import *
|
||||||
|
from topics.characters import *
|
||||||
|
from topics.functions import *
|
||||||
|
from topics.number_line import *
|
||||||
|
from topics.combinatorics 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.utils import *
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
class Physicist(PiCreature):
|
||||||
|
CONFIG = {
|
||||||
|
"color" : PINK,
|
||||||
|
}
|
||||||
|
|
||||||
|
class ComputerScientist(PiCreature):
|
||||||
|
CONFIG = {
|
||||||
|
"color" : PURPLE_E,
|
||||||
|
"flip_at_start" : True,
|
||||||
|
}
|
||||||
|
|
||||||
|
class OpeningQuote(Scene):
|
||||||
|
def construct(self):
|
||||||
|
words = TextMobject(
|
||||||
|
"``The introduction of numbers as \\\\ coordinates is an act of violence.''",
|
||||||
|
)
|
||||||
|
words.to_edge(UP)
|
||||||
|
for mob in words.submobjects[27:27+11]:
|
||||||
|
mob.highlight(GREEN)
|
||||||
|
author = TextMobject("-Hermann Weyl")
|
||||||
|
author.highlight(YELLOW)
|
||||||
|
author.next_to(words, DOWN, buff = 0.5)
|
||||||
|
|
||||||
|
self.play(FadeIn(words))
|
||||||
|
self.dither(1)
|
||||||
|
self.play(Write(author, run_time = 4))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
class IntroVector(Scene):
|
||||||
|
def construct(self):
|
||||||
|
plane = NumberPlane()
|
||||||
|
labels = plane.get_coordinate_labels()
|
||||||
|
vector = Vector(RIGHT+2*UP, color = YELLOW)
|
||||||
|
coordinates = vector_coordinate_label(vector)
|
||||||
|
|
||||||
|
self.play(ShowCreation(
|
||||||
|
plane,
|
||||||
|
submobject_mode = "lagged_start",
|
||||||
|
run_time = 3
|
||||||
|
))
|
||||||
|
self.play(ShowCreation(
|
||||||
|
vector,
|
||||||
|
submobject_mode = "one_at_a_time"
|
||||||
|
))
|
||||||
|
self.play(Write(VMobject(*labels)), Write(coordinates))
|
||||||
|
self.dither()
|
||||||
|
|
||||||
|
|
||||||
|
class DifferentConceptions(Scene):
|
||||||
|
def construct(self):
|
||||||
|
physy = Physicist()
|
||||||
|
mathy = Mathematician(mode = "pondering")
|
||||||
|
compy = ComputerScientist()
|
||||||
|
people = [physy, compy, mathy]
|
||||||
|
physy.name = TextMobject("Physics student").to_corner(DOWN+LEFT)
|
||||||
|
compy.name = TextMobject("CS student").to_corner(DOWN+RIGHT)
|
||||||
|
mathy.name = TextMobject("Mathematician").to_edge(DOWN)
|
||||||
|
names = VMobject(physy.name, mathy.name, compy.name)
|
||||||
|
names.arrange_submobjects(RIGHT, buff = 1)
|
||||||
|
names.to_corner(DOWN+LEFT)
|
||||||
|
for pi in people:
|
||||||
|
pi.next_to(pi.name, UP)
|
||||||
|
self.add(pi)
|
||||||
|
|
||||||
|
for pi in people:
|
||||||
|
self.play(Write(pi.name), run_time = 1)
|
||||||
|
self.preview_conceptions(people)
|
||||||
|
self.physics_conception(people)
|
||||||
|
self.cs_conception(people)
|
||||||
|
self.handle_mathy(people)
|
||||||
|
|
||||||
|
|
||||||
|
def preview_conceptions(self, people):
|
||||||
|
arrow = Vector(2*RIGHT+ UP)
|
||||||
|
array = matrix_to_mobject([[2], [1]])
|
||||||
|
tex = TextMobject("""
|
||||||
|
Set $V$ with operations \\\\
|
||||||
|
$a : V \\times V \\to V$ and \\\\
|
||||||
|
$s : \\mathds{R} \\times V \\to V$ such that...
|
||||||
|
""")
|
||||||
|
physy, compy, mathy = people
|
||||||
|
physy.bubble = physy.get_bubble("speech")
|
||||||
|
compy.bubble = compy.get_bubble("speech")
|
||||||
|
mathy.bubble = mathy.get_bubble(width = 4)
|
||||||
|
|
||||||
|
for pi, sym in zip(people, [arrow, array, tex]):
|
||||||
|
pi.bubble.set_fill(BLACK, opacity = 1.0)
|
||||||
|
pi.bubble.add_content(sym)
|
||||||
|
self.play(FadeIn(pi.bubble))
|
||||||
|
self.dither()
|
||||||
|
for pi in people:
|
||||||
|
self.remove(pi.bubble)
|
||||||
|
|
||||||
|
|
||||||
|
def physics_conception(self, people):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def cs_conception(self, people):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def handle_mathy(self, people):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -10,9 +10,10 @@ from animation.simple_animations import ShowCreation
|
|||||||
from topics.number_line import NumberPlane
|
from topics.number_line import NumberPlane
|
||||||
from topics.geometry import Vector, Line, Circle
|
from topics.geometry import Vector, Line, Circle
|
||||||
|
|
||||||
|
|
||||||
from helpers import *
|
from helpers import *
|
||||||
|
|
||||||
|
VECTOR_LABEL_SCALE_VAL = 0.7
|
||||||
|
|
||||||
def matrix_to_tex_string(matrix):
|
def matrix_to_tex_string(matrix):
|
||||||
matrix = np.array(matrix).astype("string")
|
matrix = np.array(matrix).astype("string")
|
||||||
n_rows, n_cols = matrix.shape
|
n_rows, n_cols = matrix.shape
|
||||||
@ -28,6 +29,24 @@ def matrix_to_tex_string(matrix):
|
|||||||
def matrix_to_mobject(matrix):
|
def matrix_to_mobject(matrix):
|
||||||
return TexMobject(matrix_to_tex_string(matrix))
|
return TexMobject(matrix_to_tex_string(matrix))
|
||||||
|
|
||||||
|
def vector_coordinate_label(vector_mob, integer_labels = True, n_dim = 2):
|
||||||
|
vect = np.array(vector_mob.get_end())
|
||||||
|
if integer_labels:
|
||||||
|
vect = vect.astype(int)
|
||||||
|
vect = vect[:n_dim]
|
||||||
|
vect = vect.reshape((n_dim, 1))
|
||||||
|
label = matrix_to_mobject(vect)
|
||||||
|
label.scale(VECTOR_LABEL_SCALE_VAL)
|
||||||
|
|
||||||
|
shift_dir = np.array(vector_mob.get_end())
|
||||||
|
if shift_dir[0] > 0: #Pointing right
|
||||||
|
shift_dir -= label.get_left() + DEFAULT_MOBJECT_TO_MOBJECT_BUFFER*LEFT
|
||||||
|
else: #Pointing left
|
||||||
|
shift_dir -= label.get_right() + DEFAULT_MOBJECT_TO_MOBJECT_BUFFER*RIGHT
|
||||||
|
label.shift(shift_dir)
|
||||||
|
return label
|
||||||
|
|
||||||
|
|
||||||
class LinearTransformationScene(Scene):
|
class LinearTransformationScene(Scene):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"include_background_plane" : True,
|
"include_background_plane" : True,
|
||||||
|
@ -125,7 +125,7 @@ class Randolph(PiCreature):
|
|||||||
|
|
||||||
class Mortimer(PiCreature):
|
class Mortimer(PiCreature):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"color" : "#736357",
|
"color" : GREY_BROWN,
|
||||||
"flip_at_start" : True,
|
"flip_at_start" : True,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,4 +233,13 @@ class ThoughtBubble(Bubble):
|
|||||||
lambda m1, m2 : int((m1.get_bottom()-m2.get_bottom())[1])
|
lambda m1, m2 : int((m1.get_bottom()-m2.get_bottom())[1])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def make_green_screen(self):
|
||||||
|
self.submobjects[-1].set_fill(GREEN_SCREEN, opacity = 1)
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ class Arrow(Line):
|
|||||||
|
|
||||||
class Vector(Arrow):
|
class Vector(Arrow):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"color" : WHITE,
|
"color" : YELLOW,
|
||||||
"buff" : 0,
|
"buff" : 0,
|
||||||
}
|
}
|
||||||
def __init__(self, direction, **kwargs):
|
def __init__(self, direction, **kwargs):
|
||||||
|
Reference in New Issue
Block a user