diff --git a/.gitignore b/.gitignore index d7e368c9..d83683d2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ *.pyc -animation_files/ .DS_Store homeless.py ka_playgrounds/ playground.py prettiness_hall_of_fame.py +files/ \ No newline at end of file diff --git a/animation/transform.py b/animation/transform.py index 8c87f4c5..51a9d64a 100644 --- a/animation/transform.py +++ b/animation/transform.py @@ -153,26 +153,20 @@ class ApplyFunction(Transform): ) self.name = "ApplyFunctionTo"+str(mobject) -class ApplyMatrix(Animation): +class ApplyMatrix(ApplyPointwiseFunction): #Truth be told, I'm not sure if this is useful. def __init__(self, matrix, mobject, **kwargs): matrix = np.array(matrix) if matrix.shape == (2, 2): - self.matrix = np.identity(3) - self.matrix[:2, :2] = matrix - elif matrix.shape == (3, 3): - self.matrix = matrix - else: + new_matrix = np.identity(3) + new_matrix[:2, :2] = matrix + matrix = new_matrix + elif matrix.shape != (3, 3): raise "Matrix has bad dimensions" - Animation.__init__(self, mobject, **kwargs) - - def update_mobject(self, alpha): - matrix = interpolate(np.identity(3), self.matrix, alpha) - self.mobject.points = np.dot( - self.starting_mobject.points, - np.transpose(matrix) - ) - + transpose = np.transpose(matrix) + def func(p): + return np.dot(p, transpose) + ApplyPointwiseFunction.__init__(self, func, mobject, **kwargs) class TransformAnimations(Transform): diff --git a/camera.py b/camera.py index 2a3d4ca0..736303ca 100644 --- a/camera.py +++ b/camera.py @@ -129,8 +129,6 @@ class Camera(object): if len(points) == 0: continue coords = self.points_to_pixel_coords(points) - if np.all(~self.on_screen_pixels(coords)): - return result start = "M%d %d"%tuple(coords[0]) #(handle1, handle2, anchor) tripletes triplets = zip(*[ diff --git a/constants.py b/constants.py index 11f64e1a..db36691e 100644 --- a/constants.py +++ b/constants.py @@ -15,7 +15,7 @@ MEDIUM_QUALITY_CAMERA_CONFIG = { } LOW_QUALITY_CAMERA_CONFIG = { - "pixel_shape" : (480, 720), + "pixel_shape" : (480, 853), } @@ -53,7 +53,7 @@ LEFT_SIDE = SPACE_WIDTH*LEFT RIGHT_SIDE = SPACE_WIDTH*RIGHT THIS_DIR = os.path.dirname(os.path.realpath(__file__)) -FILE_DIR = os.path.join(THIS_DIR, "animation_files") +FILE_DIR = os.path.join(THIS_DIR, "files") IMAGE_DIR = os.path.join(FILE_DIR, "images") GIF_DIR = os.path.join(FILE_DIR, "gifs") MOVIE_DIR = os.path.join(FILE_DIR, "movies") diff --git a/mobject/svg_mobject.py b/mobject/svg_mobject.py index 4cd97041..dd66399a 100644 --- a/mobject/svg_mobject.py +++ b/mobject/svg_mobject.py @@ -12,9 +12,22 @@ class SVGMobject(VMobject): } def __init__(self, svg_file, **kwargs): digest_config(self, kwargs, locals()) + self.ensure_valid_file() VMobject.__init__(self, **kwargs) self.move_into_position() + def ensure_valid_file(self): + possible_paths = [ + self.svg_file, + os.path.join(IMAGE_DIR, self.svg_file), + os.path.join(IMAGE_DIR, self.svg_file + ".svg"), + ] + for path in possible_paths: + if os.path.exists(path): + self.svg_file = path + return + raise IOError("No file matching %s in image directory"%self.svg_file) + def generate_points(self): doc = minidom.parse(self.svg_file) self.ref_to_element = {} diff --git a/mobject/tex_mobject.py b/mobject/tex_mobject.py index 12fcca3b..5acb8868 100644 --- a/mobject/tex_mobject.py +++ b/mobject/tex_mobject.py @@ -34,13 +34,15 @@ class TexMobject(SVGMobject): "next_to_direction" : RIGHT, "next_to_buff" : 0.25, "initial_scale_val" : TEX_MOB_SCALE_VAL, + "organize_left_to_right" : True, "propogate_style_to_family" : True, } def __init__(self, expression, **kwargs): digest_config(self, kwargs, locals()) VMobject.__init__(self, **kwargs) self.move_into_position() - self.organize_submobjects() + if self.organize_left_to_right: + self.organize_submobjects_left_to_right() def path_string_to_mobject(self, path_string): #Overwrite superclass default to use @@ -78,7 +80,7 @@ class TexMobject(SVGMobject): self.submobjects = subs return self - def organize_submobjects(self): + def organize_submobjects_left_to_right(self): self.submobjects.sort( lambda m1, m2 : int((m1.get_left()-m2.get_left())[0]) ) diff --git a/topics/characters.py b/topics/characters.py index 4a7bb2d0..bf1161b8 100644 --- a/topics/characters.py +++ b/topics/characters.py @@ -106,11 +106,11 @@ class PiCreature(SVGMobject): self.to_corner(DOWN+LEFT) return self - def get_bubble(self, bubble_type = "thought"): + def get_bubble(self, bubble_type = "thought", **kwargs): if bubble_type == "thought": - bubble = ThoughtBubble() + bubble = ThoughtBubble(**kwargs) elif bubble_type == "speech": - bubble = SpeechBubble() + bubble = SpeechBubble(**kwargs) else: raise Exception("%s is an invalid bubble type"%bubble_type) bubble.pin_to(self) @@ -191,13 +191,19 @@ class Bubble(SVGMobject): self.move_tip_to(mob_center+vector_from_center) return self - def add_content(self, mobject): - if self.content in self.submobjects: - self.submobjects.remove(self.content) + def position_mobject_inside(self, mobject): scaled_width = self.content_scale_factor*self.get_width() if mobject.get_width() > scaled_width: mobject.scale_to_fit_width(scaled_width) - mobject.shift(self.get_bubble_center()) + mobject.shift( + self.get_bubble_center() - mobject.get_center() + ) + return mobject + + def add_content(self, mobject): + if self.content in self.submobjects: + self.submobjects.remove(self.content) + self.position_mobject_inside(mobject) self.content = mobject self.add(self.content) return self diff --git a/topics/geometry.py b/topics/geometry.py index f889a62f..9676c245 100644 --- a/topics/geometry.py +++ b/topics/geometry.py @@ -142,10 +142,13 @@ class Arrow(Line): Line.__init__(self, *args, **kwargs) self.add_tip() - def add_tip(self): + def add_tip(self, add_at_end = True): vect = self.tip_length*RIGHT vect = rotate_vector(vect, self.get_angle()+np.pi) start, end = self.get_start_and_end() + if not add_at_end: + start, end = end, start + vect = -vect tip_points = [ end+rotate_vector(vect, u*np.pi/5) for u in 1, -1 @@ -175,9 +178,8 @@ class Vector(Arrow): class DoubleArrow(Arrow): def __init__(self, *args, **kwargs): Arrow.__init__(self, *args, **kwargs) - self.start, self.end = self.end, self.start - self.add_tip() - self.start, self.end = self.end, self.start + self.add_tip(add_at_end = False) + class Cross(VMobject): CONFIG = {