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
|
@@ -4,11 +4,13 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
__all__ = ["VectorScene", "LinearTransformationScene"]
|
|
6
6
|
|
|
7
|
-
from
|
|
7
|
+
from collections.abc import Callable, Iterable
|
|
8
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
8
9
|
|
|
9
10
|
import numpy as np
|
|
10
|
-
from colour import Color
|
|
11
11
|
|
|
12
|
+
from manim.animation.creation import DrawBorderThenFill, Group
|
|
13
|
+
from manim.camera.camera import Camera
|
|
12
14
|
from manim.mobject.geometry.arc import Dot
|
|
13
15
|
from manim.mobject.geometry.line import Arrow, Line, Vector
|
|
14
16
|
from manim.mobject.geometry.polygram import Rectangle
|
|
@@ -28,10 +30,33 @@ from ..mobject.matrix import Matrix
|
|
|
28
30
|
from ..mobject.mobject import Mobject
|
|
29
31
|
from ..mobject.types.vectorized_mobject import VGroup, VMobject
|
|
30
32
|
from ..scene.scene import Scene
|
|
31
|
-
from ..utils.color import
|
|
33
|
+
from ..utils.color import (
|
|
34
|
+
BLACK,
|
|
35
|
+
BLUE_D,
|
|
36
|
+
GREEN_C,
|
|
37
|
+
GREY,
|
|
38
|
+
RED_C,
|
|
39
|
+
WHITE,
|
|
40
|
+
YELLOW,
|
|
41
|
+
ManimColor,
|
|
42
|
+
ParsableManimColor,
|
|
43
|
+
)
|
|
32
44
|
from ..utils.rate_functions import rush_from, rush_into
|
|
33
45
|
from ..utils.space_ops import angle_of_vector
|
|
34
46
|
|
|
47
|
+
if TYPE_CHECKING:
|
|
48
|
+
from typing_extensions import Self
|
|
49
|
+
|
|
50
|
+
from manim.typing import (
|
|
51
|
+
MappingFunction,
|
|
52
|
+
Point3D,
|
|
53
|
+
Point3DLike,
|
|
54
|
+
Vector2DLike,
|
|
55
|
+
Vector3D,
|
|
56
|
+
Vector3DLike,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
35
60
|
X_COLOR = GREEN_C
|
|
36
61
|
Y_COLOR = RED_C
|
|
37
62
|
Z_COLOR = BLUE_D
|
|
@@ -44,11 +69,11 @@ Z_COLOR = BLUE_D
|
|
|
44
69
|
# Also, methods I would have thought of as getters, like coords_to_vector, are
|
|
45
70
|
# actually doing a lot of animating.
|
|
46
71
|
class VectorScene(Scene):
|
|
47
|
-
def __init__(self, basis_vector_stroke_width=6, **kwargs):
|
|
72
|
+
def __init__(self, basis_vector_stroke_width: float = 6.0, **kwargs: Any) -> None:
|
|
48
73
|
super().__init__(**kwargs)
|
|
49
74
|
self.basis_vector_stroke_width = basis_vector_stroke_width
|
|
50
75
|
|
|
51
|
-
def add_plane(self, animate: bool = False, **kwargs):
|
|
76
|
+
def add_plane(self, animate: bool = False, **kwargs: Any) -> NumberPlane:
|
|
52
77
|
"""
|
|
53
78
|
Adds a NumberPlane object to the background.
|
|
54
79
|
|
|
@@ -70,7 +95,11 @@ class VectorScene(Scene):
|
|
|
70
95
|
self.add(plane)
|
|
71
96
|
return plane
|
|
72
97
|
|
|
73
|
-
def add_axes(
|
|
98
|
+
def add_axes(
|
|
99
|
+
self,
|
|
100
|
+
animate: bool = False,
|
|
101
|
+
color: ParsableManimColor | Iterable[ParsableManimColor] = WHITE,
|
|
102
|
+
) -> Axes:
|
|
74
103
|
"""
|
|
75
104
|
Adds a pair of Axes to the Scene.
|
|
76
105
|
|
|
@@ -87,7 +116,9 @@ class VectorScene(Scene):
|
|
|
87
116
|
self.add(axes)
|
|
88
117
|
return axes
|
|
89
118
|
|
|
90
|
-
def lock_in_faded_grid(
|
|
119
|
+
def lock_in_faded_grid(
|
|
120
|
+
self, dimness: float = 0.7, axes_dimness: float = 0.5
|
|
121
|
+
) -> None:
|
|
91
122
|
"""
|
|
92
123
|
This method freezes the NumberPlane and Axes that were already
|
|
93
124
|
in the background, and adds new, manipulatable ones to the foreground.
|
|
@@ -107,11 +138,13 @@ class VectorScene(Scene):
|
|
|
107
138
|
axes.fade(axes_dimness)
|
|
108
139
|
self.add(axes)
|
|
109
140
|
|
|
110
|
-
|
|
141
|
+
# TODO
|
|
142
|
+
# error: Missing positional argument "scene" in call to "update_frame" of "CairoRenderer" [call-arg]
|
|
143
|
+
self.renderer.update_frame() # type: ignore[call-arg]
|
|
111
144
|
self.renderer.camera = Camera(self.renderer.get_frame())
|
|
112
145
|
self.clear()
|
|
113
146
|
|
|
114
|
-
def get_vector(self, numerical_vector:
|
|
147
|
+
def get_vector(self, numerical_vector: Vector3DLike, **kwargs: Any) -> Arrow:
|
|
115
148
|
"""
|
|
116
149
|
Returns an arrow on the Plane given an input numerical vector.
|
|
117
150
|
|
|
@@ -128,19 +161,21 @@ class VectorScene(Scene):
|
|
|
128
161
|
The Arrow representing the Vector.
|
|
129
162
|
"""
|
|
130
163
|
return Arrow(
|
|
131
|
-
|
|
132
|
-
|
|
164
|
+
# TODO
|
|
165
|
+
# error: "VectorScene" has no attribute "plane" [attr-defined]
|
|
166
|
+
self.plane.coords_to_point(0, 0), # type: ignore[attr-defined]
|
|
167
|
+
self.plane.coords_to_point(*numerical_vector[:2]), # type: ignore[attr-defined]
|
|
133
168
|
buff=0,
|
|
134
169
|
**kwargs,
|
|
135
170
|
)
|
|
136
171
|
|
|
137
172
|
def add_vector(
|
|
138
173
|
self,
|
|
139
|
-
vector: Arrow |
|
|
140
|
-
color:
|
|
174
|
+
vector: Arrow | Vector3DLike,
|
|
175
|
+
color: ParsableManimColor | Iterable[ParsableManimColor] = YELLOW,
|
|
141
176
|
animate: bool = True,
|
|
142
|
-
**kwargs,
|
|
143
|
-
):
|
|
177
|
+
**kwargs: Any,
|
|
178
|
+
) -> Arrow:
|
|
144
179
|
"""
|
|
145
180
|
Returns the Vector after adding it to the Plane.
|
|
146
181
|
|
|
@@ -170,13 +205,13 @@ class VectorScene(Scene):
|
|
|
170
205
|
The arrow representing the vector.
|
|
171
206
|
"""
|
|
172
207
|
if not isinstance(vector, Arrow):
|
|
173
|
-
vector = Vector(vector, color=color, **kwargs)
|
|
208
|
+
vector = Vector(np.asarray(vector), color=color, **kwargs)
|
|
174
209
|
if animate:
|
|
175
210
|
self.play(GrowArrow(vector))
|
|
176
211
|
self.add(vector)
|
|
177
212
|
return vector
|
|
178
213
|
|
|
179
|
-
def write_vector_coordinates(self, vector:
|
|
214
|
+
def write_vector_coordinates(self, vector: Vector, **kwargs: Any) -> Matrix:
|
|
180
215
|
"""
|
|
181
216
|
Returns a column matrix indicating the vector coordinates,
|
|
182
217
|
after writing them to the screen.
|
|
@@ -194,11 +229,15 @@ class VectorScene(Scene):
|
|
|
194
229
|
:class:`.Matrix`
|
|
195
230
|
The column matrix representing the vector.
|
|
196
231
|
"""
|
|
197
|
-
coords = vector.coordinate_label(**kwargs)
|
|
232
|
+
coords: Matrix = vector.coordinate_label(**kwargs)
|
|
198
233
|
self.play(Write(coords))
|
|
199
234
|
return coords
|
|
200
235
|
|
|
201
|
-
def get_basis_vectors(
|
|
236
|
+
def get_basis_vectors(
|
|
237
|
+
self,
|
|
238
|
+
i_hat_color: ParsableManimColor | Iterable[ParsableManimColor] = X_COLOR,
|
|
239
|
+
j_hat_color: ParsableManimColor | Iterable[ParsableManimColor] = Y_COLOR,
|
|
240
|
+
) -> VGroup:
|
|
202
241
|
"""
|
|
203
242
|
Returns a VGroup of the Basis Vectors (1,0) and (0,1)
|
|
204
243
|
|
|
@@ -217,12 +256,16 @@ class VectorScene(Scene):
|
|
|
217
256
|
"""
|
|
218
257
|
return VGroup(
|
|
219
258
|
*(
|
|
220
|
-
Vector(
|
|
259
|
+
Vector(
|
|
260
|
+
np.asarray(vect),
|
|
261
|
+
color=color,
|
|
262
|
+
stroke_width=self.basis_vector_stroke_width,
|
|
263
|
+
)
|
|
221
264
|
for vect, color in [([1, 0], i_hat_color), ([0, 1], j_hat_color)]
|
|
222
265
|
)
|
|
223
266
|
)
|
|
224
267
|
|
|
225
|
-
def get_basis_vector_labels(self, **kwargs):
|
|
268
|
+
def get_basis_vector_labels(self, **kwargs: Any) -> VGroup:
|
|
226
269
|
"""
|
|
227
270
|
Returns naming labels for the basis vectors.
|
|
228
271
|
|
|
@@ -254,13 +297,13 @@ class VectorScene(Scene):
|
|
|
254
297
|
def get_vector_label(
|
|
255
298
|
self,
|
|
256
299
|
vector: Vector,
|
|
257
|
-
label,
|
|
300
|
+
label: MathTex | str,
|
|
258
301
|
at_tip: bool = False,
|
|
259
302
|
direction: str = "left",
|
|
260
303
|
rotate: bool = False,
|
|
261
|
-
color:
|
|
304
|
+
color: ParsableManimColor | None = None,
|
|
262
305
|
label_scale_factor: float = LARGE_BUFF - 0.2,
|
|
263
|
-
):
|
|
306
|
+
) -> MathTex:
|
|
264
307
|
"""
|
|
265
308
|
Returns naming labels for the passed vector.
|
|
266
309
|
|
|
@@ -288,11 +331,14 @@ class VectorScene(Scene):
|
|
|
288
331
|
"""
|
|
289
332
|
if not isinstance(label, MathTex):
|
|
290
333
|
if len(label) == 1:
|
|
291
|
-
label = "\\vec{\\textbf{%s}}" % label
|
|
334
|
+
label = "\\vec{\\textbf{%s}}" % label # noqa: UP031
|
|
292
335
|
label = MathTex(label)
|
|
293
336
|
if color is None:
|
|
294
|
-
|
|
295
|
-
|
|
337
|
+
prepared_color: ParsableManimColor = vector.get_color()
|
|
338
|
+
else:
|
|
339
|
+
prepared_color = color
|
|
340
|
+
label.set_color(prepared_color)
|
|
341
|
+
assert isinstance(label, MathTex)
|
|
296
342
|
label.scale(label_scale_factor)
|
|
297
343
|
label.add_background_rectangle()
|
|
298
344
|
|
|
@@ -305,16 +351,18 @@ class VectorScene(Scene):
|
|
|
305
351
|
if not rotate:
|
|
306
352
|
label.rotate(-angle, about_point=ORIGIN)
|
|
307
353
|
if direction == "left":
|
|
308
|
-
|
|
354
|
+
temp_shift_1: Vector3D = np.asarray(label.get_bottom())
|
|
355
|
+
label.shift(-temp_shift_1 + 0.1 * UP)
|
|
309
356
|
else:
|
|
310
|
-
|
|
357
|
+
temp_shift_2: Vector3D = np.asarray(label.get_top())
|
|
358
|
+
label.shift(-temp_shift_2 + 0.1 * DOWN)
|
|
311
359
|
label.rotate(angle, about_point=ORIGIN)
|
|
312
360
|
label.shift((vector.get_end() - vector.get_start()) / 2)
|
|
313
361
|
return label
|
|
314
362
|
|
|
315
363
|
def label_vector(
|
|
316
|
-
self, vector: Vector, label: MathTex | str, animate: bool = True, **kwargs
|
|
317
|
-
):
|
|
364
|
+
self, vector: Vector, label: MathTex | str, animate: bool = True, **kwargs: Any
|
|
365
|
+
) -> MathTex:
|
|
318
366
|
"""
|
|
319
367
|
Shortcut method for creating, and animating the addition of
|
|
320
368
|
a label for the vector.
|
|
@@ -338,38 +386,38 @@ class VectorScene(Scene):
|
|
|
338
386
|
:class:`~.MathTex`
|
|
339
387
|
The MathTex of the label.
|
|
340
388
|
"""
|
|
341
|
-
|
|
389
|
+
mathtex_label = self.get_vector_label(vector, label, **kwargs)
|
|
342
390
|
if animate:
|
|
343
|
-
self.play(Write(
|
|
344
|
-
self.add(
|
|
345
|
-
return
|
|
391
|
+
self.play(Write(mathtex_label, run_time=1))
|
|
392
|
+
self.add(mathtex_label)
|
|
393
|
+
return mathtex_label
|
|
346
394
|
|
|
347
395
|
def position_x_coordinate(
|
|
348
396
|
self,
|
|
349
|
-
x_coord,
|
|
350
|
-
x_line,
|
|
351
|
-
vector,
|
|
352
|
-
): # TODO Write DocStrings for this.
|
|
397
|
+
x_coord: MathTex,
|
|
398
|
+
x_line: Line,
|
|
399
|
+
vector: Vector3DLike,
|
|
400
|
+
) -> MathTex: # TODO Write DocStrings for this.
|
|
353
401
|
x_coord.next_to(x_line, -np.sign(vector[1]) * UP)
|
|
354
402
|
x_coord.set_color(X_COLOR)
|
|
355
403
|
return x_coord
|
|
356
404
|
|
|
357
405
|
def position_y_coordinate(
|
|
358
406
|
self,
|
|
359
|
-
y_coord,
|
|
360
|
-
y_line,
|
|
361
|
-
vector,
|
|
362
|
-
): # TODO Write DocStrings for this.
|
|
407
|
+
y_coord: MathTex,
|
|
408
|
+
y_line: Line,
|
|
409
|
+
vector: Vector3DLike,
|
|
410
|
+
) -> MathTex: # TODO Write DocStrings for this.
|
|
363
411
|
y_coord.next_to(y_line, np.sign(vector[0]) * RIGHT)
|
|
364
412
|
y_coord.set_color(Y_COLOR)
|
|
365
413
|
return y_coord
|
|
366
414
|
|
|
367
415
|
def coords_to_vector(
|
|
368
416
|
self,
|
|
369
|
-
vector:
|
|
370
|
-
coords_start:
|
|
417
|
+
vector: Vector2DLike,
|
|
418
|
+
coords_start: Point3DLike = 2 * RIGHT + 2 * UP,
|
|
371
419
|
clean_up: bool = True,
|
|
372
|
-
):
|
|
420
|
+
) -> None:
|
|
373
421
|
"""
|
|
374
422
|
This method writes the vector as a column matrix (henceforth called the label),
|
|
375
423
|
takes the values in it one by one, and form the corresponding
|
|
@@ -400,26 +448,29 @@ class VectorScene(Scene):
|
|
|
400
448
|
y_line = Line(x_line.get_end(), arrow.get_end())
|
|
401
449
|
x_line.set_color(X_COLOR)
|
|
402
450
|
y_line.set_color(Y_COLOR)
|
|
403
|
-
|
|
451
|
+
mob_matrix = array.get_mob_matrix()
|
|
452
|
+
x_coord = mob_matrix[0][0]
|
|
453
|
+
y_coord = mob_matrix[1][0]
|
|
404
454
|
|
|
405
455
|
self.play(Write(array, run_time=1))
|
|
406
456
|
self.wait()
|
|
407
457
|
self.play(
|
|
408
458
|
ApplyFunction(
|
|
409
|
-
lambda x: self.position_x_coordinate(x, x_line, vector),
|
|
459
|
+
lambda x: self.position_x_coordinate(x, x_line, vector), # type: ignore[arg-type]
|
|
410
460
|
x_coord,
|
|
411
461
|
),
|
|
412
462
|
)
|
|
413
463
|
self.play(Create(x_line))
|
|
414
464
|
animations = [
|
|
415
465
|
ApplyFunction(
|
|
416
|
-
lambda y: self.position_y_coordinate(y, y_line, vector),
|
|
466
|
+
lambda y: self.position_y_coordinate(y, y_line, vector), # type: ignore[arg-type]
|
|
417
467
|
y_coord,
|
|
418
468
|
),
|
|
419
469
|
FadeOut(array.get_brackets()),
|
|
420
470
|
]
|
|
421
471
|
self.play(*animations)
|
|
422
|
-
|
|
472
|
+
# TODO: Can we delete the line below? I don't think it have any purpose.
|
|
473
|
+
# y_coord, _ = (anim.mobject for anim in animations)
|
|
423
474
|
self.play(Create(y_line))
|
|
424
475
|
self.play(Create(arrow))
|
|
425
476
|
self.wait()
|
|
@@ -429,10 +480,10 @@ class VectorScene(Scene):
|
|
|
429
480
|
|
|
430
481
|
def vector_to_coords(
|
|
431
482
|
self,
|
|
432
|
-
vector:
|
|
483
|
+
vector: Vector3DLike,
|
|
433
484
|
integer_labels: bool = True,
|
|
434
485
|
clean_up: bool = True,
|
|
435
|
-
):
|
|
486
|
+
) -> tuple[Matrix, Line, Line]:
|
|
436
487
|
"""
|
|
437
488
|
This method displays vector as a Vector() based vector, and then shows
|
|
438
489
|
the corresponding lines that make up the x and y components of the vector.
|
|
@@ -466,7 +517,7 @@ class VectorScene(Scene):
|
|
|
466
517
|
y_line = Line(x_line.get_end(), arrow.get_end())
|
|
467
518
|
x_line.set_color(X_COLOR)
|
|
468
519
|
y_line.set_color(Y_COLOR)
|
|
469
|
-
x_coord, y_coord = array.get_entries()
|
|
520
|
+
x_coord, y_coord = cast(VGroup, array.get_entries())
|
|
470
521
|
x_coord_start = self.position_x_coordinate(x_coord.copy(), x_line, vector)
|
|
471
522
|
y_coord_start = self.position_y_coordinate(y_coord.copy(), y_line, vector)
|
|
472
523
|
brackets = array.get_brackets()
|
|
@@ -490,7 +541,7 @@ class VectorScene(Scene):
|
|
|
490
541
|
self.add(*starting_mobjects)
|
|
491
542
|
return array, x_line, y_line
|
|
492
543
|
|
|
493
|
-
def show_ghost_movement(self, vector: Arrow |
|
|
544
|
+
def show_ghost_movement(self, vector: Arrow | Vector2DLike | Vector3DLike) -> None:
|
|
494
545
|
"""
|
|
495
546
|
This method plays an animation that partially shows the entire plane moving
|
|
496
547
|
in the direction of a particular vector. This is useful when you wish to
|
|
@@ -504,20 +555,26 @@ class VectorScene(Scene):
|
|
|
504
555
|
"""
|
|
505
556
|
if isinstance(vector, Arrow):
|
|
506
557
|
vector = vector.get_end() - vector.get_start()
|
|
507
|
-
|
|
508
|
-
vector = np.
|
|
509
|
-
|
|
510
|
-
|
|
558
|
+
else:
|
|
559
|
+
vector = np.asarray(vector)
|
|
560
|
+
if len(vector) == 2:
|
|
561
|
+
vector = np.append(np.array(vector), 0.0)
|
|
562
|
+
vector_cleaned: Vector3D = vector
|
|
563
|
+
|
|
564
|
+
x_max = int(config["frame_x_radius"] + abs(vector_cleaned[0]))
|
|
565
|
+
y_max = int(config["frame_y_radius"] + abs(vector_cleaned[1]))
|
|
566
|
+
# TODO:
|
|
567
|
+
# I think that this should be a VGroup instead of a VMobject.
|
|
511
568
|
dots = VMobject(
|
|
512
|
-
*(
|
|
569
|
+
*( # type: ignore[arg-type]
|
|
513
570
|
Dot(x * RIGHT + y * UP)
|
|
514
571
|
for x in range(-x_max, x_max)
|
|
515
572
|
for y in range(-y_max, y_max)
|
|
516
573
|
)
|
|
517
574
|
)
|
|
518
575
|
dots.set_fill(BLACK, opacity=0)
|
|
519
|
-
dots_halfway = dots.copy().shift(
|
|
520
|
-
dots_end = dots.copy().shift(
|
|
576
|
+
dots_halfway = dots.copy().shift(vector_cleaned / 2).set_fill(WHITE, 1)
|
|
577
|
+
dots_end = dots.copy().shift(vector_cleaned)
|
|
521
578
|
|
|
522
579
|
self.play(Transform(dots, dots_halfway, rate_func=rush_into))
|
|
523
580
|
self.play(Transform(dots, dots_end, rate_func=rush_from))
|
|
@@ -558,11 +615,12 @@ class LinearTransformationScene(VectorScene):
|
|
|
558
615
|
.. manim:: LinearTransformationSceneExample
|
|
559
616
|
|
|
560
617
|
class LinearTransformationSceneExample(LinearTransformationScene):
|
|
561
|
-
def __init__(self):
|
|
618
|
+
def __init__(self, **kwargs):
|
|
562
619
|
LinearTransformationScene.__init__(
|
|
563
620
|
self,
|
|
564
621
|
show_coordinates=True,
|
|
565
622
|
leave_ghost_vectors=True,
|
|
623
|
+
**kwargs
|
|
566
624
|
)
|
|
567
625
|
|
|
568
626
|
def construct(self):
|
|
@@ -575,17 +633,16 @@ class LinearTransformationScene(VectorScene):
|
|
|
575
633
|
self,
|
|
576
634
|
include_background_plane: bool = True,
|
|
577
635
|
include_foreground_plane: bool = True,
|
|
578
|
-
background_plane_kwargs: dict | None = None,
|
|
579
|
-
foreground_plane_kwargs: dict | None = None,
|
|
636
|
+
background_plane_kwargs: dict[str, Any] | None = None,
|
|
637
|
+
foreground_plane_kwargs: dict[str, Any] | None = None,
|
|
580
638
|
show_coordinates: bool = False,
|
|
581
639
|
show_basis_vectors: bool = True,
|
|
582
640
|
basis_vector_stroke_width: float = 6,
|
|
583
|
-
i_hat_color:
|
|
584
|
-
j_hat_color:
|
|
641
|
+
i_hat_color: ParsableManimColor = X_COLOR,
|
|
642
|
+
j_hat_color: ParsableManimColor = Y_COLOR,
|
|
585
643
|
leave_ghost_vectors: bool = False,
|
|
586
|
-
**kwargs,
|
|
587
|
-
):
|
|
588
|
-
|
|
644
|
+
**kwargs: Any,
|
|
645
|
+
) -> None:
|
|
589
646
|
super().__init__(**kwargs)
|
|
590
647
|
|
|
591
648
|
self.include_background_plane = include_background_plane
|
|
@@ -593,10 +650,10 @@ class LinearTransformationScene(VectorScene):
|
|
|
593
650
|
self.show_coordinates = show_coordinates
|
|
594
651
|
self.show_basis_vectors = show_basis_vectors
|
|
595
652
|
self.basis_vector_stroke_width = basis_vector_stroke_width
|
|
596
|
-
self.i_hat_color = i_hat_color
|
|
597
|
-
self.j_hat_color = j_hat_color
|
|
653
|
+
self.i_hat_color = ManimColor(i_hat_color)
|
|
654
|
+
self.j_hat_color = ManimColor(j_hat_color)
|
|
598
655
|
self.leave_ghost_vectors = leave_ghost_vectors
|
|
599
|
-
self.background_plane_kwargs = {
|
|
656
|
+
self.background_plane_kwargs: dict[str, Any] = {
|
|
600
657
|
"color": GREY,
|
|
601
658
|
"axis_config": {
|
|
602
659
|
"color": GREY,
|
|
@@ -607,7 +664,9 @@ class LinearTransformationScene(VectorScene):
|
|
|
607
664
|
},
|
|
608
665
|
}
|
|
609
666
|
|
|
610
|
-
self.
|
|
667
|
+
self.ghost_vectors = VGroup()
|
|
668
|
+
|
|
669
|
+
self.foreground_plane_kwargs: dict[str, Any] = {
|
|
611
670
|
"x_range": np.array([-config["frame_width"], config["frame_width"], 1.0]),
|
|
612
671
|
"y_range": np.array([-config["frame_width"], config["frame_width"], 1.0]),
|
|
613
672
|
"faded_line_ratio": 1,
|
|
@@ -619,22 +678,25 @@ class LinearTransformationScene(VectorScene):
|
|
|
619
678
|
)
|
|
620
679
|
|
|
621
680
|
@staticmethod
|
|
622
|
-
def update_default_configs(
|
|
681
|
+
def update_default_configs(
|
|
682
|
+
default_configs: Iterable[dict[str, Any]],
|
|
683
|
+
passed_configs: Iterable[dict[str, Any] | None],
|
|
684
|
+
) -> None:
|
|
623
685
|
for default_config, passed_config in zip(default_configs, passed_configs):
|
|
624
686
|
if passed_config is not None:
|
|
625
687
|
update_dict_recursively(default_config, passed_config)
|
|
626
688
|
|
|
627
|
-
def setup(self):
|
|
689
|
+
def setup(self) -> None:
|
|
628
690
|
# The has_already_setup attr is to not break all the old Scenes
|
|
629
691
|
if hasattr(self, "has_already_setup"):
|
|
630
692
|
return
|
|
631
693
|
self.has_already_setup = True
|
|
632
|
-
self.background_mobjects = []
|
|
633
|
-
self.foreground_mobjects = []
|
|
634
|
-
self.transformable_mobjects = []
|
|
635
|
-
self.moving_vectors = []
|
|
636
|
-
self.transformable_labels = []
|
|
637
|
-
self.moving_mobjects = []
|
|
694
|
+
self.background_mobjects: list[Mobject] = []
|
|
695
|
+
self.foreground_mobjects: list[Mobject] = []
|
|
696
|
+
self.transformable_mobjects: list[Mobject] = []
|
|
697
|
+
self.moving_vectors: list[Mobject] = []
|
|
698
|
+
self.transformable_labels: list[MathTex] = []
|
|
699
|
+
self.moving_mobjects: list[Mobject] = []
|
|
638
700
|
|
|
639
701
|
self.background_plane = NumberPlane(**self.background_plane_kwargs)
|
|
640
702
|
|
|
@@ -654,7 +716,9 @@ class LinearTransformationScene(VectorScene):
|
|
|
654
716
|
self.i_hat, self.j_hat = self.basis_vectors
|
|
655
717
|
self.add(self.basis_vectors)
|
|
656
718
|
|
|
657
|
-
def add_special_mobjects(
|
|
719
|
+
def add_special_mobjects(
|
|
720
|
+
self, mob_list: list[Mobject], *mobs_to_add: Mobject
|
|
721
|
+
) -> None:
|
|
658
722
|
"""
|
|
659
723
|
Adds mobjects to a separate list that can be tracked,
|
|
660
724
|
if these mobjects have some extra importance.
|
|
@@ -674,7 +738,7 @@ class LinearTransformationScene(VectorScene):
|
|
|
674
738
|
mob_list.append(mobject)
|
|
675
739
|
self.add(mobject)
|
|
676
740
|
|
|
677
|
-
def add_background_mobject(self, *mobjects: Mobject):
|
|
741
|
+
def add_background_mobject(self, *mobjects: Mobject) -> None:
|
|
678
742
|
"""
|
|
679
743
|
Adds the mobjects to the special list
|
|
680
744
|
self.background_mobjects.
|
|
@@ -686,8 +750,9 @@ class LinearTransformationScene(VectorScene):
|
|
|
686
750
|
"""
|
|
687
751
|
self.add_special_mobjects(self.background_mobjects, *mobjects)
|
|
688
752
|
|
|
689
|
-
# TODO, this conflicts with Scene.
|
|
690
|
-
|
|
753
|
+
# TODO, this conflicts with Scene.add_foreground_mobject
|
|
754
|
+
# Please be aware that there is also the method Scene.add_foreground_mobjects.
|
|
755
|
+
def add_foreground_mobject(self, *mobjects: Mobject) -> None: # type: ignore[override]
|
|
691
756
|
"""
|
|
692
757
|
Adds the mobjects to the special list
|
|
693
758
|
self.foreground_mobjects.
|
|
@@ -699,7 +764,7 @@ class LinearTransformationScene(VectorScene):
|
|
|
699
764
|
"""
|
|
700
765
|
self.add_special_mobjects(self.foreground_mobjects, *mobjects)
|
|
701
766
|
|
|
702
|
-
def add_transformable_mobject(self, *mobjects: Mobject):
|
|
767
|
+
def add_transformable_mobject(self, *mobjects: Mobject) -> None:
|
|
703
768
|
"""
|
|
704
769
|
Adds the mobjects to the special list
|
|
705
770
|
self.transformable_mobjects.
|
|
@@ -713,7 +778,7 @@ class LinearTransformationScene(VectorScene):
|
|
|
713
778
|
|
|
714
779
|
def add_moving_mobject(
|
|
715
780
|
self, mobject: Mobject, target_mobject: Mobject | None = None
|
|
716
|
-
):
|
|
781
|
+
) -> None:
|
|
717
782
|
"""
|
|
718
783
|
Adds the mobject to the special list
|
|
719
784
|
self.moving_mobject, and adds a property
|
|
@@ -732,9 +797,19 @@ class LinearTransformationScene(VectorScene):
|
|
|
732
797
|
mobject.target = target_mobject
|
|
733
798
|
self.add_special_mobjects(self.moving_mobjects, mobject)
|
|
734
799
|
|
|
800
|
+
def get_ghost_vectors(self) -> VGroup:
|
|
801
|
+
"""
|
|
802
|
+
Returns all ghost vectors ever added to ``self``. Each element is a ``VGroup`` of
|
|
803
|
+
two ghost vectors.
|
|
804
|
+
"""
|
|
805
|
+
return self.ghost_vectors
|
|
806
|
+
|
|
735
807
|
def get_unit_square(
|
|
736
|
-
self,
|
|
737
|
-
|
|
808
|
+
self,
|
|
809
|
+
color: ParsableManimColor | Iterable[ParsableManimColor] = YELLOW,
|
|
810
|
+
opacity: float = 0.3,
|
|
811
|
+
stroke_width: float = 3,
|
|
812
|
+
) -> Rectangle:
|
|
738
813
|
"""
|
|
739
814
|
Returns a unit square for the current NumberPlane.
|
|
740
815
|
|
|
@@ -765,7 +840,7 @@ class LinearTransformationScene(VectorScene):
|
|
|
765
840
|
square.move_to(self.plane.coords_to_point(0, 0), DL)
|
|
766
841
|
return square
|
|
767
842
|
|
|
768
|
-
def add_unit_square(self, animate: bool = False, **kwargs):
|
|
843
|
+
def add_unit_square(self, animate: bool = False, **kwargs: Any) -> Self:
|
|
769
844
|
"""
|
|
770
845
|
Adds a unit square to the scene via
|
|
771
846
|
self.get_unit_square.
|
|
@@ -796,8 +871,12 @@ class LinearTransformationScene(VectorScene):
|
|
|
796
871
|
return self
|
|
797
872
|
|
|
798
873
|
def add_vector(
|
|
799
|
-
self,
|
|
800
|
-
|
|
874
|
+
self,
|
|
875
|
+
vector: Arrow | list | tuple | np.ndarray,
|
|
876
|
+
color: ParsableManimColor = YELLOW,
|
|
877
|
+
animate: bool = False,
|
|
878
|
+
**kwargs: Any,
|
|
879
|
+
) -> Arrow:
|
|
801
880
|
"""
|
|
802
881
|
Adds a vector to the scene, and puts it in the special
|
|
803
882
|
list self.moving_vectors.
|
|
@@ -821,11 +900,11 @@ class LinearTransformationScene(VectorScene):
|
|
|
821
900
|
Arrow
|
|
822
901
|
The arrow representing the vector.
|
|
823
902
|
"""
|
|
824
|
-
vector = super().add_vector(vector, color=color, **kwargs)
|
|
903
|
+
vector = super().add_vector(vector, color=color, animate=animate, **kwargs)
|
|
825
904
|
self.moving_vectors.append(vector)
|
|
826
905
|
return vector
|
|
827
906
|
|
|
828
|
-
def write_vector_coordinates(self, vector:
|
|
907
|
+
def write_vector_coordinates(self, vector: Vector, **kwargs: Any) -> Matrix:
|
|
829
908
|
"""
|
|
830
909
|
Returns a column matrix indicating the vector coordinates,
|
|
831
910
|
after writing them to the screen, and adding them to the
|
|
@@ -854,8 +933,8 @@ class LinearTransformationScene(VectorScene):
|
|
|
854
933
|
label: MathTex | str,
|
|
855
934
|
transformation_name: str | MathTex = "L",
|
|
856
935
|
new_label: str | MathTex | None = None,
|
|
857
|
-
**kwargs,
|
|
858
|
-
):
|
|
936
|
+
**kwargs: Any,
|
|
937
|
+
) -> MathTex:
|
|
859
938
|
"""
|
|
860
939
|
Method for creating, and animating the addition of
|
|
861
940
|
a transformable label for the vector.
|
|
@@ -882,27 +961,27 @@ class LinearTransformationScene(VectorScene):
|
|
|
882
961
|
:class:`~.MathTex`
|
|
883
962
|
The MathTex of the label.
|
|
884
963
|
"""
|
|
964
|
+
# TODO: Clear up types in this function. This is currently a mess.
|
|
885
965
|
label_mob = self.label_vector(vector, label, **kwargs)
|
|
886
966
|
if new_label:
|
|
887
|
-
label_mob.target_text = new_label
|
|
967
|
+
label_mob.target_text = new_label # type: ignore[attr-defined]
|
|
888
968
|
else:
|
|
889
|
-
label_mob.target_text =
|
|
890
|
-
transformation_name
|
|
891
|
-
label_mob.get_tex_string(),
|
|
969
|
+
label_mob.target_text = ( # type: ignore[attr-defined]
|
|
970
|
+
f"{transformation_name}({label_mob.get_tex_string()})"
|
|
892
971
|
)
|
|
893
|
-
label_mob.vector = vector
|
|
894
|
-
label_mob.kwargs = kwargs
|
|
972
|
+
label_mob.vector = vector # type: ignore[attr-defined]
|
|
973
|
+
label_mob.kwargs = kwargs # type: ignore[attr-defined]
|
|
895
974
|
if "animate" in label_mob.kwargs:
|
|
896
975
|
label_mob.kwargs.pop("animate")
|
|
897
976
|
self.transformable_labels.append(label_mob)
|
|
898
|
-
return label_mob
|
|
977
|
+
return cast(MathTex, label_mob)
|
|
899
978
|
|
|
900
979
|
def add_title(
|
|
901
980
|
self,
|
|
902
981
|
title: str | MathTex | Tex,
|
|
903
982
|
scale_factor: float = 1.5,
|
|
904
983
|
animate: bool = False,
|
|
905
|
-
):
|
|
984
|
+
) -> Self:
|
|
906
985
|
"""
|
|
907
986
|
Adds a title, after scaling it, adding a background rectangle,
|
|
908
987
|
moving it to the top and adding it to foreground_mobjects adding
|
|
@@ -934,7 +1013,9 @@ class LinearTransformationScene(VectorScene):
|
|
|
934
1013
|
self.title = title
|
|
935
1014
|
return self
|
|
936
1015
|
|
|
937
|
-
def get_matrix_transformation(
|
|
1016
|
+
def get_matrix_transformation(
|
|
1017
|
+
self, matrix: np.ndarray | list | tuple
|
|
1018
|
+
) -> Callable[[Point3D], Point3D]:
|
|
938
1019
|
"""
|
|
939
1020
|
Returns a function corresponding to the linear
|
|
940
1021
|
transformation represented by the matrix passed.
|
|
@@ -948,7 +1029,7 @@ class LinearTransformationScene(VectorScene):
|
|
|
948
1029
|
|
|
949
1030
|
def get_transposed_matrix_transformation(
|
|
950
1031
|
self, transposed_matrix: np.ndarray | list | tuple
|
|
951
|
-
):
|
|
1032
|
+
) -> Callable[[Point3D], Point3D]:
|
|
952
1033
|
"""
|
|
953
1034
|
Returns a function corresponding to the linear
|
|
954
1035
|
transformation represented by the transposed
|
|
@@ -968,7 +1049,7 @@ class LinearTransformationScene(VectorScene):
|
|
|
968
1049
|
raise ValueError("Matrix has bad dimensions")
|
|
969
1050
|
return lambda point: np.dot(point, transposed_matrix)
|
|
970
1051
|
|
|
971
|
-
def get_piece_movement(self, pieces:
|
|
1052
|
+
def get_piece_movement(self, pieces: Iterable[Mobject]) -> Transform:
|
|
972
1053
|
"""
|
|
973
1054
|
This method returns an animation that moves an arbitrary
|
|
974
1055
|
mobject in "pieces" to its corresponding .target value.
|
|
@@ -985,13 +1066,18 @@ class LinearTransformationScene(VectorScene):
|
|
|
985
1066
|
Animation
|
|
986
1067
|
The animation of the movement.
|
|
987
1068
|
"""
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1069
|
+
v_pieces = [piece for piece in pieces if isinstance(piece, VMobject)]
|
|
1070
|
+
start = VGroup(*v_pieces)
|
|
1071
|
+
target = VGroup(*(mob.target for mob in v_pieces))
|
|
1072
|
+
|
|
1073
|
+
# don't add empty VGroups
|
|
1074
|
+
if self.leave_ghost_vectors and start.submobjects:
|
|
1075
|
+
# start.copy() gives a VGroup of Vectors
|
|
1076
|
+
self.ghost_vectors.add(start.copy().fade(0.7))
|
|
1077
|
+
self.add(self.ghost_vectors[-1])
|
|
992
1078
|
return Transform(start, target, lag_ratio=0)
|
|
993
1079
|
|
|
994
|
-
def get_moving_mobject_movement(self, func:
|
|
1080
|
+
def get_moving_mobject_movement(self, func: MappingFunction) -> Transform:
|
|
995
1081
|
"""
|
|
996
1082
|
This method returns an animation that moves a mobject
|
|
997
1083
|
in "self.moving_mobjects" to its corresponding .target value.
|
|
@@ -1012,11 +1098,12 @@ class LinearTransformationScene(VectorScene):
|
|
|
1012
1098
|
for m in self.moving_mobjects:
|
|
1013
1099
|
if m.target is None:
|
|
1014
1100
|
m.target = m.copy()
|
|
1015
|
-
|
|
1101
|
+
temp: Point3D = m.get_center()
|
|
1102
|
+
target_point = func(temp)
|
|
1016
1103
|
m.target.move_to(target_point)
|
|
1017
1104
|
return self.get_piece_movement(self.moving_mobjects)
|
|
1018
1105
|
|
|
1019
|
-
def get_vector_movement(self, func:
|
|
1106
|
+
def get_vector_movement(self, func: MappingFunction) -> Transform:
|
|
1020
1107
|
"""
|
|
1021
1108
|
This method returns an animation that moves a mobject
|
|
1022
1109
|
in "self.moving_vectors" to its corresponding .target value.
|
|
@@ -1036,12 +1123,12 @@ class LinearTransformationScene(VectorScene):
|
|
|
1036
1123
|
"""
|
|
1037
1124
|
for v in self.moving_vectors:
|
|
1038
1125
|
v.target = Vector(func(v.get_end()), color=v.get_color())
|
|
1039
|
-
norm = np.linalg.norm(v.target.get_end())
|
|
1126
|
+
norm = float(np.linalg.norm(v.target.get_end()))
|
|
1040
1127
|
if norm < 0.1:
|
|
1041
1128
|
v.target.get_tip().scale(norm)
|
|
1042
1129
|
return self.get_piece_movement(self.moving_vectors)
|
|
1043
1130
|
|
|
1044
|
-
def get_transformable_label_movement(self):
|
|
1131
|
+
def get_transformable_label_movement(self) -> Transform:
|
|
1045
1132
|
"""
|
|
1046
1133
|
This method returns an animation that moves all labels
|
|
1047
1134
|
in "self.transformable_labels" to its corresponding .target .
|
|
@@ -1052,12 +1139,17 @@ class LinearTransformationScene(VectorScene):
|
|
|
1052
1139
|
The animation of the movement.
|
|
1053
1140
|
"""
|
|
1054
1141
|
for label in self.transformable_labels:
|
|
1142
|
+
# TODO: This location and lines 933 and 335 are the only locations in
|
|
1143
|
+
# the code where the target_text property is referenced.
|
|
1144
|
+
target_text: MathTex | str = label.target_text # type: ignore[assignment]
|
|
1055
1145
|
label.target = self.get_vector_label(
|
|
1056
|
-
label.vector.target,
|
|
1146
|
+
label.vector.target, # type: ignore[attr-defined]
|
|
1147
|
+
target_text,
|
|
1148
|
+
**label.kwargs, # type: ignore[arg-type]
|
|
1057
1149
|
)
|
|
1058
1150
|
return self.get_piece_movement(self.transformable_labels)
|
|
1059
1151
|
|
|
1060
|
-
def apply_matrix(self, matrix: np.ndarray | list | tuple, **kwargs):
|
|
1152
|
+
def apply_matrix(self, matrix: np.ndarray | list | tuple, **kwargs: Any) -> None:
|
|
1061
1153
|
"""
|
|
1062
1154
|
Applies the transformation represented by the
|
|
1063
1155
|
given matrix to the number plane, and each vector/similar
|
|
@@ -1072,7 +1164,7 @@ class LinearTransformationScene(VectorScene):
|
|
|
1072
1164
|
"""
|
|
1073
1165
|
self.apply_transposed_matrix(np.array(matrix).T, **kwargs)
|
|
1074
1166
|
|
|
1075
|
-
def apply_inverse(self, matrix: np.ndarray | list | tuple, **kwargs):
|
|
1167
|
+
def apply_inverse(self, matrix: np.ndarray | list | tuple, **kwargs: Any) -> None:
|
|
1076
1168
|
"""
|
|
1077
1169
|
This method applies the linear transformation
|
|
1078
1170
|
represented by the inverse of the passed matrix
|
|
@@ -1088,8 +1180,8 @@ class LinearTransformationScene(VectorScene):
|
|
|
1088
1180
|
self.apply_matrix(np.linalg.inv(matrix), **kwargs)
|
|
1089
1181
|
|
|
1090
1182
|
def apply_transposed_matrix(
|
|
1091
|
-
self, transposed_matrix: np.ndarray | list | tuple, **kwargs
|
|
1092
|
-
):
|
|
1183
|
+
self, transposed_matrix: np.ndarray | list | tuple, **kwargs: Any
|
|
1184
|
+
) -> None:
|
|
1093
1185
|
"""
|
|
1094
1186
|
Applies the transformation represented by the
|
|
1095
1187
|
given transposed matrix to the number plane,
|
|
@@ -1110,7 +1202,9 @@ class LinearTransformationScene(VectorScene):
|
|
|
1110
1202
|
kwargs["path_arc"] = net_rotation
|
|
1111
1203
|
self.apply_function(func, **kwargs)
|
|
1112
1204
|
|
|
1113
|
-
def apply_inverse_transpose(
|
|
1205
|
+
def apply_inverse_transpose(
|
|
1206
|
+
self, t_matrix: np.ndarray | list | tuple, **kwargs: Any
|
|
1207
|
+
) -> None:
|
|
1114
1208
|
"""
|
|
1115
1209
|
Applies the inverse of the transformation represented
|
|
1116
1210
|
by the given transposed matrix to the number plane and each
|
|
@@ -1127,8 +1221,8 @@ class LinearTransformationScene(VectorScene):
|
|
|
1127
1221
|
self.apply_transposed_matrix(t_inv, **kwargs)
|
|
1128
1222
|
|
|
1129
1223
|
def apply_nonlinear_transformation(
|
|
1130
|
-
self, function: Callable[[np.ndarray], np.ndarray], **kwargs
|
|
1131
|
-
):
|
|
1224
|
+
self, function: Callable[[np.ndarray], np.ndarray], **kwargs: Any
|
|
1225
|
+
) -> None:
|
|
1132
1226
|
"""
|
|
1133
1227
|
Applies the non-linear transformation represented
|
|
1134
1228
|
by the given function to the number plane and each
|
|
@@ -1146,10 +1240,10 @@ class LinearTransformationScene(VectorScene):
|
|
|
1146
1240
|
|
|
1147
1241
|
def apply_function(
|
|
1148
1242
|
self,
|
|
1149
|
-
function:
|
|
1150
|
-
added_anims: list = [],
|
|
1151
|
-
**kwargs,
|
|
1152
|
-
):
|
|
1243
|
+
function: MappingFunction,
|
|
1244
|
+
added_anims: list[Animation] = [],
|
|
1245
|
+
**kwargs: Any,
|
|
1246
|
+
) -> None:
|
|
1153
1247
|
"""
|
|
1154
1248
|
Applies the given function to each of the mobjects in
|
|
1155
1249
|
self.transformable_mobjects, and plays the animation showing
|
|
@@ -1172,7 +1266,7 @@ class LinearTransformationScene(VectorScene):
|
|
|
1172
1266
|
kwargs["run_time"] = 3
|
|
1173
1267
|
anims = (
|
|
1174
1268
|
[
|
|
1175
|
-
ApplyPointwiseFunction(function, t_mob)
|
|
1269
|
+
ApplyPointwiseFunction(function, t_mob) # type: ignore[arg-type]
|
|
1176
1270
|
for t_mob in self.transformable_mobjects
|
|
1177
1271
|
]
|
|
1178
1272
|
+ [
|