mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Merge branch 'master' of https://github.com/3b1b/manim
This commit is contained in:
commit
24a39c7e03
11 changed files with 124 additions and 103 deletions
33
camera.py
33
camera.py
|
@ -84,15 +84,38 @@ class Camera(object):
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.set_pixel_array(np.array(self.background))
|
self.set_pixel_array(np.array(self.background))
|
||||||
|
|
||||||
|
####
|
||||||
|
|
||||||
|
def extract_mobject_family_members(self, mobjects, only_those_with_points = False):
|
||||||
|
if only_those_with_points:
|
||||||
|
method = Mobject.family_members_with_points
|
||||||
|
else:
|
||||||
|
method = Mobject.submobject_family
|
||||||
|
return remove_list_redundancies(list(
|
||||||
|
it.chain(*[
|
||||||
|
method(m)
|
||||||
|
for m in mobjects
|
||||||
|
if not (isinstance(m, VMobject) and m.is_subpath)
|
||||||
|
])
|
||||||
|
))
|
||||||
|
|
||||||
def capture_mobject(self, mobject):
|
def capture_mobject(self, mobject):
|
||||||
return self.capture_mobjects([mobject])
|
return self.capture_mobjects([mobject])
|
||||||
|
|
||||||
def capture_mobjects(self, mobjects, include_submobjects = True):
|
def capture_mobjects(
|
||||||
|
self, mobjects,
|
||||||
|
include_submobjects = True,
|
||||||
|
excluded_mobjects = None,
|
||||||
|
):
|
||||||
if include_submobjects:
|
if include_submobjects:
|
||||||
mobjects = it.chain(*[
|
mobjects = self.extract_mobject_family_members(
|
||||||
mob.family_members_with_points()
|
mobjects, only_those_with_points = True
|
||||||
for mob in mobjects
|
)
|
||||||
])
|
if excluded_mobjects:
|
||||||
|
all_excluded = self.extract_mobject_family_members(
|
||||||
|
excluded_mobjects
|
||||||
|
)
|
||||||
|
mobjects = list_difference_update(mobjects, all_excluded)
|
||||||
vmobjects = []
|
vmobjects = []
|
||||||
for mobject in mobjects:
|
for mobject in mobjects:
|
||||||
if isinstance(mobject, VMobject):
|
if isinstance(mobject, VMobject):
|
||||||
|
|
|
@ -43,7 +43,7 @@ DEFAULT_MOBJECT_TO_MOBJECT_BUFFER = MED_SMALL_BUFF
|
||||||
#All in seconds
|
#All in seconds
|
||||||
DEFAULT_ANIMATION_RUN_TIME = 1.0
|
DEFAULT_ANIMATION_RUN_TIME = 1.0
|
||||||
DEFAULT_POINTWISE_FUNCTION_RUN_TIME = 3.0
|
DEFAULT_POINTWISE_FUNCTION_RUN_TIME = 3.0
|
||||||
DEFAULT_wait_TIME = 1.0
|
DEFAULT_WAIT_TIME = 1.0
|
||||||
|
|
||||||
|
|
||||||
ORIGIN = np.array(( 0., 0., 0.))
|
ORIGIN = np.array(( 0., 0., 0.))
|
||||||
|
|
|
@ -454,7 +454,6 @@ class Mobject(object):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def submobject_radial_gradient_highlight(self, center = None, radius = 1, inner_color = WHITE, outer_color = BLACK):
|
def submobject_radial_gradient_highlight(self, center = None, radius = 1, inner_color = WHITE, outer_color = BLACK):
|
||||||
|
|
||||||
mobs = self.family_members_with_points()
|
mobs = self.family_members_with_points()
|
||||||
if center == None:
|
if center == None:
|
||||||
center = self.get_center()
|
center = self.get_center()
|
||||||
|
@ -462,14 +461,11 @@ class Mobject(object):
|
||||||
for mob in self.family_members_with_points():
|
for mob in self.family_members_with_points():
|
||||||
t = np.linalg.norm(mob.get_center() - center)/radius
|
t = np.linalg.norm(mob.get_center() - center)/radius
|
||||||
t = min(t,1)
|
t = min(t,1)
|
||||||
print t
|
|
||||||
mob_color = interpolate_color(inner_color, outer_color, t)
|
mob_color = interpolate_color(inner_color, outer_color, t)
|
||||||
print mob_color
|
|
||||||
mob.highlight(mob_color, family = False)
|
mob.highlight(mob_color, family = False)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def set_color(self, color):
|
def set_color(self, color):
|
||||||
self.highlight(color)
|
self.highlight(color)
|
||||||
self.color = Color(color)
|
self.color = Color(color)
|
||||||
|
|
|
@ -14,8 +14,9 @@ class VMobject(Mobject):
|
||||||
"is_subpath" : False,
|
"is_subpath" : False,
|
||||||
"close_new_points" : False,
|
"close_new_points" : False,
|
||||||
"mark_paths_closed" : False,
|
"mark_paths_closed" : False,
|
||||||
"considered_smooth" : True,
|
|
||||||
"propagate_style_to_family" : False,
|
"propagate_style_to_family" : False,
|
||||||
|
"pre_function_handle_to_anchor_scale_factor" : 0.01,
|
||||||
|
"make_smooth_after_applying_functions" : False,
|
||||||
}
|
}
|
||||||
|
|
||||||
## Colors
|
## Colors
|
||||||
|
@ -191,7 +192,6 @@ class VMobject(Mobject):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def make_smooth(self):
|
def make_smooth(self):
|
||||||
self.considered_smooth = True
|
|
||||||
return self.change_anchor_mode("smooth")
|
return self.change_anchor_mode("smooth")
|
||||||
|
|
||||||
def make_jagged(self):
|
def make_jagged(self):
|
||||||
|
@ -232,12 +232,35 @@ class VMobject(Mobject):
|
||||||
self.submobjects
|
self.submobjects
|
||||||
)
|
)
|
||||||
|
|
||||||
def apply_function(self, function, maintain_smoothness = False):
|
def apply_function(self, function):
|
||||||
|
factor = self.pre_function_handle_to_anchor_scale_factor
|
||||||
|
self.scale_handle_to_anchor_distances(factor)
|
||||||
Mobject.apply_function(self, function)
|
Mobject.apply_function(self, function)
|
||||||
if maintain_smoothness and self.considered_smooth:
|
self.scale_handle_to_anchor_distances(1./factor)
|
||||||
|
if self.make_smooth_after_applying_functions:
|
||||||
self.make_smooth()
|
self.make_smooth()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def scale_handle_to_anchor_distances(self, factor):
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
again.
|
||||||
|
"""
|
||||||
|
if self.get_num_points() == 0:
|
||||||
|
return
|
||||||
|
anchors, handles1, handles2 = self.get_anchors_and_handles()
|
||||||
|
# print len(anchors), len(handles1), len(handles2)
|
||||||
|
a_to_h1 = handles1 - anchors[:-1]
|
||||||
|
a_to_h2 = handles2 - anchors[1:]
|
||||||
|
handles1 = anchors[:-1] + factor*a_to_h1
|
||||||
|
handles2 = anchors[1:] + factor*a_to_h2
|
||||||
|
self.set_anchors_and_handles(anchors, handles1, handles2)
|
||||||
|
|
||||||
## Information about line
|
## Information about line
|
||||||
|
|
||||||
|
@ -271,8 +294,7 @@ class VMobject(Mobject):
|
||||||
return self.get_anchors()
|
return self.get_anchors()
|
||||||
|
|
||||||
|
|
||||||
## Alignment
|
## Alignment
|
||||||
|
|
||||||
def align_points(self, mobject):
|
def align_points(self, mobject):
|
||||||
Mobject.align_points(self, mobject)
|
Mobject.align_points(self, mobject)
|
||||||
is_subpath = self.is_subpath or mobject.is_subpath
|
is_subpath = self.is_subpath or mobject.is_subpath
|
||||||
|
@ -280,7 +302,7 @@ class VMobject(Mobject):
|
||||||
mark_closed = self.mark_paths_closed and mobject.mark_paths_closed
|
mark_closed = self.mark_paths_closed and mobject.mark_paths_closed
|
||||||
self.mark_paths_closed = mobject.mark_paths_closed = mark_closed
|
self.mark_paths_closed = mobject.mark_paths_closed = mark_closed
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def align_points_with_larger(self, larger_mobject):
|
def align_points_with_larger(self, larger_mobject):
|
||||||
assert(isinstance(larger_mobject, VMobject))
|
assert(isinstance(larger_mobject, VMobject))
|
||||||
self.insert_n_anchor_points(
|
self.insert_n_anchor_points(
|
||||||
|
@ -288,7 +310,7 @@ class VMobject(Mobject):
|
||||||
self.get_num_anchor_points()
|
self.get_num_anchor_points()
|
||||||
)
|
)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def insert_n_anchor_points(self, n):
|
def insert_n_anchor_points(self, n):
|
||||||
curr = self.get_num_anchor_points()
|
curr = self.get_num_anchor_points()
|
||||||
if curr == 0:
|
if curr == 0:
|
||||||
|
@ -318,17 +340,17 @@ class VMobject(Mobject):
|
||||||
)
|
)
|
||||||
self.set_points(points)
|
self.set_points(points)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def get_point_mobject(self, center = None):
|
def get_point_mobject(self, center = None):
|
||||||
if center is None:
|
if center is None:
|
||||||
center = self.get_center()
|
center = self.get_center()
|
||||||
return VectorizedPoint(center)
|
return VectorizedPoint(center)
|
||||||
|
|
||||||
def repeat_submobject(self, submobject):
|
def repeat_submobject(self, submobject):
|
||||||
if submobject.is_subpath:
|
if submobject.is_subpath:
|
||||||
return VectorizedPoint(submobject.points[0])
|
return VectorizedPoint(submobject.points[0])
|
||||||
return submobject.copy()
|
return submobject.copy()
|
||||||
|
|
||||||
def interpolate_color(self, mobject1, mobject2, alpha):
|
def interpolate_color(self, mobject1, mobject2, alpha):
|
||||||
attrs = [
|
attrs = [
|
||||||
"stroke_rgb",
|
"stroke_rgb",
|
||||||
|
@ -345,7 +367,7 @@ class VMobject(Mobject):
|
||||||
if alpha == 1.0:
|
if alpha == 1.0:
|
||||||
# print getattr(mobject2, attr)
|
# print getattr(mobject2, attr)
|
||||||
setattr(self, attr, getattr(mobject2, attr))
|
setattr(self, attr, getattr(mobject2, attr))
|
||||||
|
|
||||||
def pointwise_become_partial(self, mobject, a, b):
|
def pointwise_become_partial(self, mobject, a, b):
|
||||||
assert(isinstance(mobject, VMobject))
|
assert(isinstance(mobject, VMobject))
|
||||||
#Partial curve includes three portions:
|
#Partial curve includes three portions:
|
||||||
|
|
|
@ -123,19 +123,23 @@ class Scene(object):
|
||||||
def capture_mobjects_in_camera(self, mobjects, **kwargs):
|
def capture_mobjects_in_camera(self, mobjects, **kwargs):
|
||||||
self.camera.capture_mobjects(mobjects, **kwargs)
|
self.camera.capture_mobjects(mobjects, **kwargs)
|
||||||
|
|
||||||
def update_frame(self, mobjects = None, background = None, **kwargs):
|
def update_frame(
|
||||||
if "include_submobjects" not in kwargs:
|
self,
|
||||||
kwargs["include_submobjects"] = False
|
mobjects = None,
|
||||||
|
background = None,
|
||||||
|
include_submobjects = True,
|
||||||
|
**kwargs):
|
||||||
if mobjects is None:
|
if mobjects is None:
|
||||||
mobjects = list_update(
|
mobjects = list_update(
|
||||||
self.foreground_mobjects,
|
|
||||||
self.mobjects,
|
self.mobjects,
|
||||||
|
self.foreground_mobjects,
|
||||||
)
|
)
|
||||||
if background is not None:
|
if background is not None:
|
||||||
self.set_camera_pixel_array(background)
|
self.set_camera_pixel_array(background)
|
||||||
else:
|
else:
|
||||||
self.reset_camera()
|
self.reset_camera()
|
||||||
|
|
||||||
|
kwargs["include_submobjects"] = include_submobjects
|
||||||
self.capture_mobjects_in_camera(mobjects, **kwargs)
|
self.capture_mobjects_in_camera(mobjects, **kwargs)
|
||||||
|
|
||||||
def freeze_background(self):
|
def freeze_background(self):
|
||||||
|
@ -167,15 +171,6 @@ class Scene(object):
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
def extract_mobject_family_members(self, *mobjects):
|
|
||||||
return remove_list_redundancies(list(
|
|
||||||
it.chain(*[
|
|
||||||
m.submobject_family()
|
|
||||||
for m in mobjects
|
|
||||||
if not (isinstance(m, VMobject) and m.is_subpath)
|
|
||||||
])
|
|
||||||
))
|
|
||||||
|
|
||||||
def get_top_level_mobjects(self):
|
def get_top_level_mobjects(self):
|
||||||
# Return only those which are not in the family
|
# Return only those which are not in the family
|
||||||
# of another mobject from the scene
|
# of another mobject from the scene
|
||||||
|
@ -209,14 +204,10 @@ class Scene(object):
|
||||||
"""
|
"""
|
||||||
Mobjects will be displayed, from background to foreground,
|
Mobjects will be displayed, from background to foreground,
|
||||||
in the order with which they are entered.
|
in the order with which they are entered.
|
||||||
|
|
||||||
Scene class keeps track not just of the mobject directly added,
|
|
||||||
but also of every family member therein.
|
|
||||||
"""
|
"""
|
||||||
mobjects, continual_animations = self.separate_mobjects_and_continual_animations(
|
mobjects, continual_animations = self.separate_mobjects_and_continual_animations(
|
||||||
mobjects_or_continual_animations
|
mobjects_or_continual_animations
|
||||||
)
|
)
|
||||||
mobjects = self.extract_mobject_family_members(*mobjects)
|
|
||||||
self.mobjects = list_update(self.mobjects, mobjects)
|
self.mobjects = list_update(self.mobjects, mobjects)
|
||||||
self.continual_animations = list_update(
|
self.continual_animations = list_update(
|
||||||
self.continual_animations, continual_animations
|
self.continual_animations, continual_animations
|
||||||
|
@ -236,31 +227,38 @@ class Scene(object):
|
||||||
mobjects, continual_animations = self.separate_mobjects_and_continual_animations(
|
mobjects, continual_animations = self.separate_mobjects_and_continual_animations(
|
||||||
mobjects_or_continual_animations
|
mobjects_or_continual_animations
|
||||||
)
|
)
|
||||||
mobjects = self.extract_mobject_family_members(*mobjects)
|
to_remove = self.camera.extract_mobject_family_members(mobjects)
|
||||||
self.mobjects = filter(
|
|
||||||
lambda m : m not in mobjects,
|
|
||||||
self.mobjects
|
|
||||||
)
|
|
||||||
self.remove_mobjects_not_completely_on_screen()
|
|
||||||
self.remove_foreground_mobjects(*mobjects)
|
|
||||||
|
|
||||||
|
self.mobjects = self.get_restructured_mobject_list(self.mobjects, to_remove)
|
||||||
|
self.foreground_mobjects = self.get_restructured_mobject_list(
|
||||||
|
self.foreground_mobjects, to_remove
|
||||||
|
)
|
||||||
self.continual_animations = filter(
|
self.continual_animations = filter(
|
||||||
lambda ca : ca not in continual_animations and \
|
lambda ca : ca not in continual_animations and \
|
||||||
ca.mobject not in mobjects,
|
ca.mobject not in to_remove,
|
||||||
self.continual_animations
|
self.continual_animations
|
||||||
)
|
)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def remove_mobjects_not_completely_on_screen(self):
|
def get_restructured_mobject_list(self, mobjects, to_remove):
|
||||||
def should_keep(mobject):
|
"""
|
||||||
return all([
|
In cases where the scene contains a group, e.g. Group(m1, m2, m3), but one
|
||||||
submob in self.mobjects
|
of its submobjects is removed, e.g. scene.remove(m1), the list of mobjects
|
||||||
for submob in mobject.family_members_with_points()
|
will be editing to contain other submobjects, but not m1, e.g. it will now
|
||||||
])
|
insert m2 and m3 to where the group once was.
|
||||||
|
"""
|
||||||
self.mobjects = filter(should_keep, self.mobjects)
|
new_mobjects = []
|
||||||
return self
|
def add_safe_mobjects_from_list(list_to_examine, set_to_remove):
|
||||||
|
for mob in list_to_examine:
|
||||||
|
if mob in set_to_remove:
|
||||||
|
continue
|
||||||
|
intersect = set_to_remove.intersection(mob.submobject_family())
|
||||||
|
if intersect:
|
||||||
|
add_safe_mobjects_from_list(mob.submobjects, intersect)
|
||||||
|
else:
|
||||||
|
new_mobjects.append(mob)
|
||||||
|
add_safe_mobjects_from_list(mobjects, set(to_remove))
|
||||||
|
return new_mobjects
|
||||||
|
|
||||||
def add_foreground_mobjects(self, *mobjects):
|
def add_foreground_mobjects(self, *mobjects):
|
||||||
self.foreground_mobjects = list_update(
|
self.foreground_mobjects = list_update(
|
||||||
|
@ -274,9 +272,9 @@ class Scene(object):
|
||||||
return self.add_foreground_mobjects(mobject)
|
return self.add_foreground_mobjects(mobject)
|
||||||
|
|
||||||
def remove_foreground_mobjects(self, *mobjects):
|
def remove_foreground_mobjects(self, *mobjects):
|
||||||
self.foreground_mobjects = filter(
|
self.foreground_mobjects = get_restructured_mobject_list(
|
||||||
lambda m : m not in mobjects,
|
self.foreground_mobjects,
|
||||||
self.foreground_mobjects
|
self.camera.extract_mobject_family_members(mobjects)
|
||||||
)
|
)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -289,7 +287,7 @@ class Scene(object):
|
||||||
|
|
||||||
def bring_to_back(self, *mobjects):
|
def bring_to_back(self, *mobjects):
|
||||||
self.remove(*mobjects)
|
self.remove(*mobjects)
|
||||||
self.mobjects = mobjects + self.mobjects
|
self.mobjects = list(mobjects) + self.mobjects
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
|
@ -304,17 +302,13 @@ class Scene(object):
|
||||||
def get_mobject_copies(self):
|
def get_mobject_copies(self):
|
||||||
return [m.copy() for m in self.mobjects]
|
return [m.copy() for m in self.mobjects]
|
||||||
|
|
||||||
def separate_moving_and_static_mobjects(self, *animations):
|
def get_moving_mobjects(self, *animations):
|
||||||
moving_mobjects = self.extract_mobject_family_members(*it.chain(
|
moving_mobjects = list(it.chain(
|
||||||
[anim.mobject for anim in animations],
|
[anim.mobject for anim in animations],
|
||||||
[ca.mobject for ca in self.continual_animations],
|
[ca.mobject for ca in self.continual_animations],
|
||||||
self.foreground_mobjects,
|
self.foreground_mobjects,
|
||||||
))
|
))
|
||||||
static_mobjects = filter(
|
return moving_mobjects
|
||||||
lambda m : m not in moving_mobjects,
|
|
||||||
self.mobjects
|
|
||||||
)
|
|
||||||
return moving_mobjects, static_mobjects
|
|
||||||
|
|
||||||
def get_time_progression(self, run_time):
|
def get_time_progression(self, run_time):
|
||||||
times = np.arange(0, run_time, self.frame_duration)
|
times = np.arange(0, run_time, self.frame_duration)
|
||||||
|
@ -395,9 +389,8 @@ class Scene(object):
|
||||||
self.num_plays += 1
|
self.num_plays += 1
|
||||||
|
|
||||||
sync_animation_run_times_and_rate_funcs(*animations, **kwargs)
|
sync_animation_run_times_and_rate_funcs(*animations, **kwargs)
|
||||||
moving_mobjects, static_mobjects = \
|
moving_mobjects = self.get_moving_mobjects(*animations)
|
||||||
self.separate_moving_and_static_mobjects(*animations)
|
self.update_frame(excluded_mobjects = moving_mobjects)
|
||||||
self.update_frame(static_mobjects)
|
|
||||||
static_image = self.get_frame()
|
static_image = self.get_frame()
|
||||||
for t in self.get_animation_time_progression(animations):
|
for t in self.get_animation_time_progression(animations):
|
||||||
for animation in animations:
|
for animation in animations:
|
||||||
|
@ -422,7 +415,7 @@ class Scene(object):
|
||||||
return self.mobjects_from_last_animation
|
return self.mobjects_from_last_animation
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def wait(self, duration = DEFAULT_wait_TIME):
|
def wait(self, duration = DEFAULT_WAIT_TIME):
|
||||||
if self.skip_animations:
|
if self.skip_animations:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@ -527,3 +520,7 @@ class Scene(object):
|
||||||
shutil.move(*self.args_to_rename_file)
|
shutil.move(*self.args_to_rename_file)
|
||||||
else:
|
else:
|
||||||
os.rename(*self.args_to_rename_file)
|
os.rename(*self.args_to_rename_file)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -122,15 +122,13 @@ class ZoomedScene(Scene):
|
||||||
self.zoomed_camera.capture_mobjects(
|
self.zoomed_camera.capture_mobjects(
|
||||||
mobjects, **kwargs
|
mobjects, **kwargs
|
||||||
)
|
)
|
||||||
def separate_moving_and_static_mobjects(self, *animations):
|
def get_moving_mobjects(self, *animations):
|
||||||
moving_mobjects, static_mobjects = Scene.separate_moving_and_static_mobjects(
|
moving_mobjects = Scene.get_moving_mobjects(self, *animations)
|
||||||
self, *animations
|
|
||||||
)
|
|
||||||
if self.zoom_activated and self.little_rectangle in moving_mobjects:
|
if self.zoom_activated and self.little_rectangle in moving_mobjects:
|
||||||
# When the camera is moving, so is everything,
|
# When the camera is moving, so is everything,
|
||||||
return self.get_mobjects(), []
|
return self.mobjects
|
||||||
else:
|
else:
|
||||||
return moving_mobjects, static_mobjects
|
return moving_mobjects
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,6 @@ class Sector(VMobject):
|
||||||
class Line(VMobject):
|
class Line(VMobject):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"buff" : 0,
|
"buff" : 0,
|
||||||
"considered_smooth" : False,
|
|
||||||
"path_arc" : None,
|
"path_arc" : None,
|
||||||
"n_arc_anchors" : 10, #Only used if path_arc is not None
|
"n_arc_anchors" : 10, #Only used if path_arc is not None
|
||||||
}
|
}
|
||||||
|
@ -132,7 +131,6 @@ class Line(VMobject):
|
||||||
path_func(self.start, self.end, alpha)
|
path_func(self.start, self.end, alpha)
|
||||||
for alpha in np.linspace(0, 1, self.n_arc_anchors)
|
for alpha in np.linspace(0, 1, self.n_arc_anchors)
|
||||||
])
|
])
|
||||||
self.considered_smooth = True
|
|
||||||
self.account_for_buff()
|
self.account_for_buff()
|
||||||
|
|
||||||
def account_for_buff(self):
|
def account_for_buff(self):
|
||||||
|
@ -449,7 +447,6 @@ class Polygon(VMobject):
|
||||||
"color" : GREEN_D,
|
"color" : GREEN_D,
|
||||||
"mark_paths_closed" : True,
|
"mark_paths_closed" : True,
|
||||||
"close_new_points" : True,
|
"close_new_points" : True,
|
||||||
"considered_smooth" : False,
|
|
||||||
}
|
}
|
||||||
def __init__(self, *vertices, **kwargs):
|
def __init__(self, *vertices, **kwargs):
|
||||||
assert len(vertices) > 1
|
assert len(vertices) > 1
|
||||||
|
@ -479,7 +476,6 @@ class Rectangle(VMobject):
|
||||||
"width" : 4.0,
|
"width" : 4.0,
|
||||||
"mark_paths_closed" : True,
|
"mark_paths_closed" : True,
|
||||||
"close_new_points" : True,
|
"close_new_points" : True,
|
||||||
"considered_smooth" : False,
|
|
||||||
}
|
}
|
||||||
def generate_points(self):
|
def generate_points(self):
|
||||||
y, x = self.height/2., self.width/2.
|
y, x = self.height/2., self.width/2.
|
||||||
|
@ -586,7 +582,6 @@ class Grid(VMobject):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"height" : 6.0,
|
"height" : 6.0,
|
||||||
"width" : 6.0,
|
"width" : 6.0,
|
||||||
"considered_smooth" : False,
|
|
||||||
}
|
}
|
||||||
def __init__(self, rows, columns, **kwargs):
|
def __init__(self, rows, columns, **kwargs):
|
||||||
digest_config(self, kwargs, locals())
|
digest_config(self, kwargs, locals())
|
||||||
|
|
|
@ -223,6 +223,7 @@ class NumberPlane(VMobject):
|
||||||
"secondary_line_ratio" : 1,
|
"secondary_line_ratio" : 1,
|
||||||
"written_coordinate_height" : 0.2,
|
"written_coordinate_height" : 0.2,
|
||||||
"propagate_style_to_family" : False,
|
"propagate_style_to_family" : False,
|
||||||
|
"make_smooth_after_applying_functions" : True,
|
||||||
}
|
}
|
||||||
def generate_points(self):
|
def generate_points(self):
|
||||||
if self.x_radius is None:
|
if self.x_radius is None:
|
||||||
|
@ -360,9 +361,6 @@ class NumberPlane(VMobject):
|
||||||
mob.make_smooth()
|
mob.make_smooth()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def apply_function(self, function, maintain_smoothness = True):
|
|
||||||
VMobject.apply_function(self, function, maintain_smoothness = maintain_smoothness)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -67,8 +67,9 @@ class ChangingDecimal(Animation):
|
||||||
for x in range(self.spare_parts)]
|
for x in range(self.spare_parts)]
|
||||||
)
|
)
|
||||||
if self.tracked_mobject:
|
if self.tracked_mobject:
|
||||||
self.diff_from_tracked_mobject = \
|
dmc = decimal_number_mobject.get_center()
|
||||||
decimal_number_mobject.get_center() - self.tracked_mobject.get_center()
|
tmc = self.tracked_mobject.get_center()
|
||||||
|
self.diff_from_tracked_mobject = dmc - tmc
|
||||||
Animation.__init__(self, decimal_number_mobject, **kwargs)
|
Animation.__init__(self, decimal_number_mobject, **kwargs)
|
||||||
|
|
||||||
def update_mobject(self, alpha):
|
def update_mobject(self, alpha):
|
||||||
|
@ -85,14 +86,9 @@ class ChangingDecimal(Animation):
|
||||||
)
|
)
|
||||||
new_decimal.replace(decimal, dim_to_match = 1)
|
new_decimal.replace(decimal, dim_to_match = 1)
|
||||||
new_decimal.highlight(decimal.get_color())
|
new_decimal.highlight(decimal.get_color())
|
||||||
decimal.align_data(new_decimal)
|
|
||||||
families = [
|
decimal.submobjects = new_decimal.submobjects
|
||||||
mob.family_members_with_points()
|
decimal.number = new_number
|
||||||
for mob in decimal, new_decimal
|
|
||||||
]
|
|
||||||
for sm1, sm2 in zip(*families):
|
|
||||||
sm1.interpolate(sm1, sm2, 1)
|
|
||||||
self.mobject.number = new_number
|
|
||||||
|
|
||||||
def update_position(self):
|
def update_position(self):
|
||||||
if self.position_update_func is not None:
|
if self.position_update_func is not None:
|
||||||
|
|
|
@ -267,7 +267,6 @@ class VideoIcon(SVGMobject):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
"file_name" : "video_icon",
|
"file_name" : "video_icon",
|
||||||
"width" : 2*SPACE_WIDTH/12.,
|
"width" : 2*SPACE_WIDTH/12.,
|
||||||
"considered_smooth" : False,
|
|
||||||
}
|
}
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
SVGMobject.__init__(self, **kwargs)
|
SVGMobject.__init__(self, **kwargs)
|
||||||
|
@ -275,8 +274,6 @@ class VideoIcon(SVGMobject):
|
||||||
self.scale_to_fit_width(self.width)
|
self.scale_to_fit_width(self.width)
|
||||||
self.set_stroke(color = WHITE, width = 0)
|
self.set_stroke(color = WHITE, width = 0)
|
||||||
self.set_fill(color = WHITE, opacity = 1)
|
self.set_fill(color = WHITE, opacity = 1)
|
||||||
for mob in self:
|
|
||||||
mob.considered_smooth = False
|
|
||||||
|
|
||||||
class VideoSeries(VGroup):
|
class VideoSeries(VGroup):
|
||||||
CONFIG = {
|
CONFIG = {
|
||||||
|
|
|
@ -175,11 +175,10 @@ class ThreeDScene(Scene):
|
||||||
if is_camera_rotating:
|
if is_camera_rotating:
|
||||||
self.add(self.ambient_camera_rotation)
|
self.add(self.ambient_camera_rotation)
|
||||||
|
|
||||||
def separate_moving_and_static_mobjects(self, *animations):
|
def get_moving_mobjects(self, *animations):
|
||||||
moving, static = Scene.separate_moving_and_static_mobjects(self, *animations)
|
|
||||||
if self.camera.rotation_mobject in moving:
|
if self.camera.rotation_mobject in moving:
|
||||||
return moving + static, []
|
return self.mobjects
|
||||||
return moving, static
|
return Scene.get_moving_mobjects(self, *animations)
|
||||||
|
|
||||||
##############
|
##############
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue