|
1 | | -from manimlib.constants import * |
| 1 | +import numpy as np |
| 2 | +from manimlib.constants import BLUE_D |
| 3 | +from manimlib.constants import BLUE_B |
| 4 | +from manimlib.constants import BLUE_E |
| 5 | +from manimlib.constants import GREY_BROWN |
| 6 | +from manimlib.constants import WHITE |
| 7 | +from manimlib.mobject.mobject import Mobject |
2 | 8 | from manimlib.mobject.types.vectorized_mobject import VMobject |
3 | 9 | from manimlib.mobject.types.vectorized_mobject import VGroup |
4 | 10 | from manimlib.utils.rate_functions import smooth |
@@ -75,24 +81,52 @@ class TracedPath(VMobject): |
75 | 81 | "stroke_width": 2, |
76 | 82 | "stroke_color": WHITE, |
77 | 83 | "min_distance_to_new_point": 0.1, |
| 84 | + "time_traced": np.inf, |
| 85 | + "fill_opacity": 0, |
| 86 | + "sparseness": 1, |
78 | 87 | } |
79 | 88 |
|
80 | 89 | def __init__(self, traced_point_func, **kwargs): |
81 | 90 | super().__init__(**kwargs) |
82 | 91 | self.traced_point_func = traced_point_func |
83 | | - self.add_updater(lambda m: m.update_path()) |
| 92 | + self.time = 0 |
| 93 | + self.times = [] |
| 94 | + self.traced_points = [] |
| 95 | + self.add_updater(lambda m, dt: m.update_path(dt)) |
84 | 96 |
|
85 | | - def update_path(self): |
86 | | - new_point = self.traced_point_func() |
87 | | - if not self.has_points(): |
88 | | - self.start_new_path(new_point) |
89 | | - self.add_line_to(new_point) |
| 97 | + def update_path(self, dt): |
| 98 | + point = np.array(self.traced_point_func()) |
| 99 | + tps = self.traced_points |
| 100 | + times = self.times |
| 101 | + |
| 102 | + if len(tps) == 0: |
| 103 | + tps.append(point) |
| 104 | + times.append(self.time) |
| 105 | + if get_norm(point - tps[-1]) >= self.min_distance_to_new_point: |
| 106 | + times.append(self.time) |
| 107 | + tps.append(point) |
| 108 | + # Cut off tail |
| 109 | + while times and times[0] < self.time - self.time_traced: |
| 110 | + times = times[1:] |
| 111 | + tps = tps[1:] |
| 112 | + if tps: |
| 113 | + self.set_points_as_corners(tps[::self.sparseness]) |
| 114 | + self.time += dt |
| 115 | + |
| 116 | + |
| 117 | +class TracingTail(TracedPath): |
| 118 | + CONFIG = { |
| 119 | + "stroke_width": (0, 3), |
| 120 | + "stroke_opacity": (0, 1), |
| 121 | + "stroke_color": WHITE, |
| 122 | + "time_traced": 1.0, |
| 123 | + "min_distance_to_new_point": 0, |
| 124 | + "sparseness": 3, |
| 125 | + } |
| 126 | + |
| 127 | + def __init__(self, mobject_or_func, **kwargs): |
| 128 | + if isinstance(mobject_or_func, Mobject): |
| 129 | + func = mobject_or_func.get_center |
90 | 130 | else: |
91 | | - # Set the end to be the new point |
92 | | - self.get_points()[-1] = new_point |
93 | | - |
94 | | - # Second to last point |
95 | | - nppcc = self.n_points_per_curve |
96 | | - dist = get_norm(new_point - self.get_points()[-nppcc]) |
97 | | - if dist >= self.min_distance_to_new_point: |
98 | | - self.add_line_to(new_point) |
| 131 | + func = mobject_or_func |
| 132 | + super().__init__(func, **kwargs) |
0 commit comments