diff --git a/animation/simple_animations.py b/animation/simple_animations.py index e4c28a55..2a39e4af 100644 --- a/animation/simple_animations.py +++ b/animation/simple_animations.py @@ -69,10 +69,9 @@ class Flash(Animation): def update_mobject(self, alpha): #Makes alpha go from 0 to slow_factor to 0 instead of 0 to 1 alpha = self.slow_factor * (1.0 - 4 * (alpha - 0.5)**2) - Mobject.interpolate( + self.mobject.interpolate( self.starting_mobject, self.intermediate, - self.mobject, alpha ) diff --git a/animation/transform.py b/animation/transform.py index 1ab3a7ca..c9258e66 100644 --- a/animation/transform.py +++ b/animation/transform.py @@ -41,16 +41,16 @@ class Transform(Animation): self.non_redundant_m2_indices = indices def update_mobject(self, alpha): - self.mobject.points = self.interpolation_function( - self.starting_mobject.points, - self.ending_mobject.points, - alpha - ) - self.mobject.rgbs = straight_path( - self.starting_mobject.rgbs, - self.ending_mobject.rgbs, - alpha + families = map( + Mobject.get_full_submobject_family, + [self.mobject, self.starting_mobject, self.ending_mobject] ) + for m, start, end in zip(*families): + m.points = self.interpolation_function( + start.points, end.points, alpha + ) + m.rgbs = straight_path(start.rgbs, end.rgbs, alpha) + def clean_up(self): Animation.clean_up(self) diff --git a/generate_logo.py b/generate_logo.py index f83a0a66..31bb3e1b 100644 --- a/generate_logo.py +++ b/generate_logo.py @@ -46,8 +46,8 @@ class LogoGeneration(Scene): sphere.rotate(-np.pi / 7, [1, 0, 0]) sphere.rotate(-np.pi / 7) iris = Mobject() - Mobject.interpolate( - circle, sphere, iris, + iris.interpolate( + circle, sphere, self.interpolation_factor ) for mob, color in [(iris, self.sphere_brown), (circle, self.circle_brown)]: diff --git a/helpers.py b/helpers.py index 5f23a1b7..60bee399 100644 --- a/helpers.py +++ b/helpers.py @@ -190,6 +190,13 @@ def invert_image(image): arr = (255 * np.ones(arr.shape)).astype(arr.dtype) - arr return Image.fromarray(arr) +def streth_array_to_length(nparray, length): + curr_len = len(nparray) + if curr_len > length: + raise Warning("Trying to stretch array to a length shorter than its own") + indices = np.arange(length)/ (float(length)/curr_len) + return nparray[indices.astype('int')] + def make_even(iterable_1, iterable_2): list_1, list_2 = list(iterable_1), list(iterable_2) length = max(len(list_1), len(list_2)) diff --git a/mobject/mobject.py b/mobject/mobject.py index fd84190a..9b66dd67 100644 --- a/mobject/mobject.py +++ b/mobject/mobject.py @@ -92,7 +92,7 @@ class Mobject(object): def apply_over_attr_arrays(self, func): - for attr in self.get_array_attrs(self): + for attr in self.get_array_attrs(): setattr(self, attr, func(getattr(self, attr))) return self @@ -325,7 +325,7 @@ class Mobject(object): def ingest_sub_mobjects(self): for attr in self.get_array_attrs(): - setattr(self, attr, get_merged_array(attr)) + setattr(self, attr, self.get_merged_array(attr)) self.sub_mobjects = [] return self @@ -411,24 +411,51 @@ class Mobject(object): #Typically implemented in subclass, unless purposefully left blank pass - def align_data(self, mobject): - count1, count2 = self.get_num_points(), mobject.get_num_points() - if count1 == 0: - self.add_points([(0, 0, 0)]) - if count2 == 0: - mobject.add_points([(0, 0, 0)]) - if count1 == count2: - return - for attr in ['points', 'rgbs']: - new_arrays = make_even(getattr(self, attr), getattr(mobject, attr)) - for array, mobject in zip(new_arrays, [self, mobject]): - setattr(mobject, attr, np.array(array)) + @staticmethod + def align_data(mobject1, mobject2): + count1 = len(mobject1.points) + count2 = len(mobject2.points) + if count1 != count2: + if count1 < count2: + smaller = mobject1 + target_size = count2 + else: + smaller = mobject2 + target_size = count1 + if len(smaller.points) == 0: + smaller.add_points([np.zeros(smaller.DIM)]) + smaller.apply_over_attr_arrays( + lambda a : streth_array_to_length(a, target_size) + ) - def interpolate(mobject1, mobject2, target_mobject, alpha): + num_sub_mobjects1 = len(mobject1.sub_mobjects) + num_sub_mobjects2 = len(mobject2.sub_mobjects) + if num_sub_mobjects1 != num_sub_mobjects2: + diff = abs(num_sub_mobjects1 - num_sub_mobjects2) + if num_sub_mobjects1 < num_sub_mobjects2: + larger, smaller = mobject2, mobject1 + else: + larger, smaller = mobject1, mobject2 + for sub_mob in larger.sub_mobjects[-diff:]: + center = sub_mob.get_center() + point_distances = np.apply_along_axis( + lambda p : np.linalg.norm(p - center), + 1, larger.points + ) + index = np.argmin(point_distances) + smaller.add(Point( + smaller.points[index], + color = Color(rgb = smaller.rgbs[index]) + )) + for m1, m2 in zip(mobject1.sub_mobjects, mobject2.sub_mobjects): + Mobject.align_data(m1, m2) + + def interpolate(self, mobject1, mobject2, alpha): """ Turns target_mobject into an interpolation between mobject1 and mobject2. """ + #TODO Mobject.align_data(mobject1, mobject2) for attr in self.get_array_attrs(): setattr(target_mobject, attr, interpolate( diff --git a/mobject/tex_mobject.py b/mobject/tex_mobject.py index 4689ac61..7eb5d685 100644 --- a/mobject/tex_mobject.py +++ b/mobject/tex_mobject.py @@ -28,7 +28,10 @@ class TexMobject(Mobject): self.template_tex_file ) for image_file in image_files: - self.add(ImageMobject(image_file)) + self.add(ImageMobject(image_file, should_center = False)) + if len(image_files) == 1: + ## Single image should be the mobject, not a sub_mobject + self.ingest_sub_mobjects() if self.should_center: self.center() self.highlight(self.color) @@ -55,7 +58,7 @@ class Underbrace(TexMobject): def tex_hash(expression, size): - return str(hash(expression + size)) + return str(hash("".join(expression) + size)) def tex_to_image_files(expression, size, template_tex_file): """ @@ -139,8 +142,12 @@ def get_sorted_image_list(images_dir): ], cmp_enumerated_files) def cmp_enumerated_files(name1, name2): + name1, name2 = [ + os.path.split(name)[1].replace(".png", "") + for name in name1, name2 + ] num1, num2 = [ - int(name.split(".")[0].split("-")[-1]) + int(name.split("-")[-1]) for name in (name1, name2) ] return num1 - num2 diff --git a/old_projects/tau_poem.py b/old_projects/tau_poem.py index f63ebf9a..f08cfc80 100644 --- a/old_projects/tau_poem.py +++ b/old_projects/tau_poem.py @@ -195,10 +195,9 @@ class TauPoem(Scene): tau = TauCreature() tau.to_symbol() sphere = Mobject() - Mobject.interpolate( + sphere.interpolate( two_pi, Sphere().highlight("yellow"), - sphere, 0.8 ) self.add(two_pi) diff --git a/scene/scene.py b/scene/scene.py index efcda548..e781b29e 100644 --- a/scene/scene.py +++ b/scene/scene.py @@ -183,6 +183,7 @@ class Scene(object): self.frames.append(new_frame) for animation in animations: animation.clean_up() + self.add(*moving_mobjects) self.repaint_mojects() progress_bar.finish() return self