mirror of
https://github.com/3b1b/manim.git
synced 2025-04-13 09:47:07 +00:00
Finished with preliminary chapter 2 animations
This commit is contained in:
parent
3ab6b8579e
commit
93acd48fe9
8 changed files with 992 additions and 80 deletions
|
@ -92,14 +92,19 @@ class ApplyMethod(Transform):
|
||||||
**kwargs
|
**kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
class FadeOut(ApplyMethod):
|
class FadeOut(Transform):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"remover" : True,
|
"remover" : True,
|
||||||
}
|
}
|
||||||
def __init__(self, mobject, **kwargs):
|
def __init__(self, mobject, **kwargs):
|
||||||
ApplyMethod.__init__(self, mobject.fade, 1, **kwargs)
|
target = mobject.copy()
|
||||||
|
target.fade(1)
|
||||||
|
if isinstance(mobject, VMobject):
|
||||||
|
target.set_stroke(width = 0)
|
||||||
|
target.set_fill(opacity = 0)
|
||||||
|
Transform.__init__(self, mobject, target, **kwargs)
|
||||||
|
|
||||||
def cleanup(self):
|
def clean_up(self):
|
||||||
self.update(0)
|
self.update(0)
|
||||||
|
|
||||||
class FadeIn(Transform):
|
class FadeIn(Transform):
|
||||||
|
|
|
@ -25,6 +25,12 @@ from eola.chapter0 import UpcomingSeriesOfVidoes
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
def plane_wave_homotopy(x, y, z, t):
|
||||||
|
norm = np.linalg.norm([x, y])
|
||||||
|
tau = interpolate(5, -5, t) + norm/SPACE_WIDTH
|
||||||
|
alpha = sigmoid(tau)
|
||||||
|
return [x, y + 0.5*np.sin(2*np.pi*alpha), z]
|
||||||
|
|
||||||
class Physicist(PiCreature):
|
class Physicist(PiCreature):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"color" : PINK,
|
"color" : PINK,
|
||||||
|
@ -319,7 +325,7 @@ class DifferentConceptions(Scene):
|
||||||
v_array, TexMobject("+"), w_array, TexMobject("="), sum_array
|
v_array, TexMobject("+"), w_array, TexMobject("="), sum_array
|
||||||
)
|
)
|
||||||
arrays.arrange_submobjects(RIGHT)
|
arrays.arrange_submobjects(RIGHT)
|
||||||
arrays.scale(0.5)
|
arrays.scale(0.75)
|
||||||
arrays.to_edge(RIGHT).shift(UP)
|
arrays.to_edge(RIGHT).shift(UP)
|
||||||
|
|
||||||
v_sym = TexMobject("\\vec{\\textbf{v}}")
|
v_sym = TexMobject("\\vec{\\textbf{v}}")
|
||||||
|
@ -331,8 +337,7 @@ class DifferentConceptions(Scene):
|
||||||
statement = TextMobject("We'll ignore him \\\\ for now")
|
statement = TextMobject("We'll ignore him \\\\ for now")
|
||||||
statement.highlight(PINK)
|
statement.highlight(PINK)
|
||||||
statement.scale_to_fit_width(arrays.get_width())
|
statement.scale_to_fit_width(arrays.get_width())
|
||||||
statement.next_to(arrays, DOWN, buff = 2)
|
statement.next_to(arrays, DOWN, buff = 1.5)
|
||||||
arrow_to_mathy = Arrow(statement, mathy, color = PINK, buff = 0)
|
|
||||||
circle = Circle()
|
circle = Circle()
|
||||||
circle.shift(syms.get_bottom())
|
circle.shift(syms.get_bottom())
|
||||||
|
|
||||||
|
@ -349,7 +354,6 @@ class DifferentConceptions(Scene):
|
||||||
self.play(Blink(mathy))
|
self.play(Blink(mathy))
|
||||||
self.add_scaling(arrows, syms, arrays)
|
self.add_scaling(arrows, syms, arrays)
|
||||||
self.play(Write(statement))
|
self.play(Write(statement))
|
||||||
self.play(ShowCreation(arrow_to_mathy, submobject_mode = "one_at_a_time"))
|
|
||||||
self.play(ApplyMethod(mathy.change_mode, "sad"))
|
self.play(ApplyMethod(mathy.change_mode, "sad"))
|
||||||
self.dither()
|
self.dither()
|
||||||
self.play(
|
self.play(
|
||||||
|
@ -375,7 +379,7 @@ class DifferentConceptions(Scene):
|
||||||
matrix_to_mobject(["2(3)", "2(-5)"])
|
matrix_to_mobject(["2(3)", "2(-5)"])
|
||||||
)
|
)
|
||||||
s_arrays.arrange_submobjects(RIGHT)
|
s_arrays.arrange_submobjects(RIGHT)
|
||||||
s_arrays.scale(0.5)
|
s_arrays.scale(0.75)
|
||||||
s_arrays.next_to(arrays, DOWN)
|
s_arrays.next_to(arrays, DOWN)
|
||||||
|
|
||||||
s_syms = TexMobject(["2", "\\vec{\\textbf{v}}"])
|
s_syms = TexMobject(["2", "\\vec{\\textbf{v}}"])
|
||||||
|
@ -797,7 +801,7 @@ class VectorAdditionNumerically(VectorScene):
|
||||||
x_axis, y_axis = axes.split()
|
x_axis, y_axis = axes.split()
|
||||||
|
|
||||||
v1 = self.add_vector([1, 2])
|
v1 = self.add_vector([1, 2])
|
||||||
coords1, x_line1, y_line1 = self.vector_to_coords(v1, cleanup = False)
|
coords1, x_line1, y_line1 = self.vector_to_coords(v1, clean_up = False)
|
||||||
self.play(ApplyFunction(
|
self.play(ApplyFunction(
|
||||||
lambda m : m.next_to(y_axis, RIGHT).to_edge(UP),
|
lambda m : m.next_to(y_axis, RIGHT).to_edge(UP),
|
||||||
coords1
|
coords1
|
||||||
|
@ -805,7 +809,7 @@ class VectorAdditionNumerically(VectorScene):
|
||||||
plus.next_to(coords1, RIGHT)
|
plus.next_to(coords1, RIGHT)
|
||||||
|
|
||||||
v2 = self.add_vector([3, -1], color = MAROON_B)
|
v2 = self.add_vector([3, -1], color = MAROON_B)
|
||||||
coords2, x_line2, y_line2 = self.vector_to_coords(v2, cleanup = False)
|
coords2, x_line2, y_line2 = self.vector_to_coords(v2, clean_up = False)
|
||||||
self.dither()
|
self.dither()
|
||||||
self.play(
|
self.play(
|
||||||
ApplyMethod(coords2.next_to, plus, RIGHT),
|
ApplyMethod(coords2.next_to, plus, RIGHT),
|
||||||
|
@ -1020,7 +1024,7 @@ class ScalingNumerically(VectorScene):
|
||||||
equals = TexMobject("=")
|
equals = TexMobject("=")
|
||||||
self.add_axes()
|
self.add_axes()
|
||||||
v = self.add_vector([3, 1])
|
v = self.add_vector([3, 1])
|
||||||
v_coords, vx_line, vy_line = self.vector_to_coords(v, cleanup = False)
|
v_coords, vx_line, vy_line = self.vector_to_coords(v, clean_up = False)
|
||||||
self.play(ApplyMethod(v_coords.to_edge, UP))
|
self.play(ApplyMethod(v_coords.to_edge, UP))
|
||||||
two_dot.next_to(v_coords, LEFT)
|
two_dot.next_to(v_coords, LEFT)
|
||||||
equals.next_to(v_coords, RIGHT)
|
equals.next_to(v_coords, RIGHT)
|
||||||
|
@ -1031,7 +1035,7 @@ class ScalingNumerically(VectorScene):
|
||||||
Write(two_dot, run_time = 1)
|
Write(two_dot, run_time = 1)
|
||||||
)
|
)
|
||||||
two_v_coords, two_v_x_line, two_v_y_line = self.vector_to_coords(
|
two_v_coords, two_v_x_line, two_v_y_line = self.vector_to_coords(
|
||||||
two_v, cleanup = False
|
two_v, clean_up = False
|
||||||
)
|
)
|
||||||
self.play(
|
self.play(
|
||||||
ApplyMethod(two_v_coords.next_to, equals, RIGHT),
|
ApplyMethod(two_v_coords.next_to, equals, RIGHT),
|
||||||
|
@ -1233,12 +1237,6 @@ class ManipulateSpace(LinearTransformationScene):
|
||||||
pi_creature.shift(-pi_creature.get_corner(DOWN+LEFT))
|
pi_creature.shift(-pi_creature.get_corner(DOWN+LEFT))
|
||||||
self.plane.prepare_for_nonlinear_transform()
|
self.plane.prepare_for_nonlinear_transform()
|
||||||
|
|
||||||
def homotopy(x, y, z, t):
|
|
||||||
norm = np.linalg.norm([x, y])
|
|
||||||
tau = interpolate(5, -5, t) + norm/SPACE_WIDTH
|
|
||||||
alpha = sigmoid(tau)
|
|
||||||
return [x, y + 0.5*np.sin(2*np.pi*alpha), z]
|
|
||||||
|
|
||||||
self.play(ShowCreation(
|
self.play(ShowCreation(
|
||||||
self.plane,
|
self.plane,
|
||||||
submobject_mode = "one_at_a_time",
|
submobject_mode = "one_at_a_time",
|
||||||
|
@ -1247,7 +1245,7 @@ class ManipulateSpace(LinearTransformationScene):
|
||||||
self.play(FadeIn(pi_creature))
|
self.play(FadeIn(pi_creature))
|
||||||
self.play(Blink(pi_creature))
|
self.play(Blink(pi_creature))
|
||||||
self.plane.add(pi_creature)
|
self.plane.add(pi_creature)
|
||||||
self.play(Homotopy(homotopy, self.plane, run_time = 3))
|
self.play(Homotopy(plane_wave_homotopy, self.plane, run_time = 3))
|
||||||
self.dither(2)
|
self.dither(2)
|
||||||
self.apply_matrix([[2, 1], [1, 2]])
|
self.apply_matrix([[2, 1], [1, 2]])
|
||||||
self.dither()
|
self.dither()
|
||||||
|
|
947
eola/chapter2.py
947
eola/chapter2.py
File diff suppressed because it is too large
Load diff
|
@ -127,6 +127,15 @@ class VectorScene(Scene):
|
||||||
self.add(axes)
|
self.add(axes)
|
||||||
return axes
|
return axes
|
||||||
|
|
||||||
|
def lock_in_dim_grid(self, dimness = 0.7, axes_dimness = 0.5):
|
||||||
|
plane = self.add_plane()
|
||||||
|
axes = plane.get_axes()
|
||||||
|
plane.fade(dimness)
|
||||||
|
axes.highlight(WHITE)
|
||||||
|
axes.fade(axes_dimness)
|
||||||
|
self.add(axes)
|
||||||
|
self.freeze_background()
|
||||||
|
|
||||||
def add_vector(self, vector, animate = True, color = YELLOW):
|
def add_vector(self, vector, animate = True, color = YELLOW):
|
||||||
if not isinstance(vector, Arrow):
|
if not isinstance(vector, Arrow):
|
||||||
vector = Vector(vector, color = color)
|
vector = Vector(vector, color = color)
|
||||||
|
@ -202,7 +211,7 @@ class VectorScene(Scene):
|
||||||
y_coord.highlight(Y_COLOR)
|
y_coord.highlight(Y_COLOR)
|
||||||
return y_coord
|
return y_coord
|
||||||
|
|
||||||
def coords_to_vector(self, vector, coords_start = 2*RIGHT+2*UP, cleanup = True):
|
def coords_to_vector(self, vector, coords_start = 2*RIGHT+2*UP, clean_up = True):
|
||||||
starting_mobjects = list(self.mobjects)
|
starting_mobjects = list(self.mobjects)
|
||||||
array = Matrix(vector)
|
array = Matrix(vector)
|
||||||
array.shift(coords_start)
|
array.shift(coords_start)
|
||||||
|
@ -231,11 +240,11 @@ class VectorScene(Scene):
|
||||||
self.play(ShowCreation(y_line))
|
self.play(ShowCreation(y_line))
|
||||||
self.play(ShowCreation(arrow))
|
self.play(ShowCreation(arrow))
|
||||||
self.dither()
|
self.dither()
|
||||||
if cleanup:
|
if clean_up:
|
||||||
self.clear()
|
self.clear()
|
||||||
self.add(*starting_mobjects)
|
self.add(*starting_mobjects)
|
||||||
|
|
||||||
def vector_to_coords(self, vector, integer_labels = True, cleanup = True):
|
def vector_to_coords(self, vector, integer_labels = True, clean_up = True):
|
||||||
starting_mobjects = list(self.mobjects)
|
starting_mobjects = list(self.mobjects)
|
||||||
show_creation = False
|
show_creation = False
|
||||||
if isinstance(vector, Arrow):
|
if isinstance(vector, Arrow):
|
||||||
|
@ -281,7 +290,7 @@ class VectorScene(Scene):
|
||||||
|
|
||||||
self.remove(x_coord_start, y_coord_start, brackets)
|
self.remove(x_coord_start, y_coord_start, brackets)
|
||||||
self.add(array)
|
self.add(array)
|
||||||
if cleanup:
|
if clean_up:
|
||||||
self.clear()
|
self.clear()
|
||||||
self.add(*starting_mobjects)
|
self.add(*starting_mobjects)
|
||||||
return array, x_line, y_line
|
return array, x_line, y_line
|
||||||
|
|
|
@ -31,8 +31,7 @@ class TexMobject(SVGMobject):
|
||||||
"fill_opacity" : 1.0,
|
"fill_opacity" : 1.0,
|
||||||
"fill_color" : WHITE,
|
"fill_color" : WHITE,
|
||||||
"should_center" : True,
|
"should_center" : True,
|
||||||
"next_to_direction" : RIGHT,
|
"separate_list_arg_with_spaces" : True,
|
||||||
"next_to_buff" : 0.25,
|
|
||||||
"initial_scale_val" : TEX_MOB_SCALE_VAL,
|
"initial_scale_val" : TEX_MOB_SCALE_VAL,
|
||||||
"organize_left_to_right" : False,
|
"organize_left_to_right" : False,
|
||||||
"propogate_style_to_family" : True,
|
"propogate_style_to_family" : True,
|
||||||
|
@ -51,30 +50,28 @@ class TexMobject(SVGMobject):
|
||||||
|
|
||||||
|
|
||||||
def generate_points(self):
|
def generate_points(self):
|
||||||
if isinstance(self.expression, list):
|
is_list = isinstance(self.expression, list)
|
||||||
self.handle_list_expression()
|
separator = ""
|
||||||
else:
|
if is_list and self.separate_list_arg_with_spaces:
|
||||||
self.svg_file = tex_to_svg_file(
|
separator = " "
|
||||||
"".join(self.expression),
|
expression = separator.join(self.expression)
|
||||||
self.template_tex_file
|
self.svg_file = tex_to_svg_file(expression, self.template_tex_file)
|
||||||
)
|
|
||||||
SVGMobject.generate_points(self)
|
SVGMobject.generate_points(self)
|
||||||
|
if is_list:
|
||||||
|
self.handle_list_expression(self.expression)
|
||||||
|
|
||||||
|
|
||||||
def handle_list_expression(self):
|
def handle_list_expression(self, list_expression):
|
||||||
#TODO, next_to not sufficient?
|
new_submobjects = []
|
||||||
subs = [
|
curr_index = 0
|
||||||
TexMobject(expr)
|
for expr in list_expression:
|
||||||
for expr in self.expression
|
model = TexMobject(expr, **self.CONFIG)
|
||||||
]
|
new_index = curr_index + len(model.submobjects)
|
||||||
self.initial_scale_val = 1
|
new_submobjects.append(VMobject(
|
||||||
for sm1, sm2 in zip(subs, subs[1:]):
|
*self.submobjects[curr_index:new_index]
|
||||||
sm2.next_to(
|
))
|
||||||
sm1,
|
curr_index = new_index
|
||||||
self.next_to_direction,
|
self.submobjects = new_submobjects
|
||||||
buff = self.next_to_buff
|
|
||||||
)
|
|
||||||
self.submobjects = subs
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def organize_submobjects_left_to_right(self):
|
def organize_submobjects_left_to_right(self):
|
||||||
|
|
|
@ -93,8 +93,7 @@ class VMobject(Mobject):
|
||||||
|
|
||||||
def get_stroke_color(self):
|
def get_stroke_color(self):
|
||||||
try:
|
try:
|
||||||
self.stroke_rgb[self.stroke_rgb<0] = 0
|
self.stroke_rgb = np.clip(self.stroke_rgb, 0, 1)
|
||||||
self.stroke_rgb[self.stroke_rgb>1] = 1
|
|
||||||
return Color(rgb = self.stroke_rgb)
|
return Color(rgb = self.stroke_rgb)
|
||||||
except:
|
except:
|
||||||
return Color(WHITE)
|
return Color(WHITE)
|
||||||
|
|
|
@ -104,7 +104,12 @@ class Scene(object):
|
||||||
mobjects = list(it.chain(*[m.submobject_family() for m in mobjects]))
|
mobjects = list(it.chain(*[m.submobject_family() for m in mobjects]))
|
||||||
if len(mobjects) == 0:
|
if len(mobjects) == 0:
|
||||||
return
|
return
|
||||||
self.mobjects = filter(lambda m : m not in mobjects, self.mobjects)
|
self.mobjects = filter(
|
||||||
|
lambda m : not set(
|
||||||
|
m.family_members_with_points()
|
||||||
|
).issubset(mobjects),
|
||||||
|
self.mobjects
|
||||||
|
)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def bring_to_front(self, mobject):
|
def bring_to_front(self, mobject):
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
|
|
||||||
|
|
||||||
|
from mobject.vectorized_mobject import VMobject
|
||||||
from mobject.tex_mobject import TexMobject
|
from mobject.tex_mobject import TexMobject
|
||||||
from animation import Animation
|
from animation import Animation
|
||||||
from helpers import *
|
from helpers import *
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DecimalNumber(TexMobject):
|
class DecimalNumber(VMobject):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"num_decimal_points" : 2,
|
"num_decimal_points" : 2,
|
||||||
"digit_to_digit_buff" : 0.05
|
"digit_to_digit_buff" : 0.05
|
||||||
|
@ -14,7 +15,10 @@ class DecimalNumber(TexMobject):
|
||||||
def __init__(self, float_num, **kwargs):
|
def __init__(self, float_num, **kwargs):
|
||||||
digest_config(self, kwargs)
|
digest_config(self, kwargs)
|
||||||
num_string = '%.*f' % (self.num_decimal_points, float_num)
|
num_string = '%.*f' % (self.num_decimal_points, float_num)
|
||||||
TexMobject.__init__(self, list(num_string))
|
VMobject.__init__(self, *[
|
||||||
|
TexMobject(char)
|
||||||
|
for char in num_string
|
||||||
|
], **kwargs)
|
||||||
self.arrange_submobjects(
|
self.arrange_submobjects(
|
||||||
buff = self.digit_to_digit_buff,
|
buff = self.digit_to_digit_buff,
|
||||||
aligned_edge = DOWN
|
aligned_edge = DOWN
|
||||||
|
|
Loading…
Add table
Reference in a new issue