manim 0.17.0__py3-none-any.whl → 0.19.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- manim/__init__.py +11 -6
- manim/__main__.py +62 -19
- manim/_config/__init__.py +10 -9
- manim/_config/cli_colors.py +26 -9
- manim/_config/default.cfg +1 -3
- manim/_config/logger_utils.py +23 -13
- manim/_config/utils.py +662 -468
- manim/animation/animation.py +164 -18
- manim/animation/changing.py +34 -23
- manim/animation/composition.py +265 -67
- manim/animation/creation.py +208 -26
- manim/animation/fading.py +16 -18
- manim/animation/growing.py +35 -15
- manim/animation/indication.py +150 -76
- manim/animation/movement.py +56 -22
- manim/animation/numbers.py +64 -6
- manim/animation/rotation.py +78 -7
- manim/animation/specialized.py +6 -7
- manim/animation/speedmodifier.py +13 -10
- manim/animation/transform.py +14 -11
- manim/animation/transform_matching_parts.py +3 -4
- manim/animation/updaters/mobject_update_utils.py +152 -30
- manim/animation/updaters/update.py +10 -7
- manim/camera/camera.py +182 -118
- manim/camera/mapping_camera.py +34 -3
- manim/camera/moving_camera.py +95 -74
- manim/camera/multi_camera.py +23 -15
- manim/camera/three_d_camera.py +70 -52
- manim/cli/__init__.py +17 -0
- manim/cli/cfg/group.py +76 -44
- manim/cli/checkhealth/checks.py +192 -0
- manim/cli/checkhealth/commands.py +90 -0
- manim/cli/default_group.py +158 -25
- manim/cli/init/commands.py +33 -25
- manim/cli/plugins/commands.py +16 -3
- manim/cli/render/commands.py +72 -60
- manim/cli/render/ease_of_access_options.py +4 -3
- manim/cli/render/global_options.py +59 -17
- manim/cli/render/output_options.py +6 -5
- manim/cli/render/render_options.py +98 -33
- manim/constants.py +109 -59
- manim/data_structures.py +31 -0
- manim/mobject/frame.py +8 -5
- manim/mobject/geometry/__init__.py +1 -0
- manim/mobject/geometry/arc.py +277 -135
- manim/mobject/geometry/boolean_ops.py +32 -31
- manim/mobject/geometry/labeled.py +376 -0
- manim/mobject/geometry/line.py +192 -87
- manim/mobject/geometry/polygram.py +224 -58
- manim/mobject/geometry/shape_matchers.py +61 -25
- manim/mobject/geometry/tips.py +122 -48
- manim/mobject/graph.py +1027 -419
- manim/mobject/graphing/coordinate_systems.py +533 -278
- manim/mobject/graphing/functions.py +53 -32
- manim/mobject/graphing/number_line.py +123 -65
- manim/mobject/graphing/probability.py +88 -62
- manim/mobject/graphing/scale.py +33 -19
- manim/mobject/logo.py +118 -28
- manim/mobject/matrix.py +87 -83
- manim/mobject/mobject.py +912 -442
- manim/mobject/opengl/dot_cloud.py +16 -5
- manim/mobject/opengl/opengl_compatibility.py +4 -2
- manim/mobject/opengl/opengl_geometry.py +254 -153
- manim/mobject/opengl/opengl_image_mobject.py +3 -1
- manim/mobject/opengl/opengl_mobject.py +779 -482
- manim/mobject/opengl/opengl_point_cloud_mobject.py +41 -14
- manim/mobject/opengl/opengl_surface.py +14 -92
- manim/mobject/opengl/opengl_three_dimensions.py +12 -8
- manim/mobject/opengl/opengl_vectorized_mobject.py +98 -100
- manim/mobject/svg/brace.py +173 -41
- manim/mobject/svg/svg_mobject.py +139 -53
- manim/mobject/table.py +61 -68
- manim/mobject/text/code_mobject.py +193 -539
- manim/mobject/text/numbers.py +81 -34
- manim/mobject/text/tex_mobject.py +130 -78
- manim/mobject/text/text_mobject.py +288 -164
- manim/mobject/three_d/polyhedra.py +111 -13
- manim/mobject/three_d/three_d_utils.py +17 -8
- manim/mobject/three_d/three_dimensions.py +239 -106
- manim/mobject/types/image_mobject.py +50 -30
- manim/mobject/types/point_cloud_mobject.py +120 -75
- manim/mobject/types/vectorized_mobject.py +841 -408
- manim/mobject/value_tracker.py +105 -38
- manim/mobject/vector_field.py +50 -31
- manim/opengl/__init__.py +3 -3
- manim/plugins/__init__.py +14 -1
- manim/plugins/plugins_flags.py +10 -14
- manim/renderer/cairo_renderer.py +65 -50
- manim/renderer/opengl_renderer.py +89 -69
- manim/renderer/opengl_renderer_window.py +39 -18
- manim/renderer/shader.py +123 -87
- manim/renderer/shader_wrapper.py +44 -28
- manim/renderer/vectorized_mobject_rendering.py +38 -10
- manim/scene/moving_camera_scene.py +32 -3
- manim/scene/scene.py +507 -242
- manim/scene/scene_file_writer.py +371 -220
- manim/scene/section.py +20 -16
- manim/scene/three_d_scene.py +14 -22
- manim/scene/vector_space_scene.py +223 -129
- manim/scene/zoomed_scene.py +46 -41
- manim/typing.py +990 -0
- manim/utils/bezier.py +1823 -371
- manim/utils/caching.py +12 -5
- manim/utils/color/AS2700.py +236 -0
- manim/utils/color/BS381.py +318 -0
- manim/utils/color/DVIPSNAMES.py +96 -0
- manim/utils/color/SVGNAMES.py +179 -0
- manim/utils/color/X11.py +533 -0
- manim/utils/color/XKCD.py +952 -0
- manim/utils/color/__init__.py +61 -0
- manim/utils/color/core.py +1667 -0
- manim/utils/color/manim_colors.py +218 -0
- manim/utils/commands.py +48 -20
- manim/utils/config_ops.py +39 -19
- manim/utils/debug.py +8 -7
- manim/utils/deprecation.py +86 -39
- manim/utils/docbuild/__init__.py +17 -0
- manim/utils/docbuild/autoaliasattr_directive.py +236 -0
- manim/utils/docbuild/autocolor_directive.py +99 -0
- manim/utils/docbuild/manim_directive.py +94 -41
- manim/utils/docbuild/module_parsing.py +245 -0
- manim/utils/exceptions.py +6 -0
- manim/utils/family.py +5 -3
- manim/utils/family_ops.py +17 -4
- manim/utils/file_ops.py +27 -17
- manim/utils/hashing.py +55 -45
- manim/utils/images.py +13 -7
- manim/utils/ipython_magic.py +13 -7
- manim/utils/iterables.py +163 -120
- manim/utils/module_ops.py +66 -24
- manim/utils/opengl.py +77 -24
- manim/utils/parameter_parsing.py +32 -0
- manim/utils/paths.py +30 -33
- manim/utils/polylabel.py +235 -0
- manim/utils/qhull.py +218 -0
- manim/utils/rate_functions.py +98 -32
- manim/utils/simple_functions.py +25 -33
- manim/utils/sounds.py +7 -1
- manim/utils/space_ops.py +188 -115
- manim/utils/testing/__init__.py +17 -0
- manim/utils/testing/_frames_testers.py +13 -8
- manim/utils/testing/_show_diff.py +5 -3
- manim/utils/testing/_test_class_makers.py +34 -18
- manim/utils/testing/frames_comparison.py +37 -19
- manim/utils/tex.py +130 -198
- manim/utils/tex_file_writing.py +77 -47
- manim/utils/tex_templates.py +2 -1
- manim/utils/unit.py +6 -5
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/METADATA +64 -65
- manim-0.19.1.dist-info/RECORD +220 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/WHEEL +1 -1
- manim-0.19.1.dist-info/entry_points.txt +3 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE.community +1 -1
- manim/cli/new/group.py +0 -189
- manim/communitycolors.py +0 -9
- manim/gui/__init__.py +0 -0
- manim/gui/gui.py +0 -82
- manim/plugins/import_plugins.py +0 -43
- manim/utils/color.py +0 -552
- manim-0.17.0.dist-info/RECORD +0 -206
- manim-0.17.0.dist-info/entry_points.txt +0 -4
- /manim/cli/{new → checkhealth}/__init__.py +0 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE +0 -0
manim/mobject/value_tracker.py
CHANGED
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
__all__ = ["ValueTracker", "ComplexValueTracker"]
|
|
6
6
|
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
7
8
|
|
|
8
9
|
import numpy as np
|
|
9
10
|
|
|
@@ -11,6 +12,11 @@ from manim.mobject.mobject import Mobject
|
|
|
11
12
|
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
|
|
12
13
|
from manim.utils.paths import straight_path
|
|
13
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from typing_extensions import Self
|
|
17
|
+
|
|
18
|
+
from manim.typing import PathFuncType
|
|
19
|
+
|
|
14
20
|
|
|
15
21
|
class ValueTracker(Mobject, metaclass=ConvertToOpenGL):
|
|
16
22
|
"""A mobject that can be used for tracking (real-valued) parameters.
|
|
@@ -45,7 +51,7 @@ class ValueTracker(Mobject, metaclass=ConvertToOpenGL):
|
|
|
45
51
|
self.wait(1)
|
|
46
52
|
tracker -= 4
|
|
47
53
|
self.wait(0.5)
|
|
48
|
-
self.play(tracker.animate.set_value(5))
|
|
54
|
+
self.play(tracker.animate.set_value(5))
|
|
49
55
|
self.wait(0.5)
|
|
50
56
|
self.play(tracker.animate.set_value(3))
|
|
51
57
|
self.play(tracker.animate.increment_value(-2))
|
|
@@ -69,76 +75,140 @@ class ValueTracker(Mobject, metaclass=ConvertToOpenGL):
|
|
|
69
75
|
|
|
70
76
|
"""
|
|
71
77
|
|
|
72
|
-
def __init__(self, value=0, **kwargs):
|
|
78
|
+
def __init__(self, value: float = 0, **kwargs: Any) -> None:
|
|
73
79
|
super().__init__(**kwargs)
|
|
74
|
-
self.
|
|
80
|
+
self.set(points=np.zeros((1, 3)))
|
|
75
81
|
self.set_value(value)
|
|
76
82
|
|
|
77
83
|
def get_value(self) -> float:
|
|
78
84
|
"""Get the current value of this ValueTracker."""
|
|
79
|
-
|
|
85
|
+
value: float = self.points[0, 0]
|
|
86
|
+
return value
|
|
80
87
|
|
|
81
|
-
def set_value(self, value: float):
|
|
82
|
-
"""Sets a new scalar value to the ValueTracker"""
|
|
88
|
+
def set_value(self, value: float) -> Self:
|
|
89
|
+
"""Sets a new scalar value to the ValueTracker."""
|
|
83
90
|
self.points[0, 0] = value
|
|
84
91
|
return self
|
|
85
92
|
|
|
86
|
-
def increment_value(self, d_value: float):
|
|
87
|
-
"""Increments (adds) a scalar value
|
|
93
|
+
def increment_value(self, d_value: float) -> Self:
|
|
94
|
+
"""Increments (adds) a scalar value to the ValueTracker."""
|
|
88
95
|
self.set_value(self.get_value() + d_value)
|
|
89
96
|
return self
|
|
90
97
|
|
|
91
|
-
def __bool__(self):
|
|
92
|
-
"""Return whether the value of this
|
|
98
|
+
def __bool__(self) -> bool:
|
|
99
|
+
"""Return whether the value of this ValueTracker evaluates as true."""
|
|
93
100
|
return bool(self.get_value())
|
|
94
101
|
|
|
95
|
-
def
|
|
96
|
-
"""
|
|
102
|
+
def __add__(self, d_value: float | Mobject) -> ValueTracker:
|
|
103
|
+
"""Return a new :class:`ValueTracker` whose value is the current tracker's value plus
|
|
104
|
+
``d_value``.
|
|
105
|
+
"""
|
|
106
|
+
if isinstance(d_value, Mobject):
|
|
107
|
+
raise ValueError(
|
|
108
|
+
"Cannot increment ValueTracker by a Mobject. Please provide a scalar value."
|
|
109
|
+
)
|
|
110
|
+
return ValueTracker(self.get_value() + d_value)
|
|
111
|
+
|
|
112
|
+
def __iadd__(self, d_value: float | Mobject) -> Self:
|
|
113
|
+
"""adds ``+=`` syntax to increment the value of the ValueTracker."""
|
|
114
|
+
if isinstance(d_value, Mobject):
|
|
115
|
+
raise ValueError(
|
|
116
|
+
"Cannot increment ValueTracker by a Mobject. Please provide a scalar value."
|
|
117
|
+
)
|
|
97
118
|
self.increment_value(d_value)
|
|
98
119
|
return self
|
|
99
120
|
|
|
100
|
-
def
|
|
101
|
-
"""
|
|
121
|
+
def __floordiv__(self, d_value: float) -> ValueTracker:
|
|
122
|
+
"""Return a new :class:`ValueTracker` whose value is the floor division of the current
|
|
123
|
+
tracker's value by ``d_value``.
|
|
124
|
+
"""
|
|
125
|
+
return ValueTracker(self.get_value() // d_value)
|
|
126
|
+
|
|
127
|
+
def __ifloordiv__(self, d_value: float) -> Self:
|
|
128
|
+
"""Set the value of this ValueTracker to the floor division of the current value by ``d_value``."""
|
|
102
129
|
self.set_value(self.get_value() // d_value)
|
|
103
130
|
return self
|
|
104
131
|
|
|
105
|
-
def
|
|
106
|
-
"""
|
|
132
|
+
def __mod__(self, d_value: float) -> ValueTracker:
|
|
133
|
+
"""Return a new :class:`ValueTracker` whose value is the current tracker's value
|
|
134
|
+
modulo ``d_value``.
|
|
135
|
+
"""
|
|
136
|
+
return ValueTracker(self.get_value() % d_value)
|
|
137
|
+
|
|
138
|
+
def __imod__(self, d_value: float) -> Self:
|
|
139
|
+
"""Set the value of this ValueTracker to the current value modulo ``d_value``."""
|
|
107
140
|
self.set_value(self.get_value() % d_value)
|
|
108
141
|
return self
|
|
109
142
|
|
|
110
|
-
def
|
|
111
|
-
"""
|
|
143
|
+
def __mul__(self, d_value: float) -> ValueTracker:
|
|
144
|
+
"""Return a new :class:`ValueTracker` whose value is the current tracker's value multiplied by
|
|
145
|
+
``d_value``.
|
|
146
|
+
"""
|
|
147
|
+
return ValueTracker(self.get_value() * d_value)
|
|
148
|
+
|
|
149
|
+
def __imul__(self, d_value: float) -> Self:
|
|
150
|
+
"""Set the value of this ValueTracker to the product of the current value and ``d_value``."""
|
|
112
151
|
self.set_value(self.get_value() * d_value)
|
|
113
152
|
return self
|
|
114
153
|
|
|
115
|
-
def
|
|
116
|
-
"""
|
|
154
|
+
def __pow__(self, d_value: float) -> ValueTracker:
|
|
155
|
+
"""Return a new :class:`ValueTracker` whose value is the current tracker's value raised to the
|
|
156
|
+
power of ``d_value``.
|
|
157
|
+
"""
|
|
158
|
+
return ValueTracker(self.get_value() ** d_value)
|
|
159
|
+
|
|
160
|
+
def __ipow__(self, d_value: float) -> Self:
|
|
161
|
+
"""Set the value of this ValueTracker to the current value raised to the power of ``d_value``."""
|
|
117
162
|
self.set_value(self.get_value() ** d_value)
|
|
118
163
|
return self
|
|
119
164
|
|
|
120
|
-
def
|
|
121
|
-
"""
|
|
165
|
+
def __sub__(self, d_value: float | Mobject) -> ValueTracker:
|
|
166
|
+
"""Return a new :class:`ValueTracker` whose value is the current tracker's value minus
|
|
167
|
+
``d_value``.
|
|
168
|
+
"""
|
|
169
|
+
if isinstance(d_value, Mobject):
|
|
170
|
+
raise ValueError(
|
|
171
|
+
"Cannot decrement ValueTracker by a Mobject. Please provide a scalar value."
|
|
172
|
+
)
|
|
173
|
+
return ValueTracker(self.get_value() - d_value)
|
|
174
|
+
|
|
175
|
+
def __isub__(self, d_value: float | Mobject) -> Self:
|
|
176
|
+
"""Adds ``-=`` syntax to decrement the value of the ValueTracker."""
|
|
177
|
+
if isinstance(d_value, Mobject):
|
|
178
|
+
raise ValueError(
|
|
179
|
+
"Cannot decrement ValueTracker by a Mobject. Please provide a scalar value."
|
|
180
|
+
)
|
|
122
181
|
self.increment_value(-d_value)
|
|
123
182
|
return self
|
|
124
183
|
|
|
125
|
-
def
|
|
126
|
-
"""
|
|
184
|
+
def __truediv__(self, d_value: float) -> ValueTracker:
|
|
185
|
+
"""Return a new :class:`ValueTracker` whose value is the current tracker's value
|
|
186
|
+
divided by ``d_value``.
|
|
187
|
+
"""
|
|
188
|
+
return ValueTracker(self.get_value() / d_value)
|
|
189
|
+
|
|
190
|
+
def __itruediv__(self, d_value: float) -> Self:
|
|
191
|
+
"""Sets the value of this ValueTracker to the current value divided by ``d_value``."""
|
|
127
192
|
self.set_value(self.get_value() / d_value)
|
|
128
193
|
return self
|
|
129
194
|
|
|
130
|
-
def interpolate(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
195
|
+
def interpolate(
|
|
196
|
+
self,
|
|
197
|
+
mobject1: Mobject,
|
|
198
|
+
mobject2: Mobject,
|
|
199
|
+
alpha: float,
|
|
200
|
+
path_func: PathFuncType = straight_path(),
|
|
201
|
+
) -> Self:
|
|
202
|
+
"""Turns ``self`` into an interpolation between ``mobject1`` and ``mobject2``."""
|
|
203
|
+
self.set(points=path_func(mobject1.points, mobject2.points, alpha))
|
|
136
204
|
return self
|
|
137
205
|
|
|
138
206
|
|
|
139
207
|
class ComplexValueTracker(ValueTracker):
|
|
140
208
|
"""Tracks a complex-valued parameter.
|
|
141
209
|
|
|
210
|
+
The value is internally stored as a points array [a, b, 0]. This can be accessed directly
|
|
211
|
+
to represent the value geometrically, see the usage example.
|
|
142
212
|
When the value is set through :attr:`animate`, the value will take a straight path from the
|
|
143
213
|
source point to the destination point.
|
|
144
214
|
|
|
@@ -161,15 +231,12 @@ class ComplexValueTracker(ValueTracker):
|
|
|
161
231
|
self.play(tracker.animate.set_value(tracker.get_value() / (-2 + 3j)))
|
|
162
232
|
"""
|
|
163
233
|
|
|
164
|
-
def get_value(self):
|
|
165
|
-
"""Get the current value of this
|
|
166
|
-
|
|
167
|
-
The value is internally stored as a points array [a, b, 0]. This can be accessed directly
|
|
168
|
-
to represent the value geometrically, see the usage example."""
|
|
234
|
+
def get_value(self) -> complex: # type: ignore [override]
|
|
235
|
+
"""Get the current value of this ComplexValueTracker as a complex number."""
|
|
169
236
|
return complex(*self.points[0, :2])
|
|
170
237
|
|
|
171
|
-
def set_value(self,
|
|
172
|
-
"""Sets a new complex value to the ComplexValueTracker"""
|
|
173
|
-
z = complex(
|
|
238
|
+
def set_value(self, value: complex | float) -> Self:
|
|
239
|
+
"""Sets a new complex value to the ComplexValueTracker."""
|
|
240
|
+
z = complex(value)
|
|
174
241
|
self.points[0, :2] = (z.real, z.imag)
|
|
175
242
|
return self
|
manim/mobject/vector_field.py
CHANGED
|
@@ -10,11 +10,11 @@ __all__ = [
|
|
|
10
10
|
|
|
11
11
|
import itertools as it
|
|
12
12
|
import random
|
|
13
|
+
from collections.abc import Callable, Iterable, Sequence
|
|
13
14
|
from math import ceil, floor
|
|
14
|
-
from typing import
|
|
15
|
+
from typing import TYPE_CHECKING
|
|
15
16
|
|
|
16
17
|
import numpy as np
|
|
17
|
-
from colour import Color
|
|
18
18
|
from PIL import Image
|
|
19
19
|
|
|
20
20
|
from manim.animation.updaters.update import UpdateFromAlphaFunc
|
|
@@ -30,10 +30,28 @@ from ..mobject.mobject import Mobject
|
|
|
30
30
|
from ..mobject.types.vectorized_mobject import VGroup
|
|
31
31
|
from ..mobject.utils import get_vectorized_mobject_class
|
|
32
32
|
from ..utils.bezier import interpolate, inverse_interpolate
|
|
33
|
-
from ..utils.color import
|
|
33
|
+
from ..utils.color import (
|
|
34
|
+
BLUE_E,
|
|
35
|
+
GREEN,
|
|
36
|
+
RED,
|
|
37
|
+
YELLOW,
|
|
38
|
+
ManimColor,
|
|
39
|
+
ParsableManimColor,
|
|
40
|
+
color_to_rgb,
|
|
41
|
+
rgb_to_color,
|
|
42
|
+
)
|
|
34
43
|
from ..utils.rate_functions import ease_out_sine, linear
|
|
35
44
|
from ..utils.simple_functions import sigmoid
|
|
36
45
|
|
|
46
|
+
if TYPE_CHECKING:
|
|
47
|
+
from manim.typing import (
|
|
48
|
+
FloatRGB,
|
|
49
|
+
FloatRGB_Array,
|
|
50
|
+
FloatRGBA_Array,
|
|
51
|
+
Point3D,
|
|
52
|
+
Vector3D,
|
|
53
|
+
)
|
|
54
|
+
|
|
37
55
|
DEFAULT_SCALAR_FIELD_COLORS: list = [BLUE_E, GREEN, YELLOW, RED]
|
|
38
56
|
|
|
39
57
|
|
|
@@ -65,12 +83,12 @@ class VectorField(VGroup):
|
|
|
65
83
|
|
|
66
84
|
def __init__(
|
|
67
85
|
self,
|
|
68
|
-
func: Callable[[
|
|
69
|
-
color:
|
|
70
|
-
color_scheme: Callable[[
|
|
86
|
+
func: Callable[[Point3D], Vector3D],
|
|
87
|
+
color: ParsableManimColor | None = None,
|
|
88
|
+
color_scheme: Callable[[Vector3D], float] | None = None,
|
|
71
89
|
min_color_scheme_value: float = 0,
|
|
72
90
|
max_color_scheme_value: float = 2,
|
|
73
|
-
colors: Sequence[
|
|
91
|
+
colors: Sequence[ParsableManimColor] = DEFAULT_SCALAR_FIELD_COLORS,
|
|
74
92
|
**kwargs,
|
|
75
93
|
):
|
|
76
94
|
super().__init__(**kwargs)
|
|
@@ -79,13 +97,13 @@ class VectorField(VGroup):
|
|
|
79
97
|
self.single_color = False
|
|
80
98
|
if color_scheme is None:
|
|
81
99
|
|
|
82
|
-
def color_scheme(
|
|
83
|
-
return np.linalg.norm(
|
|
100
|
+
def color_scheme(vec: Vector3D) -> float:
|
|
101
|
+
return np.linalg.norm(vec)
|
|
84
102
|
|
|
85
103
|
self.color_scheme = color_scheme # TODO maybe other default for direction?
|
|
86
|
-
self.rgbs = np.array(list(map(color_to_rgb, colors)))
|
|
104
|
+
self.rgbs: FloatRGB_Array = np.array(list(map(color_to_rgb, colors)))
|
|
87
105
|
|
|
88
|
-
def pos_to_rgb(pos:
|
|
106
|
+
def pos_to_rgb(pos: Point3D) -> FloatRGB:
|
|
89
107
|
vec = self.func(pos)
|
|
90
108
|
color_value = np.clip(
|
|
91
109
|
self.color_scheme(vec),
|
|
@@ -98,8 +116,8 @@ class VectorField(VGroup):
|
|
|
98
116
|
color_value,
|
|
99
117
|
)
|
|
100
118
|
alpha *= len(self.rgbs) - 1
|
|
101
|
-
c1 = self.rgbs[int(alpha)]
|
|
102
|
-
c2 = self.rgbs[min(int(alpha + 1), len(self.rgbs) - 1)]
|
|
119
|
+
c1: FloatRGB = self.rgbs[int(alpha)]
|
|
120
|
+
c2: FloatRGB = self.rgbs[min(int(alpha + 1), len(self.rgbs) - 1)]
|
|
103
121
|
alpha %= 1
|
|
104
122
|
return interpolate(c1, c2, alpha)
|
|
105
123
|
|
|
@@ -107,7 +125,7 @@ class VectorField(VGroup):
|
|
|
107
125
|
self.pos_to_color = lambda pos: rgb_to_color(self.pos_to_rgb(pos))
|
|
108
126
|
else:
|
|
109
127
|
self.single_color = True
|
|
110
|
-
self.color = color
|
|
128
|
+
self.color = ManimColor.parse(color)
|
|
111
129
|
self.submob_movement_updater = None
|
|
112
130
|
|
|
113
131
|
@staticmethod
|
|
@@ -344,7 +362,6 @@ class VectorField(VGroup):
|
|
|
344
362
|
This vector field.
|
|
345
363
|
|
|
346
364
|
"""
|
|
347
|
-
|
|
348
365
|
self.stop_submobject_movement()
|
|
349
366
|
self.submob_movement_updater = lambda mob, dt: mob.nudge_submobjects(
|
|
350
367
|
dt * speed,
|
|
@@ -409,8 +426,8 @@ class VectorField(VGroup):
|
|
|
409
426
|
self,
|
|
410
427
|
start: float,
|
|
411
428
|
end: float,
|
|
412
|
-
colors: Iterable,
|
|
413
|
-
):
|
|
429
|
+
colors: Iterable[ParsableManimColor],
|
|
430
|
+
) -> Callable[[Sequence[float], float], FloatRGBA_Array]:
|
|
414
431
|
"""
|
|
415
432
|
Generates a gradient of rgbas as a numpy array
|
|
416
433
|
|
|
@@ -427,9 +444,9 @@ class VectorField(VGroup):
|
|
|
427
444
|
-------
|
|
428
445
|
function to generate the gradients as numpy arrays representing rgba values
|
|
429
446
|
"""
|
|
430
|
-
rgbs = np.array([color_to_rgb(c) for c in colors])
|
|
447
|
+
rgbs: FloatRGB_Array = np.array([color_to_rgb(c) for c in colors])
|
|
431
448
|
|
|
432
|
-
def func(values, opacity=1):
|
|
449
|
+
def func(values: Sequence[float], opacity: float = 1.0) -> FloatRGBA_Array:
|
|
433
450
|
alphas = inverse_interpolate(start, end, np.array(values))
|
|
434
451
|
alphas = np.clip(alphas, 0, 1)
|
|
435
452
|
scaled_alphas = alphas * (len(rgbs) - 1)
|
|
@@ -437,12 +454,14 @@ class VectorField(VGroup):
|
|
|
437
454
|
next_indices = np.clip(indices + 1, 0, len(rgbs) - 1)
|
|
438
455
|
inter_alphas = scaled_alphas % 1
|
|
439
456
|
inter_alphas = inter_alphas.repeat(3).reshape((len(indices), 3))
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
457
|
+
new_rgbs: FloatRGB_Array = interpolate(
|
|
458
|
+
rgbs[indices], rgbs[next_indices], inter_alphas
|
|
459
|
+
)
|
|
460
|
+
new_rgbas: FloatRGBA_Array = np.concatenate(
|
|
461
|
+
(new_rgbs, np.full([len(new_rgbs), 1], opacity)),
|
|
443
462
|
axis=1,
|
|
444
463
|
)
|
|
445
|
-
return
|
|
464
|
+
return new_rgbas
|
|
446
465
|
|
|
447
466
|
return func
|
|
448
467
|
|
|
@@ -533,11 +552,11 @@ class ArrowVectorField(VectorField):
|
|
|
533
552
|
def __init__(
|
|
534
553
|
self,
|
|
535
554
|
func: Callable[[np.ndarray], np.ndarray],
|
|
536
|
-
color:
|
|
555
|
+
color: ParsableManimColor | None = None,
|
|
537
556
|
color_scheme: Callable[[np.ndarray], float] | None = None,
|
|
538
557
|
min_color_scheme_value: float = 0,
|
|
539
558
|
max_color_scheme_value: float = 2,
|
|
540
|
-
colors: Sequence[
|
|
559
|
+
colors: Sequence[ParsableManimColor] = DEFAULT_SCALAR_FIELD_COLORS,
|
|
541
560
|
# Determining Vector positions:
|
|
542
561
|
x_range: Sequence[float] = None,
|
|
543
562
|
y_range: Sequence[float] = None,
|
|
@@ -613,7 +632,7 @@ class ArrowVectorField(VectorField):
|
|
|
613
632
|
The root point of the vector.
|
|
614
633
|
|
|
615
634
|
"""
|
|
616
|
-
output = np.
|
|
635
|
+
output = np.array(self.func(point))
|
|
617
636
|
norm = np.linalg.norm(output)
|
|
618
637
|
if norm != 0:
|
|
619
638
|
output *= self.length_func(norm) / norm
|
|
@@ -707,11 +726,11 @@ class StreamLines(VectorField):
|
|
|
707
726
|
def __init__(
|
|
708
727
|
self,
|
|
709
728
|
func: Callable[[np.ndarray], np.ndarray],
|
|
710
|
-
color:
|
|
729
|
+
color: ParsableManimColor | None = None,
|
|
711
730
|
color_scheme: Callable[[np.ndarray], float] | None = None,
|
|
712
731
|
min_color_scheme_value: float = 0,
|
|
713
732
|
max_color_scheme_value: float = 2,
|
|
714
|
-
colors: Sequence[
|
|
733
|
+
colors: Sequence[ParsableManimColor] = DEFAULT_SCALAR_FIELD_COLORS,
|
|
715
734
|
# Determining stream line starting positions:
|
|
716
735
|
x_range: Sequence[float] = None,
|
|
717
736
|
y_range: Sequence[float] = None,
|
|
@@ -821,7 +840,9 @@ class StreamLines(VectorField):
|
|
|
821
840
|
step = max(1, int(len(points) / self.max_anchors_per_line))
|
|
822
841
|
line.set_points_smoothly(points[::step])
|
|
823
842
|
if self.single_color:
|
|
824
|
-
line.set_stroke(
|
|
843
|
+
line.set_stroke(
|
|
844
|
+
color=self.color, width=self.stroke_width, opacity=opacity
|
|
845
|
+
)
|
|
825
846
|
else:
|
|
826
847
|
if config.renderer == RendererType.OPENGL:
|
|
827
848
|
# scaled for compatibility with cairo
|
|
@@ -940,7 +961,6 @@ class StreamLines(VectorField):
|
|
|
940
961
|
self.wait(stream_lines.virtual_time / stream_lines.flow_speed)
|
|
941
962
|
|
|
942
963
|
"""
|
|
943
|
-
|
|
944
964
|
for line in self.stream_lines:
|
|
945
965
|
run_time = line.duration / flow_speed
|
|
946
966
|
line.anim = line_animation_class(
|
|
@@ -1000,7 +1020,6 @@ class StreamLines(VectorField):
|
|
|
1000
1020
|
self.play(stream_lines.end_animation())
|
|
1001
1021
|
|
|
1002
1022
|
"""
|
|
1003
|
-
|
|
1004
1023
|
if self.flow_animation is None:
|
|
1005
1024
|
raise ValueError("You have to start the animation before fading it out.")
|
|
1006
1025
|
|
manim/opengl/__init__.py
CHANGED
manim/plugins/__init__.py
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from .
|
|
3
|
+
from manim._config import config, logger
|
|
4
|
+
from manim.plugins.plugins_flags import get_plugins, list_plugins
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"get_plugins",
|
|
8
|
+
"list_plugins",
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
requested_plugins: set[str] = set(config["plugins"])
|
|
12
|
+
missing_plugins = requested_plugins - set(get_plugins().keys())
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
if missing_plugins:
|
|
16
|
+
logger.warning("Missing Plugins: %s", missing_plugins)
|
manim/plugins/plugins_flags.py
CHANGED
|
@@ -1,30 +1,26 @@
|
|
|
1
|
-
"""
|
|
2
|
-
plugins_flags.py
|
|
3
|
-
------------
|
|
4
|
-
|
|
5
|
-
Plugin Managing Utility.
|
|
6
|
-
"""
|
|
1
|
+
"""Plugin Managing Utility"""
|
|
7
2
|
|
|
8
3
|
from __future__ import annotations
|
|
9
4
|
|
|
10
|
-
import
|
|
5
|
+
from importlib.metadata import entry_points
|
|
6
|
+
from typing import Any
|
|
11
7
|
|
|
12
|
-
from manim import console
|
|
8
|
+
from manim._config import console
|
|
13
9
|
|
|
14
10
|
__all__ = ["list_plugins"]
|
|
15
11
|
|
|
16
12
|
|
|
17
|
-
def get_plugins():
|
|
18
|
-
plugins = {
|
|
13
|
+
def get_plugins() -> dict[str, Any]:
|
|
14
|
+
plugins: dict[str, Any] = {
|
|
19
15
|
entry_point.name: entry_point.load()
|
|
20
|
-
for entry_point in
|
|
16
|
+
for entry_point in entry_points(group="manim.plugins")
|
|
21
17
|
}
|
|
22
18
|
return plugins
|
|
23
19
|
|
|
24
20
|
|
|
25
|
-
def list_plugins():
|
|
21
|
+
def list_plugins() -> None:
|
|
26
22
|
console.print("[green bold]Plugins:[/green bold]", justify="left")
|
|
27
23
|
|
|
28
24
|
plugins = get_plugins()
|
|
29
|
-
for
|
|
30
|
-
console.print(f" • {
|
|
25
|
+
for plugin_name in plugins:
|
|
26
|
+
console.print(f" • {plugin_name}")
|