Poor man's merge

This commit is contained in:
Grant Sanderson
2018-03-05 20:25:01 -08:00
parent 53521a623f
commit aba43479f0
3 changed files with 44 additions and 19 deletions

View File

@ -358,7 +358,6 @@ class Succession(Animation):
Each arg will either be an animation, or an animation class Each arg will either be an animation, or an animation class
followed by its arguments (and potentially a dict for followed by its arguments (and potentially a dict for
configuration). configuration).
For example, For example,
Succession( Succession(
ShowCreation(circle), ShowCreation(circle),
@ -443,13 +442,12 @@ class Succession(Animation):
# Beware: This does NOT take care of calling update(0) on the subanimation. # Beware: This does NOT take care of calling update(0) on the subanimation.
# This was important to avoid a pernicious possibility in which subanimations were called # This was important to avoid a pernicious possibility in which subanimations were called
# with update(0) twice, which could in turn call a sub-Succession with update(0) four times, # with update twice, which could in turn call a sub-Succession with update four times,
# continuing exponentially. # continuing exponentially.
def jump_to_start_of_anim(self, index): def jump_to_start_of_anim(self, index):
if index != self.current_anim_index: if index != self.current_anim_index:
self.mobject.remove(*self.mobject.submobjects) # Should probably have a cleaner "remove_all" method... self.mobject.remove(*self.mobject.submobjects) # Should probably have a cleaner "remove_all" method...
for m in self.scene_mobjects_at_time[index].submobjects: self.mobject.add(*self.scene_mobjects_at_time[index].submobjects)
self.mobject.add(m)
self.mobject.add(self.animations[index].mobject) self.mobject.add(self.animations[index].mobject)
for i in range(index): for i in range(index):
@ -459,10 +457,9 @@ class Succession(Animation):
self.current_alpha = self.critical_alphas[index] self.current_alpha = self.critical_alphas[index]
def update_mobject(self, alpha): def update_mobject(self, alpha):
if alpha == self.current_alpha:
return
if self.num_anims == 0: if self.num_anims == 0:
# This probably doesn't matter for anything, but just in case,
# we want it in the future, we set current_alpha even in this case
self.current_alpha = alpha self.current_alpha = alpha
return return
@ -505,16 +502,14 @@ class AnimationGroup(Animation):
"rate_func" : None "rate_func" : None
} }
def __init__(self, *sub_anims, **kwargs): def __init__(self, *sub_anims, **kwargs):
digest_config(self, kwargs, locals())
sub_anims = filter (lambda x : not(x.empty), sub_anims) sub_anims = filter (lambda x : not(x.empty), sub_anims)
digest_config(self, locals())
self.update_config(**kwargs) # Handles propagation to self.sub_anims
if len(sub_anims) == 0: if len(sub_anims) == 0:
self.empty = True self.empty = True
self.run_time = 0 self.run_time = 0
else: else:
for anim in sub_anims:
# If AnimationGroup is called with any configuration,
# it is propagated to the sub_animations
anim.update_config(**kwargs)
self.run_time = max([a.run_time for a in sub_anims]) self.run_time = max([a.run_time for a in sub_anims])
everything = Mobject(*[a.mobject for a in sub_anims]) everything = Mobject(*[a.mobject for a in sub_anims])
Animation.__init__(self, everything, **kwargs) Animation.__init__(self, everything, **kwargs)
@ -527,6 +522,14 @@ class AnimationGroup(Animation):
for anim in self.sub_anims: for anim in self.sub_anims:
anim.clean_up(*args, **kwargs) anim.clean_up(*args, **kwargs)
def update_config(self, **kwargs):
Animation.update_config(self, **kwargs)
# If AnimationGroup is called with any configuration,
# it is propagated to the sub_animations
for anim in self.sub_anims:
anim.update_config(**kwargs)
class EmptyAnimation(Animation): class EmptyAnimation(Animation):
CONFIG = { CONFIG = {
"run_time" : 0, "run_time" : 0,
@ -535,4 +538,3 @@ class EmptyAnimation(Animation):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
return Animation.__init__(self, Group(), *args, **kwargs) return Animation.__init__(self, Group(), *args, **kwargs)

View File

@ -54,10 +54,14 @@ class VMobject(Mobject):
if fill_opacity is not None: if fill_opacity is not None:
self.fill_opacity = fill_opacity self.fill_opacity = fill_opacity
if family: if family:
kwargs = locals()
kwargs.pop("self")
for mob in self.submobjects: for mob in self.submobjects:
mob.set_style_data(**kwargs) mob.set_style_data(
stroke_color = stroke_color,
stroke_width = stroke_width,
fill_color = fill_color,
fill_opacity = fill_opacity,
family = family
)
return self return self
def set_fill(self, color = None, opacity = None, family = True): def set_fill(self, color = None, opacity = None, family = True):
@ -244,7 +248,6 @@ class VMobject(Mobject):
a single "path", in the svg sense of the word. a single "path", in the svg sense of the word.
However, one such path may really consist of separate However, one such path may really consist of separate
continuous components if there is a move_to command. continuous components if there is a move_to command.
These other portions of the path will be treated as submobjects, These other portions of the path will be treated as submobjects,
but will be tracked in a separate special list for when but will be tracked in a separate special list for when
it comes time to display. it comes time to display.
@ -287,7 +290,6 @@ class VMobject(Mobject):
If the distance between a given handle point H and its associated If the distance between a given handle point H and its associated
anchor point A is d, then it changes H to be a distances factor*d anchor point A is d, then it changes H to be a distances factor*d
away from A, but so that the line from A to H doesn't change. away from A, but so that the line from A to H doesn't change.
This is mostly useful in the context of applying a (differentiable) This is mostly useful in the context of applying a (differentiable)
function, to preserve tangency properties. One would pull all the function, to preserve tangency properties. One would pull all the
handles closer to their anchors, apply the function then push them out handles closer to their anchors, apply the function then push them out
@ -481,4 +483,3 @@ class VectorizedPoint(VMobject):
def set_location(self,new_loc): def set_location(self,new_loc):
self.set_points(np.array([new_loc])) self.set_points(np.array([new_loc]))

View File

@ -222,6 +222,28 @@ class Axes(VGroup):
return graph return graph
def input_to_graph_point(self, x, graph): def input_to_graph_point(self, x, graph):
if hasattr(graph, "underlying_function"):
return self.coords_to_point(x, graph.underlying_function(x))
else:
#binary search
lh, rh = 0, 1
while abs(lh - rh) > 0.001:
mh = np.mean([lh, rh])
hands = [lh, mh, rh]
points = map(graph.point_from_proportion, hands)
lx, mx, rx = map(self.x_axis.point_to_number, points)
if lx <= x and rx >= x:
if mx > x:
rh = mh
else:
lh = mh
elif lx <= x and rx <= x:
return points[2]
elif lx >= x and rx >= x:
return points[0]
elif lx > x and rx < x:
lh, rh = rh, lh
return points[1]
return self.coords_to_point(x, graph.underlying_function(x)) return self.coords_to_point(x, graph.underlying_function(x))
class ThreeDAxes(Axes): class ThreeDAxes(Axes):