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
|
||||
followed by its arguments (and potentially a dict for
|
||||
configuration).
|
||||
|
||||
For example,
|
||||
Succession(
|
||||
ShowCreation(circle),
|
||||
@ -443,13 +442,12 @@ class Succession(Animation):
|
||||
|
||||
# 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
|
||||
# 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.
|
||||
def jump_to_start_of_anim(self, index):
|
||||
if index != self.current_anim_index:
|
||||
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(m)
|
||||
self.mobject.add(*self.scene_mobjects_at_time[index].submobjects)
|
||||
self.mobject.add(self.animations[index].mobject)
|
||||
|
||||
for i in range(index):
|
||||
@ -459,10 +457,9 @@ class Succession(Animation):
|
||||
self.current_alpha = self.critical_alphas[index]
|
||||
|
||||
def update_mobject(self, alpha):
|
||||
if alpha == self.current_alpha:
|
||||
return
|
||||
|
||||
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
|
||||
return
|
||||
|
||||
@ -505,16 +502,14 @@ class AnimationGroup(Animation):
|
||||
"rate_func" : None
|
||||
}
|
||||
def __init__(self, *sub_anims, **kwargs):
|
||||
digest_config(self, kwargs, locals())
|
||||
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:
|
||||
self.empty = True
|
||||
self.run_time = 0
|
||||
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])
|
||||
everything = Mobject(*[a.mobject for a in sub_anims])
|
||||
Animation.__init__(self, everything, **kwargs)
|
||||
@ -527,6 +522,14 @@ class AnimationGroup(Animation):
|
||||
for anim in self.sub_anims:
|
||||
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):
|
||||
CONFIG = {
|
||||
"run_time" : 0,
|
||||
@ -535,4 +538,3 @@ class EmptyAnimation(Animation):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
return Animation.__init__(self, Group(), *args, **kwargs)
|
||||
|
||||
|
@ -54,10 +54,14 @@ class VMobject(Mobject):
|
||||
if fill_opacity is not None:
|
||||
self.fill_opacity = fill_opacity
|
||||
if family:
|
||||
kwargs = locals()
|
||||
kwargs.pop("self")
|
||||
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
|
||||
|
||||
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.
|
||||
However, one such path may really consist of separate
|
||||
continuous components if there is a move_to command.
|
||||
|
||||
These other portions of the path will be treated as submobjects,
|
||||
but will be tracked in a separate special list for when
|
||||
it comes time to display.
|
||||
@ -287,7 +290,6 @@ class VMobject(Mobject):
|
||||
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
|
||||
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)
|
||||
function, to preserve tangency properties. One would pull all the
|
||||
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):
|
||||
self.set_points(np.array([new_loc]))
|
||||
|
||||
|
||||
|
@ -222,6 +222,28 @@ class Axes(VGroup):
|
||||
return 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))
|
||||
|
||||
class ThreeDAxes(Axes):
|
||||
|
Reference in New Issue
Block a user