mirror of
https://github.com/3b1b/manim.git
synced 2025-07-29 21:12:35 +08:00
Beginning eola chapter 1
This commit is contained in:
@ -132,6 +132,9 @@ COLOR_MAP = {
|
||||
"GREY" : "#888888",
|
||||
"DARK_GREY" : "#444444",
|
||||
"DARK_GRAY" : "#444444",
|
||||
"GREY_BROWN" : "#736357",
|
||||
"PINK" : "#D147BD",
|
||||
"GREEN_SCREEN": "#00FF00",
|
||||
}
|
||||
PALETTE = COLOR_MAP.values()
|
||||
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]]
|
||||
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):
|
||||
def construct(self):
|
||||
words = TextMobject(
|
||||
@ -173,27 +196,7 @@ class AboutLinearAlgebra(Scene):
|
||||
|
||||
|
||||
def get_matrix_multiplication(self):
|
||||
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]
|
||||
""")
|
||||
return matrix_multiplication()
|
||||
|
||||
def get_determinant(self):
|
||||
return TexMobject("""
|
||||
@ -447,22 +450,38 @@ class LinAlgPyramid(Scene):
|
||||
self.dither()
|
||||
|
||||
|
||||
class IndimidatingProf(Scene):
|
||||
class IntimidatingProf(Scene):
|
||||
def construct(self):
|
||||
randy = Randolph().to_corner()
|
||||
morty = Mortimer().to_corner(DOWN+RIGHT)
|
||||
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.pin_to(morty)
|
||||
speech_bubble.shift(RIGHT)
|
||||
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.to_edge(RIGHT)
|
||||
thought_bubble.to_edge(RIGHT, buff = -1)
|
||||
thought_bubble.make_green_screen()
|
||||
q_marks = TextMobject("???")
|
||||
q_marks.next_to(randy, UP)
|
||||
randy_bubble = randy.get_bubble()
|
||||
randy_bubble.add_content(matrix_multiplication())
|
||||
|
||||
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(
|
||||
FadeIn(speech_bubble),
|
||||
ApplyMethod(morty.change_mode, "speaking")
|
||||
@ -473,6 +492,8 @@ class IndimidatingProf(Scene):
|
||||
ApplyMethod(randy.change_mode, "confused"),
|
||||
Write(q_marks, run_time = 1)
|
||||
)
|
||||
self.play(FadeOut(VMobject(speech_bubble, thought_bubble)))
|
||||
self.play(FadeIn(randy_bubble))
|
||||
self.dither()
|
||||
|
||||
|
||||
@ -605,10 +626,10 @@ class PhysicsExample(Scene):
|
||||
v_label = TexMobject("\\vec{v}")
|
||||
v_label.shift(p1 + RIGHT*vector[0]/4 + UP*vector[1]/2)
|
||||
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.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.highlight(vy.get_color())
|
||||
|
||||
@ -782,6 +803,7 @@ class ProfessorsTry(Scene):
|
||||
thought_bubble = ThoughtBubble(width = 4, height = 3.5)
|
||||
thought_bubble.next_to(morty, UP)
|
||||
thought_bubble.to_edge(RIGHT)
|
||||
thought_bubble.make_green_screen()
|
||||
randy = Randolph()
|
||||
randy.scale(0.8)
|
||||
randy.to_corner()
|
||||
@ -793,7 +815,7 @@ class ProfessorsTry(Scene):
|
||||
FadeIn(words)
|
||||
)
|
||||
self.play(Blink(randy))
|
||||
self.play(FadeIn(thought_bubble ))
|
||||
self.play(FadeIn(thought_bubble))
|
||||
self.play(Blink(morty))
|
||||
|
||||
|
||||
@ -890,6 +912,8 @@ class TableOfContents(Scene):
|
||||
ShowCreation(bubble),
|
||||
Transform(icons, new_icons)
|
||||
)
|
||||
self.remove(icons)
|
||||
bubble.make_green_screen()
|
||||
self.dither()
|
||||
|
||||
|
||||
@ -915,6 +939,53 @@ class ResourceForTeachers(Scene):
|
||||
self.play(Blink(randy))
|
||||
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):
|
||||
def construct(self):
|
||||
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.geometry import Vector, Line, Circle
|
||||
|
||||
|
||||
from helpers import *
|
||||
|
||||
VECTOR_LABEL_SCALE_VAL = 0.7
|
||||
|
||||
def matrix_to_tex_string(matrix):
|
||||
matrix = np.array(matrix).astype("string")
|
||||
n_rows, n_cols = matrix.shape
|
||||
@ -28,6 +29,24 @@ def matrix_to_tex_string(matrix):
|
||||
def matrix_to_mobject(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):
|
||||
CONFIG = {
|
||||
"include_background_plane" : True,
|
||||
|
@ -125,7 +125,7 @@ class Randolph(PiCreature):
|
||||
|
||||
class Mortimer(PiCreature):
|
||||
CONFIG = {
|
||||
"color" : "#736357",
|
||||
"color" : GREY_BROWN,
|
||||
"flip_at_start" : True,
|
||||
}
|
||||
|
||||
@ -233,4 +233,13 @@ class ThoughtBubble(Bubble):
|
||||
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):
|
||||
CONFIG = {
|
||||
"color" : WHITE,
|
||||
"color" : YELLOW,
|
||||
"buff" : 0,
|
||||
}
|
||||
def __init__(self, direction, **kwargs):
|
||||
|
Reference in New Issue
Block a user