mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Changed how functions are applied to vectorized mobjects to handle smoothness issues more cleanly
This commit is contained in:
parent
1b67abd8a9
commit
f64c076e7e
4 changed files with 35 additions and 23 deletions
|
@ -14,8 +14,9 @@ class VMobject(Mobject):
|
|||
"is_subpath" : False,
|
||||
"close_new_points" : False,
|
||||
"mark_paths_closed" : False,
|
||||
"considered_smooth" : True,
|
||||
"propagate_style_to_family" : False,
|
||||
"pre_function_handle_to_anchor_scale_factor" : 0.01,
|
||||
"make_smooth_after_applying_functions" : False,
|
||||
}
|
||||
|
||||
## Colors
|
||||
|
@ -191,7 +192,6 @@ class VMobject(Mobject):
|
|||
return self
|
||||
|
||||
def make_smooth(self):
|
||||
self.considered_smooth = True
|
||||
return self.change_anchor_mode("smooth")
|
||||
|
||||
def make_jagged(self):
|
||||
|
@ -232,12 +232,35 @@ class VMobject(Mobject):
|
|||
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)
|
||||
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()
|
||||
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
|
||||
|
||||
|
@ -272,7 +295,6 @@ class VMobject(Mobject):
|
|||
|
||||
|
||||
## Alignment
|
||||
|
||||
def align_points(self, mobject):
|
||||
Mobject.align_points(self, mobject)
|
||||
is_subpath = self.is_subpath or mobject.is_subpath
|
||||
|
|
|
@ -114,7 +114,6 @@ class Sector(VMobject):
|
|||
class Line(VMobject):
|
||||
CONFIG = {
|
||||
"buff" : 0,
|
||||
"considered_smooth" : False,
|
||||
"path_arc" : 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)
|
||||
for alpha in np.linspace(0, 1, self.n_arc_anchors)
|
||||
])
|
||||
self.considered_smooth = True
|
||||
self.account_for_buff()
|
||||
|
||||
def account_for_buff(self):
|
||||
|
@ -449,7 +447,6 @@ class Polygon(VMobject):
|
|||
"color" : GREEN_D,
|
||||
"mark_paths_closed" : True,
|
||||
"close_new_points" : True,
|
||||
"considered_smooth" : False,
|
||||
}
|
||||
def __init__(self, *vertices, **kwargs):
|
||||
assert len(vertices) > 1
|
||||
|
@ -479,7 +476,6 @@ class Rectangle(VMobject):
|
|||
"width" : 4.0,
|
||||
"mark_paths_closed" : True,
|
||||
"close_new_points" : True,
|
||||
"considered_smooth" : False,
|
||||
}
|
||||
def generate_points(self):
|
||||
y, x = self.height/2., self.width/2.
|
||||
|
@ -586,7 +582,6 @@ class Grid(VMobject):
|
|||
CONFIG = {
|
||||
"height" : 6.0,
|
||||
"width" : 6.0,
|
||||
"considered_smooth" : False,
|
||||
}
|
||||
def __init__(self, rows, columns, **kwargs):
|
||||
digest_config(self, kwargs, locals())
|
||||
|
|
|
@ -223,6 +223,7 @@ class NumberPlane(VMobject):
|
|||
"secondary_line_ratio" : 1,
|
||||
"written_coordinate_height" : 0.2,
|
||||
"propagate_style_to_family" : False,
|
||||
"make_smooth_after_applying_functions" : True,
|
||||
}
|
||||
def generate_points(self):
|
||||
if self.x_radius is None:
|
||||
|
@ -360,9 +361,6 @@ class NumberPlane(VMobject):
|
|||
mob.make_smooth()
|
||||
return self
|
||||
|
||||
def apply_function(self, function, maintain_smoothness = True):
|
||||
VMobject.apply_function(self, function, maintain_smoothness = maintain_smoothness)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -267,7 +267,6 @@ class VideoIcon(SVGMobject):
|
|||
CONFIG = {
|
||||
"file_name" : "video_icon",
|
||||
"width" : 2*SPACE_WIDTH/12.,
|
||||
"considered_smooth" : False,
|
||||
}
|
||||
def __init__(self, **kwargs):
|
||||
SVGMobject.__init__(self, **kwargs)
|
||||
|
@ -275,8 +274,6 @@ class VideoIcon(SVGMobject):
|
|||
self.scale_to_fit_width(self.width)
|
||||
self.set_stroke(color = WHITE, width = 0)
|
||||
self.set_fill(color = WHITE, opacity = 1)
|
||||
for mob in self:
|
||||
mob.considered_smooth = False
|
||||
|
||||
class VideoSeries(VGroup):
|
||||
CONFIG = {
|
||||
|
|
Loading…
Add table
Reference in a new issue