mirror of
https://github.com/3b1b/manim.git
synced 2025-09-01 00:48:45 +00:00
ShowPartial works for vectorized mobjects
This commit is contained in:
parent
25aa564cca
commit
9fb31e01d0
4 changed files with 98 additions and 13 deletions
|
@ -38,15 +38,7 @@ class ShowPartial(Animation):
|
||||||
self.mobject.submobject_family()
|
self.mobject.submobject_family()
|
||||||
)
|
)
|
||||||
for start, mob in pairs:
|
for start, mob in pairs:
|
||||||
lower_alpha, upper_alpha = self.get_bounds(alpha)
|
mob.become_partial(start, *self.get_bounds(alpha))
|
||||||
lower_index, upper_index = [
|
|
||||||
int(a * start.get_num_points())
|
|
||||||
for a in lower_alpha, upper_alpha
|
|
||||||
]
|
|
||||||
for attr in mob.get_array_attrs():
|
|
||||||
full_array = getattr(start, attr)
|
|
||||||
partial_array = full_array[lower_index:upper_index]
|
|
||||||
setattr(mob, attr, partial_array)
|
|
||||||
|
|
||||||
def get_bounds(self, alpha):
|
def get_bounds(self, alpha):
|
||||||
raise Exception("Not Implemented")
|
raise Exception("Not Implemented")
|
||||||
|
|
|
@ -451,6 +451,14 @@ class Mobject(object):
|
||||||
def interpolate_color(self, mobject1, mobject2, alpha):
|
def interpolate_color(self, mobject1, mobject2, alpha):
|
||||||
raise Exception("Not implemented")
|
raise Exception("Not implemented")
|
||||||
|
|
||||||
|
def become_partial(self, mobject, a, b):
|
||||||
|
"""
|
||||||
|
Set points in such a way as to become only
|
||||||
|
part of mobject.
|
||||||
|
Inputs 0 <= a < b <= 1 determine what portion
|
||||||
|
of mobject to become.
|
||||||
|
"""
|
||||||
|
raise Exception("Not implemented")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,16 @@ class PointCloudMobject(Mobject):
|
||||||
mobject1.rgbs, mobject2.rgbs, alpha
|
mobject1.rgbs, mobject2.rgbs, alpha
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def become_partial(self, mobject, a, b):
|
||||||
|
lower_index, upper_index = [
|
||||||
|
int(x * mobject.get_num_points())
|
||||||
|
for x in a, b
|
||||||
|
]
|
||||||
|
for attr in self.get_array_attrs():
|
||||||
|
full_array = getattr(mobject, attr)
|
||||||
|
partial_array = full_array[lower_index:upper_index]
|
||||||
|
setattr(self, attr, partial_array)
|
||||||
|
|
||||||
|
|
||||||
#TODO, Make the two implementations bellow non-redundant
|
#TODO, Make the two implementations bellow non-redundant
|
||||||
class Mobject1D(PointCloudMobject):
|
class Mobject1D(PointCloudMobject):
|
||||||
|
|
|
@ -132,9 +132,12 @@ class VectorizedMobject(Mobject):
|
||||||
|
|
||||||
## Information about line
|
## Information about line
|
||||||
|
|
||||||
def component_curves_iter(self):
|
def component_curves(self):
|
||||||
for i in range(0, len(self.points)-1, 3):
|
for n in range(self.get_num_points()-1):
|
||||||
yield bezier(self.points[i:i+4])
|
yield self.get_nth_curve(n)
|
||||||
|
|
||||||
|
def get_nth_curve(self, n):
|
||||||
|
return bezier(self.points[3*n:3*n+4])
|
||||||
|
|
||||||
def get_num_points(self):
|
def get_num_points(self):
|
||||||
return (len(self.points) - 1)/3 + 1
|
return (len(self.points) - 1)/3 + 1
|
||||||
|
@ -153,6 +156,7 @@ class VectorizedMobject(Mobject):
|
||||||
]
|
]
|
||||||
|
|
||||||
## Alignment
|
## Alignment
|
||||||
|
|
||||||
# def align_points_with_larger(self, larger_mobject):
|
# def align_points_with_larger(self, larger_mobject):
|
||||||
# assert(isinstance(larger_mobject, VectorizedMobject))
|
# assert(isinstance(larger_mobject, VectorizedMobject))
|
||||||
# anchors, handles1, handles2 = self.get_anchors_and_handles()
|
# anchors, handles1, handles2 = self.get_anchors_and_handles()
|
||||||
|
@ -179,7 +183,7 @@ class VectorizedMobject(Mobject):
|
||||||
#curves are buckets, and we need to know how many new
|
#curves are buckets, and we need to know how many new
|
||||||
#anchor points to put into each one
|
#anchor points to put into each one
|
||||||
index_allocation = (np.arange(target_len) * num_curves)/target_len
|
index_allocation = (np.arange(target_len) * num_curves)/target_len
|
||||||
for index, curve in enumerate(self.component_curves_iter()):
|
for index, curve in enumerate(self.component_curves()):
|
||||||
num_inter_points = sum(index_allocation == index)
|
num_inter_points = sum(index_allocation == index)
|
||||||
step = 1./num_inter_points
|
step = 1./num_inter_points
|
||||||
alphas = np.arange(0, 1+step, step)
|
alphas = np.arange(0, 1+step, step)
|
||||||
|
@ -211,6 +215,77 @@ class VectorizedMobject(Mobject):
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
def get_partial_bezier_points(self, x, pre_x = True):
|
||||||
|
"""
|
||||||
|
Input is a number number 0 <= x <= 1, which
|
||||||
|
corresponds to some point along the curve.
|
||||||
|
This point lies on some cubic. This function
|
||||||
|
return the four bezeir points giving a partial
|
||||||
|
version of that cubic. Either the part before x,
|
||||||
|
if pre_x == True, otherwise the part after x
|
||||||
|
"""
|
||||||
|
if x >= 1.0:
|
||||||
|
return np.array(4*[self.points[-1]])
|
||||||
|
num_cubics = self.get_num_points()-1
|
||||||
|
which_curve = int(x*num_cubics)
|
||||||
|
alpha = num_cubics*(x%(1./num_cubics))
|
||||||
|
cubic = self.get_nth_curve(which_curve)
|
||||||
|
new_anchor = cubic(alpha)
|
||||||
|
a1, h1, h2, a2 = self.points[3*which_curve:3*which_curve+4]
|
||||||
|
if pre_x:
|
||||||
|
return np.array([
|
||||||
|
a1,
|
||||||
|
interpolate(cubic(alpha/3), h1, alpha),
|
||||||
|
interpolate(cubic(2*alpha/3), h2, alpha),
|
||||||
|
new_anchor
|
||||||
|
])
|
||||||
|
else:
|
||||||
|
return np.array([
|
||||||
|
new_anchor,
|
||||||
|
interpolate(h1, cubic((1-alpha)/3), alpha),
|
||||||
|
interpolate(h2, cubic(2*(1-alpha/3), alpha)),
|
||||||
|
a2
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def become_partial(self, mobject, a, b):
|
||||||
|
assert(isinstance(mobject, VectorizedMobject))
|
||||||
|
#Partial curve includes three portions:
|
||||||
|
#-A middle section, which matches the curve exactly
|
||||||
|
#-A start, which is some ending portion of an inner cubic
|
||||||
|
#-An end, which is the starting portion of a later inner cubic
|
||||||
|
self.open()
|
||||||
|
if a <= 0 and b >= 1 and mobject.is_closed():
|
||||||
|
self.close()
|
||||||
|
num_cubics = mobject.get_num_points()-1
|
||||||
|
if a <= 0:
|
||||||
|
lower_index = 0
|
||||||
|
start_points = np.zeros((0, 3))
|
||||||
|
else:
|
||||||
|
lower_index = 3*int(a*num_cubics)+4
|
||||||
|
start_points = mobject.get_partial_bezier_points(
|
||||||
|
a, pre_x = False
|
||||||
|
)
|
||||||
|
if b >= 1:
|
||||||
|
upper_index = len(mobject.points)+1
|
||||||
|
end_points = np.zeros((0, 3))
|
||||||
|
else:
|
||||||
|
upper_index = 3*int(b*num_cubics)
|
||||||
|
end_points = mobject.get_partial_bezier_points(
|
||||||
|
b, pre_x = True
|
||||||
|
)
|
||||||
|
new_points = reduce(
|
||||||
|
lambda a, b : np.append(a, b, axis = 0),
|
||||||
|
[
|
||||||
|
start_points,
|
||||||
|
mobject.points[lower_index:upper_index],
|
||||||
|
end_points
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.set_points(new_points, "handles_included")
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
class VectorizedPoint(VectorizedMobject):
|
class VectorizedPoint(VectorizedMobject):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"color" : BLACK,
|
"color" : BLACK,
|
||||||
|
|
Loading…
Add table
Reference in a new issue