mirror of
https://github.com/3b1b/manim.git
synced 2025-09-01 00:48:45 +00:00
Merge branch 'master' into eop
This commit is contained in:
commit
1a31e08692
13 changed files with 4621 additions and 453 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -13,3 +13,5 @@ ben_cairo_test.py
|
||||||
*.xml
|
*.xml
|
||||||
*.iml
|
*.iml
|
||||||
|
|
||||||
|
|
||||||
|
primes.py
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -310,3 +310,24 @@ class ApplyToCenters(Animation):
|
||||||
center_mob.get_center()-mobject.get_center()
|
center_mob.get_center()-mobject.get_center()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class FadeInAndShiftFromDirection(Transform):
|
||||||
|
CONFIG = {
|
||||||
|
"direction" : DOWN,
|
||||||
|
}
|
||||||
|
def __init__(self, mobject, **kwargs):
|
||||||
|
digest_config(self, kwargs)
|
||||||
|
target = mobject.copy()
|
||||||
|
mobject.shift(self.direction)
|
||||||
|
mobject.fade(1)
|
||||||
|
Transform.__init__(self, mobject, target, **kwargs)
|
||||||
|
|
||||||
|
# Essentially just a more convenient name for the above animation
|
||||||
|
class FadeInFromDown(FadeInAndShiftFromDirection):
|
||||||
|
CONFIG = {
|
||||||
|
"direction" : DOWN,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ from helpers import *
|
||||||
from mobject import Mobject, PMobject, VMobject, \
|
from mobject import Mobject, PMobject, VMobject, \
|
||||||
ImageMobject, Group
|
ImageMobject, Group
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
class Camera(object):
|
class Camera(object):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"background_image" : None,
|
"background_image" : None,
|
||||||
|
@ -123,14 +125,15 @@ class Camera(object):
|
||||||
pixel coordinates), and each output is expected to be an RGBA array of 4 floats.
|
pixel coordinates), and each output is expected to be an RGBA array of 4 floats.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
print "Starting set_background_from_func"
|
print "Starting set_background; for reference, the current time is ", time.strftime("%H:%M:%S")
|
||||||
|
|
||||||
coords = self.get_coords_of_all_pixels()
|
coords = self.get_coords_of_all_pixels()
|
||||||
new_background = np.apply_along_axis(
|
new_background = np.apply_along_axis(
|
||||||
coords_to_colors_func,
|
coords_to_colors_func,
|
||||||
2,
|
2,
|
||||||
coords
|
coords
|
||||||
)
|
)
|
||||||
|
print "Ending set_background; for reference, the current time is ", time.strftime("%H:%M:%S")
|
||||||
|
|
||||||
return self.convert_pixel_array(new_background, convert_from_floats = True)
|
return self.convert_pixel_array(new_background, convert_from_floats = True)
|
||||||
|
|
||||||
def set_background_from_func(self, coords_to_colors_func):
|
def set_background_from_func(self, coords_to_colors_func):
|
||||||
|
|
|
@ -210,10 +210,11 @@ class TexMobject(SVGMobject):
|
||||||
self.submobjects.sort(alphabetical_cmp)
|
self.submobjects.sort(alphabetical_cmp)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def add_background_rectangle(self, color = BLACK, opacity = 0.75):
|
def add_background_rectangle(self, color = BLACK, opacity = 0.75, **kwargs):
|
||||||
self.background_rectangle = BackgroundRectangle(
|
self.background_rectangle = BackgroundRectangle(
|
||||||
self, color = color,
|
self, color = color,
|
||||||
fill_opacity = opacity
|
fill_opacity = opacity,
|
||||||
|
**kwargs
|
||||||
)
|
)
|
||||||
letters = VMobject(*self.submobjects)
|
letters = VMobject(*self.submobjects)
|
||||||
self.submobjects = [self.background_rectangle, letters]
|
self.submobjects = [self.background_rectangle, letters]
|
||||||
|
|
|
@ -65,13 +65,6 @@ class VMobject(Mobject):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def set_fill(self, color = None, opacity = None, family = True):
|
def set_fill(self, color = None, opacity = None, family = True):
|
||||||
probably_meant_to_change_opacity = reduce(op.and_, [
|
|
||||||
color is not None,
|
|
||||||
opacity is None,
|
|
||||||
self.fill_opacity == 0
|
|
||||||
])
|
|
||||||
if probably_meant_to_change_opacity:
|
|
||||||
opacity = 1
|
|
||||||
return self.set_style_data(
|
return self.set_style_data(
|
||||||
fill_color = color,
|
fill_color = color,
|
||||||
fill_opacity = opacity,
|
fill_opacity = opacity,
|
||||||
|
|
1129
old_projects/pi_day.py
Normal file
1129
old_projects/pi_day.py
Normal file
File diff suppressed because it is too large
Load diff
|
@ -34,7 +34,7 @@ from mobject.tex_mobject import *
|
||||||
from topics.graph_scene import *
|
from topics.graph_scene import *
|
||||||
from topics.light import *
|
from topics.light import *
|
||||||
|
|
||||||
from active_projects.fourier import *
|
from old_projects.fourier import *
|
||||||
|
|
||||||
|
|
||||||
FREQUENCY_COLOR = RED
|
FREQUENCY_COLOR = RED
|
||||||
|
|
|
@ -29,6 +29,7 @@ MOUTH_INDEX = 5
|
||||||
class PiCreature(SVGMobject):
|
class PiCreature(SVGMobject):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"color" : BLUE_E,
|
"color" : BLUE_E,
|
||||||
|
"file_name_prefix" : "PiCreatures",
|
||||||
"stroke_width" : 0,
|
"stroke_width" : 0,
|
||||||
"stroke_color" : BLACK,
|
"stroke_color" : BLACK,
|
||||||
"fill_opacity" : 1.0,
|
"fill_opacity" : 1.0,
|
||||||
|
@ -43,18 +44,19 @@ class PiCreature(SVGMobject):
|
||||||
"left_arm_range" : [.34, .462],
|
"left_arm_range" : [.34, .462],
|
||||||
}
|
}
|
||||||
def __init__(self, mode = "plain", **kwargs):
|
def __init__(self, mode = "plain", **kwargs):
|
||||||
|
digest_config(self, kwargs)
|
||||||
self.parts_named = False
|
self.parts_named = False
|
||||||
try:
|
try:
|
||||||
svg_file = os.path.join(
|
svg_file = os.path.join(
|
||||||
PI_CREATURE_DIR,
|
PI_CREATURE_DIR,
|
||||||
"PiCreatures_%s.svg"%mode
|
"%s_%s.svg"%(self.file_name_prefix, mode)
|
||||||
)
|
)
|
||||||
SVGMobject.__init__(self, file_name = svg_file, **kwargs)
|
SVGMobject.__init__(self, file_name = svg_file, **kwargs)
|
||||||
except:
|
except:
|
||||||
warnings.warn("No PiCreature design with mode %s"%mode)
|
warnings.warn("No %s design with mode %s"%(self.file_name_prefix, mode))
|
||||||
svg_file = os.path.join(
|
svg_file = os.path.join(
|
||||||
FILE_DIR,
|
FILE_DIR,
|
||||||
"PiCreatures_plain.svg"
|
"PiCreatures_plain.svg",
|
||||||
)
|
)
|
||||||
SVGMobject.__init__(self, file_name = svg_file, **kwargs)
|
SVGMobject.__init__(self, file_name = svg_file, **kwargs)
|
||||||
|
|
||||||
|
@ -210,7 +212,7 @@ class PiCreature(SVGMobject):
|
||||||
|
|
||||||
def get_all_pi_creature_modes():
|
def get_all_pi_creature_modes():
|
||||||
result = []
|
result = []
|
||||||
prefix = "PiCreatures_"
|
prefix = "%s_"%PiCreature.CONFIG["file_name_prefix"]
|
||||||
suffix = ".svg"
|
suffix = ".svg"
|
||||||
for file in os.listdir(PI_CREATURE_DIR):
|
for file in os.listdir(PI_CREATURE_DIR):
|
||||||
if file.startswith(prefix) and file.endswith(suffix):
|
if file.startswith(prefix) and file.endswith(suffix):
|
||||||
|
@ -253,6 +255,17 @@ class BabyPiCreature(PiCreature):
|
||||||
pupil.scale_in_place(self.pupil_scale_factor)
|
pupil.scale_in_place(self.pupil_scale_factor)
|
||||||
self.look(looking_direction)
|
self.look(looking_direction)
|
||||||
|
|
||||||
|
class TauCreature(PiCreature):
|
||||||
|
CONFIG = {
|
||||||
|
"file_name_prefix" : "TauCreatures"
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreeLeggedPiCreature(PiCreature):
|
||||||
|
CONFIG = {
|
||||||
|
"file_name_prefix" : "ThreeLeggedPiCreatures"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Blink(ApplyMethod):
|
class Blink(ApplyMethod):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"rate_func" : squish_rate_func(there_and_back)
|
"rate_func" : squish_rate_func(there_and_back)
|
||||||
|
@ -666,6 +679,9 @@ class TeacherStudentsScene(PiCreatureScene):
|
||||||
student = self.get_students()[kwargs.get("student_index", 1)]
|
student = self.get_students()[kwargs.get("student_index", 1)]
|
||||||
return self.pi_creature_thinks(student, *content, **kwargs)
|
return self.pi_creature_thinks(student, *content, **kwargs)
|
||||||
|
|
||||||
|
def change_all_student_modes(self, mode, **kwargs):
|
||||||
|
self.change_student_modes(*[mode]*len(self.students), **kwargs)
|
||||||
|
|
||||||
def change_student_modes(self, *modes, **kwargs):
|
def change_student_modes(self, *modes, **kwargs):
|
||||||
added_anims = kwargs.pop("added_anims", [])
|
added_anims = kwargs.pop("added_anims", [])
|
||||||
self.play(
|
self.play(
|
||||||
|
|
|
@ -3,7 +3,8 @@ from helpers import *
|
||||||
|
|
||||||
from scene.scene import Scene
|
from scene.scene import Scene
|
||||||
from animation import Animation
|
from animation import Animation
|
||||||
from animation.simple_animations import Write, DrawBorderThenFill, LaggedStart
|
from animation.simple_animations import Write, DrawBorderThenFill
|
||||||
|
from animation.compositions import LaggedStart
|
||||||
from animation.transform import FadeIn, FadeOut, ApplyMethod
|
from animation.transform import FadeIn, FadeOut, ApplyMethod
|
||||||
from mobject.vectorized_mobject import VGroup
|
from mobject.vectorized_mobject import VGroup
|
||||||
from mobject.tex_mobject import TexMobject, TextMobject
|
from mobject.tex_mobject import TexMobject, TextMobject
|
||||||
|
@ -132,11 +133,11 @@ class PatreonEndScreen(PatreonThanks):
|
||||||
self.scroll_through_patrons()
|
self.scroll_through_patrons()
|
||||||
|
|
||||||
def add_title(self):
|
def add_title(self):
|
||||||
title = TextMobject("Clicky Stuffs")
|
title = self.title = TextMobject("Clicky Stuffs")
|
||||||
title.scale(1.5)
|
title.scale(1.5)
|
||||||
title.to_edge(UP, buff = MED_SMALL_BUFF)
|
title.to_edge(UP, buff = MED_SMALL_BUFF)
|
||||||
|
|
||||||
randy, morty = Randolph(), Mortimer()
|
randy, morty = self.pi_creatures = VGroup(Randolph(), Mortimer())
|
||||||
for pi, vect in (randy, LEFT), (morty, RIGHT):
|
for pi, vect in (randy, LEFT), (morty, RIGHT):
|
||||||
pi.scale_to_fit_height(title.get_height())
|
pi.scale_to_fit_height(title.get_height())
|
||||||
pi.change_mode("thinking")
|
pi.change_mode("thinking")
|
||||||
|
|
|
@ -159,7 +159,11 @@ class Circle(Arc):
|
||||||
def surround(self, mobject, dim_to_match = 0, stretch = False, buffer_factor = 1.2):
|
def surround(self, mobject, dim_to_match = 0, stretch = False, buffer_factor = 1.2):
|
||||||
# Ignores dim_to_match and stretch; result will always be a circle
|
# Ignores dim_to_match and stretch; result will always be a circle
|
||||||
# TODO: Perhaps create an ellipse class to handle singele-dimension stretching
|
# TODO: Perhaps create an ellipse class to handle singele-dimension stretching
|
||||||
|
|
||||||
|
# Something goes wrong here when surrounding lines?
|
||||||
|
# TODO: Figure out and fix
|
||||||
self.replace(mobject, dim_to_match, stretch)
|
self.replace(mobject, dim_to_match, stretch)
|
||||||
|
|
||||||
self.scale_to_fit_width(np.sqrt(mobject.get_width()**2 + mobject.get_height()**2))
|
self.scale_to_fit_width(np.sqrt(mobject.get_width()**2 + mobject.get_height()**2))
|
||||||
self.scale(buffer_factor)
|
self.scale(buffer_factor)
|
||||||
|
|
||||||
|
@ -450,7 +454,6 @@ class DashedLine(Line):
|
||||||
|
|
||||||
class Arrow(Line):
|
class Arrow(Line):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"color" : YELLOW_C,
|
|
||||||
"tip_length" : 0.25,
|
"tip_length" : 0.25,
|
||||||
"tip_width_to_length_ratio" : 1,
|
"tip_width_to_length_ratio" : 1,
|
||||||
"max_tip_length_to_length_ratio" : 0.35,
|
"max_tip_length_to_length_ratio" : 0.35,
|
||||||
|
@ -707,15 +710,6 @@ class BackgroundRectangle(SurroundingRectangle):
|
||||||
def get_fill_color(self):
|
def get_fill_color(self):
|
||||||
return Color(self.color)
|
return Color(self.color)
|
||||||
|
|
||||||
class FullScreenFadeRectangle(Rectangle):
|
|
||||||
CONFIG = {
|
|
||||||
"height" : 2*SPACE_HEIGHT,
|
|
||||||
"width" : 2*SPACE_WIDTH,
|
|
||||||
"stroke_width" : 0,
|
|
||||||
"fill_color" : BLACK,
|
|
||||||
"fill_opacity" : 0.7,
|
|
||||||
}
|
|
||||||
|
|
||||||
class ScreenRectangle(Rectangle):
|
class ScreenRectangle(Rectangle):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"width_to_height_ratio" : 16.0/9.0,
|
"width_to_height_ratio" : 16.0/9.0,
|
||||||
|
@ -725,6 +719,18 @@ class ScreenRectangle(Rectangle):
|
||||||
self.width = self.width_to_height_ratio * self.height
|
self.width = self.width_to_height_ratio * self.height
|
||||||
Rectangle.generate_points(self)
|
Rectangle.generate_points(self)
|
||||||
|
|
||||||
|
class FullScreenRectangle(ScreenRectangle):
|
||||||
|
CONFIG = {
|
||||||
|
"height" : 2*SPACE_HEIGHT,
|
||||||
|
}
|
||||||
|
|
||||||
|
class FullScreenFadeRectangle(FullScreenRectangle):
|
||||||
|
CONFIG = {
|
||||||
|
"stroke_width" : 0,
|
||||||
|
"fill_color" : BLACK,
|
||||||
|
"fill_opacity" : 0.7,
|
||||||
|
}
|
||||||
|
|
||||||
class PictureInPictureFrame(Rectangle):
|
class PictureInPictureFrame(Rectangle):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"height" : 3,
|
"height" : 3,
|
||||||
|
|
|
@ -261,6 +261,7 @@ class NumberPlane(VMobject):
|
||||||
"secondary_color" : BLUE_E,
|
"secondary_color" : BLUE_E,
|
||||||
"axes_color" : WHITE,
|
"axes_color" : WHITE,
|
||||||
"secondary_stroke_width" : 1,
|
"secondary_stroke_width" : 1,
|
||||||
|
# TODO: Allow coordinate center of NumberPlane to not be at (0, 0)
|
||||||
"x_radius": None,
|
"x_radius": None,
|
||||||
"y_radius": None,
|
"y_radius": None,
|
||||||
"x_unit_size" : 1,
|
"x_unit_size" : 1,
|
||||||
|
|
Loading…
Add table
Reference in a new issue