mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 22:03:01 +08:00
Align data and transform now working with new format
This commit is contained in:
@ -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
|
||||
)
|
||||
|
||||
|
@ -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
|
||||
families = map(
|
||||
Mobject.get_full_submobject_family,
|
||||
[self.mobject, self.starting_mobject, self.ending_mobject]
|
||||
)
|
||||
self.mobject.rgbs = straight_path(
|
||||
self.starting_mobject.rgbs,
|
||||
self.ending_mobject.rgbs,
|
||||
alpha
|
||||
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)
|
||||
|
@ -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)]:
|
||||
|
@ -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))
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user