mirror of
https://github.com/3b1b/manim.git
synced 2025-07-30 13:34:19 +08:00
Beginning of efvgt project
This commit is contained in:
230
efvgt.py
Normal file
230
efvgt.py
Normal file
@ -0,0 +1,230 @@
|
||||
from helpers import *
|
||||
|
||||
from mobject.tex_mobject import TexMobject
|
||||
from mobject import Mobject
|
||||
from mobject.image_mobject import ImageMobject
|
||||
from mobject.vectorized_mobject import *
|
||||
|
||||
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.fractals import *
|
||||
from topics.number_line import *
|
||||
from topics.combinatorics import *
|
||||
from topics.numerals import *
|
||||
from topics.three_dimensions import *
|
||||
from topics.objects import *
|
||||
from scene import Scene
|
||||
from scene.zoomed_scene import ZoomedScene
|
||||
from scene.reconfigurable_scene import ReconfigurableScene
|
||||
from camera import Camera
|
||||
from mobject.svg_mobject import *
|
||||
from mobject.tex_mobject import *
|
||||
|
||||
class ConfettiSpiril(Animation):
|
||||
CONFIG = {
|
||||
"x_start" : 0,
|
||||
"spiril_radius" : 1,
|
||||
"num_spirils" : 4,
|
||||
"run_time" : 10,
|
||||
"rate_func" : None,
|
||||
}
|
||||
def __init__(self, mobject, **kwargs):
|
||||
digest_config(self, kwargs)
|
||||
mobject.next_to(self.x_start*RIGHT + SPACE_HEIGHT*UP, UP)
|
||||
self.total_vert_shift = \
|
||||
2*SPACE_HEIGHT + mobject.get_height() + 2*MED_SMALL_BUFF
|
||||
|
||||
Animation.__init__(self, mobject, **kwargs)
|
||||
|
||||
def update_submobject(self, submobject, starting_submobject, alpha):
|
||||
submobject.points = np.array(starting_submobject.points)
|
||||
|
||||
def update_mobject(self, alpha):
|
||||
Animation.update_mobject(self, alpha)
|
||||
angle = alpha*self.num_spirils*2*np.pi
|
||||
vert_shift = alpha*self.total_vert_shift
|
||||
|
||||
start_center = self.mobject.get_center()
|
||||
self.mobject.shift(self.spiril_radius*OUT)
|
||||
self.mobject.rotate(angle, axis = UP, about_point = start_center)
|
||||
self.mobject.shift(vert_shift*DOWN)
|
||||
|
||||
class Anniversary(TeacherStudentsScene):
|
||||
CONFIG = {
|
||||
"num_confetti_squares" : 50,
|
||||
}
|
||||
def construct(self):
|
||||
self.celebrate()
|
||||
self.complain()
|
||||
|
||||
def celebrate(self):
|
||||
title = TextMobject("2 year Anniversary!")
|
||||
title.scale(1.5)
|
||||
title.to_edge(UP)
|
||||
|
||||
first_video = Rectangle(
|
||||
height = 2, width = 2*(16.0/9),
|
||||
stroke_color = WHITE,
|
||||
fill_color = "#111111",
|
||||
fill_opacity = 0.75,
|
||||
)
|
||||
first_video.next_to(self.get_teacher(), UP+LEFT)
|
||||
first_video.shift(RIGHT)
|
||||
formula = TexMobject("e^{\\pi i} = -1")
|
||||
formula.move_to(first_video)
|
||||
first_video.add(formula)
|
||||
|
||||
hats = self.get_party_hats()
|
||||
confetti_spirils = self.get_confetti_animations()
|
||||
self.play(
|
||||
Write(title, run_time = 2),
|
||||
*[
|
||||
ApplyMethod(pi.change_mode, "hooray")
|
||||
for pi in self.get_pi_creatures()
|
||||
]
|
||||
)
|
||||
self.play(
|
||||
DrawBorderThenFill(
|
||||
hats,
|
||||
submobject_mode = "lagged_start",
|
||||
rate_func = None,
|
||||
run_time = 2,
|
||||
),
|
||||
*confetti_spirils + [
|
||||
Succession(
|
||||
Animation(pi, run_time = 2),
|
||||
ApplyMethod(pi.look, UP+LEFT),
|
||||
ApplyMethod(pi.look, UP+RIGHT),
|
||||
Animation(pi),
|
||||
ApplyMethod(pi.look_at, first_video),
|
||||
rate_func = None
|
||||
)
|
||||
for pi in self.get_students()
|
||||
] + [
|
||||
Succession(
|
||||
Animation(self.get_teacher(), run_time = 2),
|
||||
Blink(self.get_teacher()),
|
||||
Animation(self.get_teacher(), run_time = 2),
|
||||
ApplyMethod(self.get_teacher().change_mode, "raise_right_hand"),
|
||||
rate_func = None
|
||||
),
|
||||
DrawBorderThenFill(
|
||||
first_video,
|
||||
run_time = 10,
|
||||
rate_func = squish_rate_func(smooth, 0.5, 0.7)
|
||||
)
|
||||
]
|
||||
)
|
||||
self.change_student_modes(*["confused"]*3)
|
||||
|
||||
def complain(self):
|
||||
self.student_says(
|
||||
"Why are you \\\\ talking so fast?",
|
||||
student_index = 0,
|
||||
target_mode = "sassy",
|
||||
)
|
||||
self.change_student_modes(*["sassy"]*3)
|
||||
self.play(self.get_teacher().change_mode, "guilty")
|
||||
self.dither(2)
|
||||
|
||||
def get_party_hats(self):
|
||||
hats = VGroup(*[
|
||||
PartyHat(
|
||||
pi_creature = pi,
|
||||
height = 0.5*pi.get_height()
|
||||
)
|
||||
for pi in self.get_pi_creatures()
|
||||
])
|
||||
max_angle = np.pi/6
|
||||
for hat in hats:
|
||||
hat.rotate(
|
||||
random.random()*2*max_angle - max_angle,
|
||||
about_point = hat.get_bottom()
|
||||
)
|
||||
return hats
|
||||
|
||||
def get_confetti_animations(self):
|
||||
colors = [RED, YELLOW, GREEN, BLUE, PURPLE, RED]
|
||||
confetti_squares = [
|
||||
Square(
|
||||
side_length = 0.2,
|
||||
stroke_width = 0,
|
||||
fill_opacity = 0.5,
|
||||
fill_color = random.choice(colors),
|
||||
)
|
||||
for x in range(self.num_confetti_squares)
|
||||
]
|
||||
confetti_spirils = [
|
||||
ConfettiSpiril(
|
||||
square,
|
||||
x_start = 2*random.random()*SPACE_WIDTH - SPACE_WIDTH,
|
||||
rate_func = squish_rate_func(lambda t : t, a, a+0.5)
|
||||
)
|
||||
for a, square in zip(
|
||||
np.linspace(0, 0.5, self.num_confetti_squares),
|
||||
confetti_squares
|
||||
)
|
||||
]
|
||||
return confetti_spirils
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -12,6 +12,37 @@ from topics.geometry import Circle, Line, Rectangle, Square
|
||||
from topics.three_dimensions import Cube
|
||||
|
||||
|
||||
class PartyHat(SVGMobject):
|
||||
CONFIG = {
|
||||
"file_name" : "party_hat",
|
||||
"height" : 1.5,
|
||||
"pi_creature" : None,
|
||||
"stroke_width" : 0,
|
||||
"fill_opacity" : 1,
|
||||
"propogate_style_to_family" : True,
|
||||
"frills_color" : MAROON_B,
|
||||
"cone_color" : RED,
|
||||
"dots_color" : YELLOW,
|
||||
}
|
||||
NUM_FRILLS = 7
|
||||
NUM_DOTS = 6
|
||||
def __init__(self, **kwargs):
|
||||
SVGMobject.__init__(self, **kwargs)
|
||||
self.scale_to_fit_height(self.height)
|
||||
if self.pi_creature is not None:
|
||||
self.next_to(self.pi_creature.eyes, UP, buff = 0)
|
||||
|
||||
self.frills = VGroup(*self[:self.NUM_FRILLS])
|
||||
self.cone = self[self.NUM_FRILLS]
|
||||
self.dots = VGroup(*self[self.NUM_FRILLS+1:])
|
||||
|
||||
self.frills.highlight(self.frills_color)
|
||||
self.cone.highlight(self.cone_color)
|
||||
self.dots.highlight(self.dots_color)
|
||||
|
||||
|
||||
|
||||
|
||||
class Laptop(VGroup):
|
||||
CONFIG = {
|
||||
"width" : 3,
|
||||
|
Reference in New Issue
Block a user