mirror of
https://github.com/3b1b/manim.git
synced 2025-07-31 22:13:30 +08:00
Poor man's merge
This commit is contained in:
@ -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)
|
||||||
|
|
||||||
|
@ -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]))
|
||||||
|
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
Reference in New Issue
Block a user