22
33__all__ = ["AnimatedBoundary" , "TracedPath" ]
44
5+ from typing import Callable , Optional
6+
57import numpy as np
8+ from colour import Color
69
710from .._config import config
811from ..constants import *
912from ..mobject .types .vectorized_mobject import VGroup , VMobject
1013from ..utils .color import BLUE_B , BLUE_D , BLUE_E , GREY_BROWN , WHITE
14+ from ..utils .deprecation import deprecated_params
1115from ..utils .rate_functions import smooth
1216from .opengl_compatibility import ConvertToOpenGL
1317
@@ -94,6 +98,18 @@ def full_family_become_partial(self, mob1, mob2, a, b):
9498class TracedPath (VMobject , metaclass = ConvertToOpenGL ):
9599 """Traces the path of a point returned by a function call.
96100
101+ Parameters
102+ ----------
103+ traced_point_func
104+ The function to be traced.
105+ stroke_width
106+ The width of the trace.
107+ stroke_color
108+ The color of the trace.
109+ dissipating_time
110+ The time taken for the path to dissipate. Default set to ``None``
111+ which disables dissipation.
112+
97113 Examples
98114 --------
99115 .. manim:: TracedPathExample
@@ -108,35 +124,47 @@ def construct(self):
108124 self.add(trace, rolling_circle)
109125 self.play(rolling_circle.animate.shift(8*RIGHT), run_time=4, rate_func=linear)
110126
127+ .. manim:: DissipatingPathExample
128+
129+ class DissipatingPathExample(Scene):
130+ def construct(self):
131+ a = Dot(RIGHT * 2)
132+ b = TracedPath(a.get_center, dissipating_time=0.5, stroke_opacity=[0, 1])
133+ self.add(a, b)
134+ self.play(a.animate(path_arc=PI / 4).shift(LEFT * 2))
135+ self.play(a.animate(path_arc=-PI / 4).shift(LEFT * 2))
136+ self.wait()
137+
111138 """
112139
140+ @deprecated_params (
141+ params = "min_distance_to_new_point" , since = "v0.10.0" , until = "v0.12.0"
142+ )
113143 def __init__ (
114144 self ,
115- traced_point_func ,
116- stroke_width = 2 ,
117- stroke_color = WHITE ,
118- min_distance_to_new_point = 0.1 ,
145+ traced_point_func : Callable ,
146+ stroke_width : float = 2 ,
147+ stroke_color : Color = WHITE ,
148+ dissipating_time : Optional [ float ] = None ,
119149 ** kwargs
120150 ):
151+ kwargs .pop ("min_distance_to_new_point" , None ) #
121152 super ().__init__ (stroke_color = stroke_color , stroke_width = stroke_width , ** kwargs )
122- self .min_distance_to_new_point = min_distance_to_new_point
123153 self .traced_point_func = traced_point_func
124- self .add_updater (lambda m : m .update_path ())
154+ self .dissipating_time = dissipating_time
155+ self .time = 1 if self .dissipating_time else None
156+ self .add_updater (self .update_path )
125157
126- def update_path (self ):
158+ def update_path (self , mob , dt ):
127159 new_point = self .traced_point_func ()
128160 if not self .has_points ():
129161 self .start_new_path (new_point )
130- self .add_line_to (new_point )
131- else :
132- # Set the end to be the new point
133- self .get_points ()[- 1 ] = new_point
134-
135- # Second to last point
136- if config ["renderer" ] == "opengl" :
137- nppcc = self .n_points_per_curve
138- else :
139- nppcc = self .n_points_per_cubic_curve
140- dist = np .linalg .norm (new_point - self .get_points ()[- nppcc ])
141- if dist >= self .min_distance_to_new_point :
142- self .add_line_to (new_point )
162+ self .add_line_to (new_point )
163+ if self .dissipating_time :
164+ self .time += dt
165+ if self .time - 1 > self .dissipating_time :
166+ if config ["renderer" ] == "opengl" :
167+ nppcc = self .n_points_per_curve
168+ else :
169+ nppcc = self .n_points_per_cubic_curve
170+ self .set_points (self .get_points ()[nppcc :])
0 commit comments