diff --git a/__init__.py b/__init__.py index 7718a95c..33c2412e 100644 --- a/__init__.py +++ b/__init__.py @@ -1,10 +1,13 @@ from animation import * -from mobject import * from scene import * -from scripts import * +from topics import * from constants import * -from helpers import * from displayer import * +from extract_scene import * +from helpers import * +from image_mobject import * +from mobject import * +from old_proje import * +from playground import * from region import * -from script_wrapper import * -from tex_utils import * \ No newline at end of file +from tex_utils import * diff --git a/animation/__init__.py b/animation/__init__.py index 59869568..2ae2b51b 100644 --- a/animation/__init__.py +++ b/animation/__init__.py @@ -1,3 +1,4 @@ from animation import * -from transform import * -from simple_animations import * \ No newline at end of file +from meta_animations import * +from simple_animations import * +from transform import * \ No newline at end of file diff --git a/animation/animation.py b/animation/animation.py index ff13d694..7bb31ac9 100644 --- a/animation/animation.py +++ b/animation/animation.py @@ -7,11 +7,10 @@ import os import copy import progressbar import inspect -from images2gif import writeGif from helpers import * -from constants import * -from mobject import Mobject, Point +from mobject import Mobject +from topics.geometry import Point class Animation(object): DEFAULT_CONFIG = { @@ -119,4 +118,3 @@ class Animation(object): - diff --git a/animation/meta_animations.py b/animation/meta_animations.py new file mode 100644 index 00000000..f452f755 --- /dev/null +++ b/animation/meta_animations.py @@ -0,0 +1,95 @@ +import numpy as np +import itertools as it +from copy import deepcopy + +from helpers import * +from animation import Animation +from transform import Transform + + +class DelayByOrder(Animation): + """ + Modifier of animation. + + Warning: This will not work on all animation types, but + when it does, it will be pretty cool + """ + DEFAULT_CONFIG = { + "max_power" : 5 + } + def __init__(self, animation, **kwargs): + digest_config(self, DelayByOrder, kwargs, locals()) + kwargs.update(dict([ + (attr, getattr(animation, attr)) + for attr in Animation.DEFAULT_CONFIG + ])) + self.num_mobject_points = animation.mobject.get_num_points() + Animation.__init__(self, animation.mobject, **kwargs) + self.name = self.__class__.__name__ + str(self.animation) + + def update_mobject(self, alpha): + dim = self.mobject.DIM + alpha_array = np.array([ + [alpha**power]*dim + for n in range(self.num_mobject_points) + for prop in [(n+1.0)/self.num_mobject_points] + for power in [1+prop*(self.max_power-1)] + ]) + self.animation.update_mobject(alpha_array) + + + +class TransformAnimations(Transform): + DEFAULT_CONFIG = { + "alpha_func" : squish_alpha_func(smooth) + } + def __init__(self, start_anim, end_anim, **kwargs): + digest_config(self, TransformAnimations, kwargs, locals()) + if "run_time" in kwargs: + self.run_time = kwargs.pop("run_time") + else: + self.run_time = max(start_anim.run_time, end_anim.run_time) + for anim in start_anim, end_anim: + anim.set_run_time(self.run_time) + + if start_anim.starting_mobject.get_num_points() != end_anim.starting_mobject.get_num_points(): + Mobject.align_data(start_anim.starting_mobject, end_anim.starting_mobject) + for anim in start_anim, end_anim: + if hasattr(anim, "ending_mobject"): + Mobject.align_data(anim.starting_mobject, anim.ending_mobject) + + Transform.__init__(self, start_anim.mobject, end_anim.mobject, **kwargs) + #Rewire starting and ending mobjects + start_anim.mobject = self.starting_mobject + end_anim.mobject = self.ending_mobject + + def update(self, alpha): + self.start_anim.update(alpha) + self.end_anim.update(alpha) + Transform.update(self, alpha) + + +class Succession(Animation): + def __init__(self, *animations, **kwargs): + if "run_time" in kwargs: + run_time = kwargs.pop("run_time") + else: + run_time = sum([anim.run_time for anim in animations]) + self.num_anims = len(animations) + self.anims = animations + mobject = animations[0].mobject + Animation.__init__(self, mobject, run_time = run_time, **kwargs) + + def __str__(self): + return self.__class__.__name__ + \ + "".join(map(str, self.anims)) + + def update(self, alpha): + scaled_alpha = alpha*self.num_anims + self.mobject = self.anims + for index in range(len(self.anims)): + self.anims[index].update(scaled_alpha - index) + + + + diff --git a/animation/simple_animations.py b/animation/simple_animations.py index e1f10fb7..0c7c6069 100644 --- a/animation/simple_animations.py +++ b/animation/simple_animations.py @@ -2,42 +2,12 @@ import numpy as np import itertools as it from copy import deepcopy -from animation import Animation -from transform import Transform -from mobject import * -from constants import * from helpers import * +from animation import Animation +from meta_animations import DelayByOrder +from transform import Transform -class DelayByOrder(Animation): - """ - Modifier of animation. - - Warning: This will not work on all animation types, but - when it does, it will be pretty cool - """ - DEFAULT_CONFIG = { - "max_power" : 5 - } - def __init__(self, animation, **kwargs): - digest_config(self, DelayByOrder, kwargs, locals()) - kwargs.update(dict([ - (attr, getattr(animation, attr)) - for attr in Animation.DEFAULT_CONFIG - ])) - self.num_mobject_points = animation.mobject.get_num_points() - Animation.__init__(self, animation.mobject, **kwargs) - self.name = self.__class__.__name__ + str(self.animation) - - def update_mobject(self, alpha): - dim = self.mobject.DIM - alpha_array = np.array([ - [alpha**power]*dim - for n in range(self.num_mobject_points) - for prop in [(n+1.0)/self.num_mobject_points] - for power in [1+prop*(self.max_power-1)] - ]) - self.animation.update_mobject(alpha_array) class Rotating(Animation): DEFAULT_CONFIG = { @@ -55,17 +25,6 @@ class Rotating(Animation): for axis in self.axes: self.mobject.rotate(self.radians * alpha, axis) -class RotationAsTransform(Rotating): - DEFAULT_CONFIG = { - "axes" : [OUT], - "radians" : np.pi / 2, - "run_time" : DEFAULT_ANIMATION_RUN_TIME, - "alpha_func" : smooth, - } - def __init__(self, mobject, **kwargs): - digest_config(self, RotationAsTransform, kwargs, locals()) - Rotating.__init__(self, mobject, **kwargs) - class FadeOut(Animation): def update_mobject(self, alpha): self.mobject.rgbs = self.starting_mobject.rgbs * (1 - alpha) @@ -136,96 +95,6 @@ class Homotopy(Animation): for x, y, z in self.starting_mobject.points ]) -class ComplexHomotopy(Homotopy): - def __init__(self, complex_homotopy, **kwargs): - """ - Complex Hootopy a function (z, t) to z' - """ - def homotopy((x, y, z, t)): - c = complex_homotopy((complex(x, y), t)) - return (c.real, c.imag, z) - if len(args) > 0: - args = list(args) - mobject = args.pop(0) - elif "mobject" in kwargs: - mobject = kwargs["mobject"] - else: - mobject = Grid() - Homotopy.__init__(self, homotopy, mobject, *args, **kwargs) - self.name = "ComplexHomotopy" + \ - to_cammel_case(complex_homotopy.__name__) - -class Succession(Animation): - def __init__(self, *animations, **kwargs): - if "run_time" in kwargs: - run_time = kwargs.pop("run_time") - else: - run_time = sum([anim.run_time for anim in animations]) - self.num_anims = len(animations) - self.anims = animations - mobject = animations[0].mobject - Animation.__init__(self, mobject, run_time = run_time, **kwargs) - - def __str__(self): - return self.__class__.__name__ + \ - "".join(map(str, self.anims)) - - def update(self, alpha): - scaled_alpha = alpha*self.num_anims - self.mobject = self.anims - for index in range(len(self.anims)): - self.anims[index].update(scaled_alpha - index) - -####### Pi Creature Stuff ############# - -class WalkPiCreature(Animation): - def __init__(self, pi_creature, destination, *args, **kwargs): - self.final = deepcopy(pi_creature).move_to(destination) - self.middle = pi_creature.get_step_intermediate(self.final) - Animation.__init__(self, pi_creature, *args, **kwargs) - - def update_mobject(self, alpha): - if alpha < 0.5: - Mobject.interpolate( - self.starting_mobject, - self.middle, - self.mobject, - 2*alpha - ) - else: - Mobject.interpolate( - self.middle, - self.final, - self.mobject, - 2*alpha - 1 - ) - - -class BlinkPiCreature(Transform): - def __init__(self, pi_creature, *args, **kwargs): - blinked = deepcopy(pi_creature).blink() - Transform.__init__( - self, pi_creature, blinked, - alpha_func = squish_alpha_func(there_and_back), - *args, **kwargs - ) - - -class WaveArm(Transform): - def __init__(self, pi_creature, *args, **kwargs): - final = deepcopy(pi_creature) - body_to_arm = pi_creature.arm.get_center()-pi_creature.get_center() - if body_to_arm[0] < 0: - wag_direction = LEFT - else: - wag_direction = RIGHT - final.arm.wag(0.7*UP, wag_direction, 2.0) - final.rewire_part_attributes(self_from_parts = True) - Transform.__init__( - self, pi_creature, final, - alpha_func = there_and_back, - *args, **kwargs - ) diff --git a/animation/transform.py b/animation/transform.py index 169cc536..692ad3dc 100644 --- a/animation/transform.py +++ b/animation/transform.py @@ -4,39 +4,12 @@ import inspect import copy import warnings -from animation import Animation -from mobject import Mobject, Point, ComplexPlane -from constants import * from helpers import * -def straight_path(start_points, end_points, alpha): - return (1-alpha)*start_points + alpha*end_points - -def path_along_arc(arc_angle): - """ - If vect is vector from start to end, [vect[:,1], -vect[:,0]] is - perpendicualr to vect in the left direction. - """ - if arc_angle == 0: - return straight_path - def path(start_points, end_points, alpha): - vects = end_points - start_points - centers = start_points + 0.5*vects - if arc_angle != np.pi: - for i, b in [(0, -1), (1, 1)]: - centers[:,i] += 0.5*b*vects[:,1-i]/np.tan(arc_angle/2) - return centers + np.dot( - start_points-centers, - np.transpose(rotation_about_z(alpha*arc_angle)) - ) - return path - -def clockwise_path(): - return path_along_arc(np.pi) - -def counterclockwise_path(): - return path_along_arc(-np.pi) - +from animation import Animation +from mobject import Mobject +from topics.geometry import Point +from topics.complex_numbers import ComplexPlane class Transform(Animation): DEFAULT_CONFIG = { @@ -137,6 +110,12 @@ class ApplyMethod(Transform): **kwargs ) +class Rotate(ApplyMethod): + def __init__(self, mobject, angle = np.pi, **kwargs): + kwargs["interpolation_function"] = path_along_arc(angle) + ApplyMethod.__init__(self, mobject.rotate, angle, **kwargs) + + class ApplyPointwiseFunction(ApplyMethod): DEFAULT_CONFIG = { "run_time" : DEFAULT_POINTWISE_FUNCTION_RUN_TIME @@ -147,20 +126,6 @@ class ApplyPointwiseFunction(ApplyMethod): self, mobject.apply_function, function, **kwargs ) - -class ComplexFunction(ApplyPointwiseFunction): - def __init__(self, function, mobject = ComplexPlane, **kwargs): - if "interpolation_function" not in kwargs: - self.interpolation_function = path_along_arc( - np.log(function(complex(1))).imag - ) - ApplyPointwiseFunction.__init__( - self, - lambda (x, y, z) : complex_to_R3(function(complex(x, y))), - instantiate(mobject), - **kwargs - ) - class FadeToColor(ApplyMethod): def __init__(self, mobject, color, **kwargs): ApplyMethod.__init__(self, mobject.highlight, color, **kwargs) @@ -200,35 +165,6 @@ class ApplyMatrix(Animation): ) -class TransformAnimations(Transform): - DEFAULT_CONFIG = { - "alpha_func" : squish_alpha_func(smooth) - } - def __init__(self, start_anim, end_anim, **kwargs): - digest_config(self, TransformAnimations, kwargs, locals()) - if "run_time" in kwargs: - self.run_time = kwargs.pop("run_time") - else: - self.run_time = max(start_anim.run_time, end_anim.run_time) - for anim in start_anim, end_anim: - anim.set_run_time(self.run_time) - - if start_anim.starting_mobject.get_num_points() != end_anim.starting_mobject.get_num_points(): - Mobject.align_data(start_anim.starting_mobject, end_anim.starting_mobject) - for anim in start_anim, end_anim: - if hasattr(anim, "ending_mobject"): - Mobject.align_data(anim.starting_mobject, anim.ending_mobject) - - Transform.__init__(self, start_anim.mobject, end_anim.mobject, **kwargs) - #Rewire starting and ending mobjects - start_anim.mobject = self.starting_mobject - end_anim.mobject = self.ending_mobject - - def update(self, alpha): - self.start_anim.update(alpha) - self.end_anim.update(alpha) - Transform.update(self, alpha) - diff --git a/displayer.py b/displayer.py index 690e35ec..8d9606b3 100644 --- a/displayer.py +++ b/displayer.py @@ -8,8 +8,7 @@ import cv2 from colour import Color import progressbar -from mobject import * -from constants import * +from helpers import * FFMPEG_BIN = "ffmpeg" @@ -136,19 +135,6 @@ def get_file_path(name, extension): os.makedirs(directory) return file_path -def write_to_gif(scene, name): - #TODO, find better means of compression - if not name.endswith(".gif"): - name += ".gif" - file_path = os.path.join(GIF_DIR, name) - temppath = os.path.join(GIF_DIR, "Temp.gif") - print "Writing " + name + "..." - images = [Image.fromarray(frame) for frame in scene.frames] - writeGif(temppath, images, scene.frame_duration) - print "Compressing..." - os.system("gifsicle -O " + temppath + " > " + file_path) - os.system("rm " + temppath) - def write_to_movie(scene, name): file_path = get_file_path(name, ".mp4") print "Writing to %s"%file_path diff --git a/script_wrapper.py b/extract_scene.py similarity index 89% rename from script_wrapper.py rename to extract_scene.py index cf7db032..c909271b 100644 --- a/script_wrapper.py +++ b/extract_scene.py @@ -1,13 +1,15 @@ +#!/usr/bin/env python + import sys import getopt import imp import itertools as it import inspect import traceback -from helpers import cammel_case_initials -from scene import Scene +import imp -from constants import * +from helpers import * +from scene import Scene HELP_MESSAGE = """