manim 0.18.0.post0__py3-none-any.whl → 0.19.0__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.
Potentially problematic release.
This version of manim might be problematic. Click here for more details.
- manim/__init__.py +3 -6
- manim/__main__.py +61 -20
- manim/_config/__init__.py +6 -3
- manim/_config/cli_colors.py +16 -8
- manim/_config/default.cfg +1 -3
- manim/_config/logger_utils.py +14 -8
- manim/_config/utils.py +651 -472
- manim/animation/animation.py +152 -5
- manim/animation/composition.py +80 -39
- manim/animation/creation.py +196 -14
- manim/animation/fading.py +5 -9
- manim/animation/indication.py +103 -47
- manim/animation/movement.py +22 -5
- manim/animation/rotation.py +3 -2
- manim/animation/specialized.py +4 -6
- manim/animation/speedmodifier.py +10 -5
- manim/animation/transform.py +4 -5
- manim/animation/transform_matching_parts.py +1 -1
- manim/animation/updaters/mobject_update_utils.py +17 -14
- manim/camera/camera.py +15 -6
- manim/cli/__init__.py +17 -0
- manim/cli/cfg/group.py +70 -44
- manim/cli/checkhealth/checks.py +93 -75
- manim/cli/checkhealth/commands.py +14 -5
- manim/cli/default_group.py +157 -25
- manim/cli/init/commands.py +32 -24
- 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 +51 -15
- manim/cli/render/output_options.py +6 -5
- manim/cli/render/render_options.py +97 -32
- manim/constants.py +65 -19
- manim/gui/gui.py +2 -0
- manim/mobject/frame.py +0 -1
- manim/mobject/geometry/arc.py +112 -78
- manim/mobject/geometry/boolean_ops.py +32 -25
- manim/mobject/geometry/labeled.py +300 -77
- manim/mobject/geometry/line.py +132 -64
- manim/mobject/geometry/polygram.py +126 -30
- manim/mobject/geometry/shape_matchers.py +35 -15
- manim/mobject/geometry/tips.py +38 -29
- manim/mobject/graph.py +414 -133
- manim/mobject/graphing/coordinate_systems.py +126 -64
- manim/mobject/graphing/functions.py +25 -15
- manim/mobject/graphing/number_line.py +24 -10
- manim/mobject/graphing/probability.py +2 -10
- manim/mobject/graphing/scale.py +6 -5
- manim/mobject/matrix.py +17 -19
- manim/mobject/mobject.py +314 -165
- manim/mobject/opengl/opengl_compatibility.py +2 -0
- manim/mobject/opengl/opengl_geometry.py +30 -9
- manim/mobject/opengl/opengl_image_mobject.py +2 -0
- manim/mobject/opengl/opengl_mobject.py +509 -343
- manim/mobject/opengl/opengl_point_cloud_mobject.py +5 -7
- manim/mobject/opengl/opengl_surface.py +3 -2
- manim/mobject/opengl/opengl_three_dimensions.py +2 -0
- manim/mobject/opengl/opengl_vectorized_mobject.py +46 -79
- manim/mobject/svg/brace.py +63 -13
- manim/mobject/svg/svg_mobject.py +4 -3
- manim/mobject/table.py +11 -13
- manim/mobject/text/code_mobject.py +186 -548
- manim/mobject/text/numbers.py +9 -7
- manim/mobject/text/tex_mobject.py +23 -14
- manim/mobject/text/text_mobject.py +70 -24
- manim/mobject/three_d/polyhedra.py +98 -1
- manim/mobject/three_d/three_d_utils.py +4 -4
- manim/mobject/three_d/three_dimensions.py +62 -34
- manim/mobject/types/image_mobject.py +42 -24
- manim/mobject/types/point_cloud_mobject.py +105 -67
- manim/mobject/types/vectorized_mobject.py +496 -228
- manim/mobject/value_tracker.py +5 -4
- manim/mobject/vector_field.py +5 -5
- manim/opengl/__init__.py +3 -3
- manim/plugins/__init__.py +14 -1
- manim/plugins/plugins_flags.py +14 -8
- manim/renderer/cairo_renderer.py +20 -10
- manim/renderer/opengl_renderer.py +21 -23
- manim/renderer/opengl_renderer_window.py +2 -0
- manim/renderer/shader.py +2 -3
- manim/renderer/shader_wrapper.py +5 -2
- manim/renderer/vectorized_mobject_rendering.py +5 -0
- manim/scene/moving_camera_scene.py +23 -0
- manim/scene/scene.py +90 -43
- manim/scene/scene_file_writer.py +316 -165
- manim/scene/section.py +17 -15
- manim/scene/three_d_scene.py +13 -21
- manim/scene/vector_space_scene.py +22 -9
- manim/typing.py +830 -70
- manim/utils/bezier.py +1667 -399
- manim/utils/caching.py +13 -5
- manim/utils/color/AS2700.py +2 -0
- manim/utils/color/BS381.py +3 -0
- manim/utils/color/DVIPSNAMES.py +96 -0
- manim/utils/color/SVGNAMES.py +179 -0
- manim/utils/color/X11.py +3 -0
- manim/utils/color/XKCD.py +3 -0
- manim/utils/color/__init__.py +8 -5
- manim/utils/color/core.py +844 -309
- manim/utils/color/manim_colors.py +7 -9
- manim/utils/commands.py +48 -20
- manim/utils/config_ops.py +18 -13
- manim/utils/debug.py +8 -7
- manim/utils/deprecation.py +90 -40
- manim/utils/docbuild/__init__.py +17 -0
- manim/utils/docbuild/autoaliasattr_directive.py +234 -0
- manim/utils/docbuild/autocolor_directive.py +21 -17
- manim/utils/docbuild/manim_directive.py +50 -35
- 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 +26 -16
- manim/utils/hashing.py +9 -7
- manim/utils/images.py +10 -4
- manim/utils/ipython_magic.py +14 -8
- manim/utils/iterables.py +161 -119
- manim/utils/module_ops.py +57 -19
- manim/utils/opengl.py +83 -24
- manim/utils/parameter_parsing.py +32 -0
- manim/utils/paths.py +21 -23
- manim/utils/polylabel.py +168 -0
- manim/utils/qhull.py +218 -0
- manim/utils/rate_functions.py +74 -39
- manim/utils/simple_functions.py +24 -15
- manim/utils/sounds.py +7 -1
- manim/utils/space_ops.py +125 -69
- 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 +33 -18
- manim/utils/testing/frames_comparison.py +27 -19
- manim/utils/tex.py +127 -197
- manim/utils/tex_file_writing.py +47 -45
- manim/utils/tex_templates.py +2 -1
- manim/utils/unit.py +6 -5
- {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/LICENSE.community +1 -1
- {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/METADATA +40 -39
- manim-0.19.0.dist-info/RECORD +221 -0
- {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/WHEEL +1 -1
- manim/cli/new/__init__.py +0 -0
- manim/cli/new/group.py +0 -189
- manim/plugins/import_plugins.py +0 -43
- manim-0.18.0.post0.dist-info/RECORD +0 -217
- {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/LICENSE +0 -0
- {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/entry_points.txt +0 -0
|
@@ -12,6 +12,8 @@ from manim.utils.color import BLACK, WHITE, YELLOW, color_gradient, color_to_rgb
|
|
|
12
12
|
from manim.utils.config_ops import _Uniforms
|
|
13
13
|
from manim.utils.iterables import resize_with_interpolation
|
|
14
14
|
|
|
15
|
+
__all__ = ["OpenGLPMobject", "OpenGLPGroup", "OpenGLPMPoint"]
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
class OpenGLPMobject(OpenGLMobject):
|
|
17
19
|
shader_folder = "true_dot"
|
|
@@ -63,13 +65,11 @@ class OpenGLPMobject(OpenGLMobject):
|
|
|
63
65
|
return self
|
|
64
66
|
|
|
65
67
|
def thin_out(self, factor=5):
|
|
66
|
-
"""
|
|
67
|
-
Removes all but every nth point for n = factor
|
|
68
|
-
"""
|
|
68
|
+
"""Removes all but every nth point for n = factor"""
|
|
69
69
|
for mob in self.family_members_with_points():
|
|
70
70
|
num_points = mob.get_num_points()
|
|
71
71
|
|
|
72
|
-
def thin_func():
|
|
72
|
+
def thin_func(num_points=num_points):
|
|
73
73
|
return np.arange(0, num_points, factor)
|
|
74
74
|
|
|
75
75
|
if len(mob.points) == len(mob.rgbas):
|
|
@@ -124,9 +124,7 @@ class OpenGLPMobject(OpenGLMobject):
|
|
|
124
124
|
return self
|
|
125
125
|
|
|
126
126
|
def sort_points(self, function=lambda p: p[0]):
|
|
127
|
-
"""
|
|
128
|
-
function is any map from R^3 to R
|
|
129
|
-
"""
|
|
127
|
+
"""function is any map from R^3 to R"""
|
|
130
128
|
for mob in self.family_members_with_points():
|
|
131
129
|
indices = np.argsort(np.apply_along_axis(function, 1, mob.points))
|
|
132
130
|
for key in mob.data:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from collections.abc import Iterable
|
|
3
4
|
from pathlib import Path
|
|
4
|
-
from typing import Iterable
|
|
5
5
|
|
|
6
6
|
import moderngl
|
|
7
7
|
import numpy as np
|
|
@@ -12,11 +12,12 @@ from manim.mobject.opengl.opengl_mobject import OpenGLMobject
|
|
|
12
12
|
from manim.utils.bezier import integer_interpolate, interpolate
|
|
13
13
|
from manim.utils.color import *
|
|
14
14
|
from manim.utils.config_ops import _Data, _Uniforms
|
|
15
|
-
from manim.utils.deprecation import deprecated
|
|
16
15
|
from manim.utils.images import change_to_rgba_array, get_full_raster_image_path
|
|
17
16
|
from manim.utils.iterables import listify
|
|
18
17
|
from manim.utils.space_ops import normalize_along_axis
|
|
19
18
|
|
|
19
|
+
__all__ = ["OpenGLSurface", "OpenGLTexturedSurface"]
|
|
20
|
+
|
|
20
21
|
|
|
21
22
|
class OpenGLSurface(OpenGLMobject):
|
|
22
23
|
r"""Creates a Surface.
|
|
@@ -5,6 +5,8 @@ import numpy as np
|
|
|
5
5
|
from manim.mobject.opengl.opengl_surface import OpenGLSurface
|
|
6
6
|
from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup, OpenGLVMobject
|
|
7
7
|
|
|
8
|
+
__all__ = ["OpenGLSurfaceMesh"]
|
|
9
|
+
|
|
8
10
|
|
|
9
11
|
class OpenGLSurfaceMesh(OpenGLVGroup):
|
|
10
12
|
def __init__(
|
|
@@ -2,8 +2,9 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import itertools as it
|
|
4
4
|
import operator as op
|
|
5
|
+
from collections.abc import Iterable, Sequence
|
|
5
6
|
from functools import reduce, wraps
|
|
6
|
-
from typing import Callable
|
|
7
|
+
from typing import Callable
|
|
7
8
|
|
|
8
9
|
import moderngl
|
|
9
10
|
import numpy as np
|
|
@@ -14,17 +15,17 @@ from manim.mobject.opengl.opengl_mobject import OpenGLMobject, OpenGLPoint
|
|
|
14
15
|
from manim.renderer.shader_wrapper import ShaderWrapper
|
|
15
16
|
from manim.utils.bezier import (
|
|
16
17
|
bezier,
|
|
18
|
+
bezier_remap,
|
|
17
19
|
get_quadratic_approximation_of_cubic,
|
|
18
20
|
get_smooth_cubic_bezier_handle_points,
|
|
19
21
|
integer_interpolate,
|
|
20
22
|
interpolate,
|
|
21
|
-
|
|
23
|
+
partial_bezier_points,
|
|
22
24
|
proportions_along_bezier_curve_for_point,
|
|
23
|
-
quadratic_bezier_remap,
|
|
24
25
|
)
|
|
25
26
|
from manim.utils.color import BLACK, WHITE, ManimColor, ParsableManimColor
|
|
26
27
|
from manim.utils.config_ops import _Data
|
|
27
|
-
from manim.utils.iterables import
|
|
28
|
+
from manim.utils.iterables import make_even, resize_with_interpolation, tuplify
|
|
28
29
|
from manim.utils.space_ops import (
|
|
29
30
|
angle_between_vectors,
|
|
30
31
|
cross2d,
|
|
@@ -34,6 +35,15 @@ from manim.utils.space_ops import (
|
|
|
34
35
|
z_to_vector,
|
|
35
36
|
)
|
|
36
37
|
|
|
38
|
+
__all__ = [
|
|
39
|
+
"triggers_refreshed_triangulation",
|
|
40
|
+
"OpenGLVMobject",
|
|
41
|
+
"OpenGLVGroup",
|
|
42
|
+
"OpenGLVectorizedPoint",
|
|
43
|
+
"OpenGLCurvesAsSubmobjects",
|
|
44
|
+
"OpenGLDashedVMobject",
|
|
45
|
+
]
|
|
46
|
+
|
|
37
47
|
|
|
38
48
|
def triggers_refreshed_triangulation(func):
|
|
39
49
|
@wraps(func)
|
|
@@ -151,6 +161,9 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
151
161
|
if stroke_color is not None:
|
|
152
162
|
self.stroke_color = ManimColor.parse(stroke_color)
|
|
153
163
|
|
|
164
|
+
def _assert_valid_submobjects(self, submobjects: Iterable[OpenGLVMobject]) -> Self:
|
|
165
|
+
return self._assert_valid_submobjects_internal(submobjects, OpenGLVMobject)
|
|
166
|
+
|
|
154
167
|
def get_group_class(self):
|
|
155
168
|
return OpenGLVGroup
|
|
156
169
|
|
|
@@ -256,7 +269,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
256
269
|
|
|
257
270
|
if width is not None:
|
|
258
271
|
for mob in self.get_family(recurse):
|
|
259
|
-
mob.stroke_width = np.array([[width] for width in
|
|
272
|
+
mob.stroke_width = np.array([[width] for width in tuplify(width)])
|
|
260
273
|
|
|
261
274
|
if background is not None:
|
|
262
275
|
for mob in self.get_family(recurse):
|
|
@@ -311,6 +324,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
311
324
|
vmobject_style = vmobject.get_style()
|
|
312
325
|
if config.renderer == RendererType.OPENGL:
|
|
313
326
|
vmobject_style["stroke_width"] = vmobject_style["stroke_width"][0][0]
|
|
327
|
+
vmobject_style["fill_opacity"] = self.get_fill_opacity()
|
|
314
328
|
self.set_style(**vmobject_style, recurse=False)
|
|
315
329
|
if recurse:
|
|
316
330
|
# Does its best to match up submobject lists, and
|
|
@@ -392,7 +406,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
392
406
|
return self.get_stroke_opacities()[0]
|
|
393
407
|
|
|
394
408
|
def get_color(self):
|
|
395
|
-
if self.
|
|
409
|
+
if not self.has_fill():
|
|
396
410
|
return self.get_stroke_color()
|
|
397
411
|
return self.get_fill_color()
|
|
398
412
|
|
|
@@ -458,9 +472,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
458
472
|
self.append_points(new_points)
|
|
459
473
|
|
|
460
474
|
def add_cubic_bezier_curve_to(self, handle1, handle2, anchor):
|
|
461
|
-
"""
|
|
462
|
-
Add cubic bezier curve to the path.
|
|
463
|
-
"""
|
|
475
|
+
"""Add cubic bezier curve to the path."""
|
|
464
476
|
self.throw_error_if_no_points()
|
|
465
477
|
quadratic_approx = get_quadratic_approximation_of_cubic(
|
|
466
478
|
self.get_last_point(),
|
|
@@ -545,7 +557,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
545
557
|
alphas = np.linspace(0, 1, n + 1)
|
|
546
558
|
new_points.extend(
|
|
547
559
|
[
|
|
548
|
-
|
|
560
|
+
partial_bezier_points(tup, a1, a2)
|
|
549
561
|
for a1, a2 in zip(alphas, alphas[1:])
|
|
550
562
|
],
|
|
551
563
|
)
|
|
@@ -803,7 +815,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
803
815
|
length : :class:`float`
|
|
804
816
|
The length of the nth curve.
|
|
805
817
|
"""
|
|
806
|
-
|
|
807
818
|
if sample_points is None:
|
|
808
819
|
sample_points = 10
|
|
809
820
|
|
|
@@ -843,7 +854,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
843
854
|
length : :class:`float`
|
|
844
855
|
The length of the nth curve.
|
|
845
856
|
"""
|
|
846
|
-
|
|
847
857
|
_, length = self.get_nth_curve_function_with_length(n, sample_points)
|
|
848
858
|
|
|
849
859
|
return length
|
|
@@ -858,7 +868,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
858
868
|
Iterable[Callable[[float], np.ndarray]]
|
|
859
869
|
The functions for the curves.
|
|
860
870
|
"""
|
|
861
|
-
|
|
862
871
|
num_curves = self.get_num_curves()
|
|
863
872
|
|
|
864
873
|
for n in range(num_curves):
|
|
@@ -908,7 +917,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
908
917
|
Iterable[Tuple[Callable[[float], np.ndarray], float]]
|
|
909
918
|
The functions and lengths of the curves.
|
|
910
919
|
"""
|
|
911
|
-
|
|
912
920
|
num_curves = self.get_num_curves()
|
|
913
921
|
|
|
914
922
|
for n in range(num_curves):
|
|
@@ -934,7 +942,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
934
942
|
:exc:`Exception`
|
|
935
943
|
If the :class:`OpenGLVMobject` has no points.
|
|
936
944
|
"""
|
|
937
|
-
|
|
938
945
|
if alpha < 0 or alpha > 1:
|
|
939
946
|
raise ValueError(f"Alpha {alpha} not between 0 and 1.")
|
|
940
947
|
|
|
@@ -944,7 +951,9 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
944
951
|
|
|
945
952
|
curves_and_lengths = tuple(self.get_curve_functions_with_lengths())
|
|
946
953
|
|
|
947
|
-
target_length = alpha * np.sum(
|
|
954
|
+
target_length = alpha * np.sum(
|
|
955
|
+
np.fromiter((length for _, length in curves_and_lengths), dtype=np.float64)
|
|
956
|
+
)
|
|
948
957
|
current_length = 0
|
|
949
958
|
|
|
950
959
|
for curve, length in curves_and_lengths:
|
|
@@ -1014,7 +1023,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1014
1023
|
|
|
1015
1024
|
return alpha
|
|
1016
1025
|
|
|
1017
|
-
def get_anchors_and_handles(self):
|
|
1026
|
+
def get_anchors_and_handles(self) -> Iterable[np.ndarray]:
|
|
1018
1027
|
"""
|
|
1019
1028
|
Returns anchors1, handles, anchors2,
|
|
1020
1029
|
where (anchors1[i], handles[i], anchors2[i])
|
|
@@ -1046,27 +1055,21 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1046
1055
|
nppc = self.n_points_per_curve
|
|
1047
1056
|
return self.points[nppc - 1 :: nppc]
|
|
1048
1057
|
|
|
1049
|
-
def get_anchors(self) -> np.ndarray:
|
|
1058
|
+
def get_anchors(self) -> Iterable[np.ndarray]:
|
|
1050
1059
|
"""Returns the anchors of the curves forming the OpenGLVMobject.
|
|
1051
1060
|
|
|
1052
1061
|
Returns
|
|
1053
1062
|
-------
|
|
1054
|
-
np.ndarray
|
|
1063
|
+
Iterable[np.ndarray]
|
|
1055
1064
|
The anchors.
|
|
1056
1065
|
"""
|
|
1057
1066
|
points = self.points
|
|
1058
1067
|
if len(points) == 1:
|
|
1059
1068
|
return points
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
self.get_start_anchors(),
|
|
1065
|
-
self.get_end_anchors(),
|
|
1066
|
-
)
|
|
1067
|
-
),
|
|
1068
|
-
),
|
|
1069
|
-
)
|
|
1069
|
+
|
|
1070
|
+
s = self.get_start_anchors()
|
|
1071
|
+
e = self.get_end_anchors()
|
|
1072
|
+
return list(it.chain.from_iterable(zip(s, e)))
|
|
1070
1073
|
|
|
1071
1074
|
def get_points_without_null_curves(self, atol=1e-9):
|
|
1072
1075
|
nppc = self.n_points_per_curve
|
|
@@ -1093,7 +1096,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1093
1096
|
float
|
|
1094
1097
|
The length of the :class:`OpenGLVMobject`.
|
|
1095
1098
|
"""
|
|
1096
|
-
|
|
1097
1099
|
return np.sum(
|
|
1098
1100
|
length
|
|
1099
1101
|
for _, length in self.get_curve_functions_with_lengths(
|
|
@@ -1214,8 +1216,8 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1214
1216
|
return path
|
|
1215
1217
|
|
|
1216
1218
|
for n in range(n_subpaths):
|
|
1217
|
-
sp1 = get_nth_subpath(subpaths1, n)
|
|
1218
|
-
sp2 = get_nth_subpath(subpaths2, n)
|
|
1219
|
+
sp1 = np.asarray(get_nth_subpath(subpaths1, n))
|
|
1220
|
+
sp2 = np.asarray(get_nth_subpath(subpaths2, n))
|
|
1219
1221
|
diff1 = max(0, (len(sp2) - len(sp1)) // nppc)
|
|
1220
1222
|
diff2 = max(0, (len(sp1) - len(sp2)) // nppc)
|
|
1221
1223
|
sp1 = self.insert_n_curves_to_point_list(diff1, sp1)
|
|
@@ -1269,33 +1271,12 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1269
1271
|
if len(points) == 1:
|
|
1270
1272
|
return np.repeat(points, nppc * n, 0)
|
|
1271
1273
|
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
else:
|
|
1279
|
-
ipc = np.round(n * norms / sum(norms)).astype(int)
|
|
1280
|
-
|
|
1281
|
-
diff = n - sum(ipc)
|
|
1282
|
-
for _ in range(diff):
|
|
1283
|
-
ipc[np.argmin(ipc)] += 1
|
|
1284
|
-
for _ in range(-diff):
|
|
1285
|
-
ipc[np.argmax(ipc)] -= 1
|
|
1286
|
-
|
|
1287
|
-
new_length = sum(x + 1 for x in ipc)
|
|
1288
|
-
new_points = np.empty((new_length, nppc, 3))
|
|
1289
|
-
i = 0
|
|
1290
|
-
for group, n_inserts in zip(bezier_groups, ipc):
|
|
1291
|
-
# What was once a single quadratic curve defined
|
|
1292
|
-
# by "group" will now be broken into n_inserts + 1
|
|
1293
|
-
# smaller quadratic curves
|
|
1294
|
-
alphas = np.linspace(0, 1, n_inserts + 2)
|
|
1295
|
-
for a1, a2 in zip(alphas, alphas[1:]):
|
|
1296
|
-
new_points[i] = partial_quadratic_bezier_points(group, a1, a2)
|
|
1297
|
-
i = i + 1
|
|
1298
|
-
return np.vstack(new_points)
|
|
1274
|
+
bezier_tuples = self.get_bezier_tuples_from_points(points)
|
|
1275
|
+
current_number_of_curves = len(bezier_tuples)
|
|
1276
|
+
new_number_of_curves = current_number_of_curves + n
|
|
1277
|
+
new_bezier_tuples = bezier_remap(bezier_tuples, new_number_of_curves)
|
|
1278
|
+
new_points = new_bezier_tuples.reshape(-1, 3)
|
|
1279
|
+
return new_points
|
|
1299
1280
|
|
|
1300
1281
|
def interpolate(self, mobject1, mobject2, alpha, *args, **kwargs):
|
|
1301
1282
|
super().interpolate(mobject1, mobject2, alpha, *args, **kwargs)
|
|
@@ -1348,7 +1329,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1348
1329
|
return self
|
|
1349
1330
|
if lower_index == upper_index:
|
|
1350
1331
|
self.append_points(
|
|
1351
|
-
|
|
1332
|
+
partial_bezier_points(
|
|
1352
1333
|
bezier_triplets[lower_index],
|
|
1353
1334
|
lower_residue,
|
|
1354
1335
|
upper_residue,
|
|
@@ -1356,24 +1337,18 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1356
1337
|
)
|
|
1357
1338
|
else:
|
|
1358
1339
|
self.append_points(
|
|
1359
|
-
|
|
1360
|
-
bezier_triplets[lower_index], lower_residue, 1
|
|
1361
|
-
),
|
|
1340
|
+
partial_bezier_points(bezier_triplets[lower_index], lower_residue, 1),
|
|
1362
1341
|
)
|
|
1363
1342
|
inner_points = bezier_triplets[lower_index + 1 : upper_index]
|
|
1364
1343
|
if len(inner_points) > 0:
|
|
1365
1344
|
if remap:
|
|
1366
|
-
new_triplets =
|
|
1367
|
-
inner_points, num_quadratics - 2
|
|
1368
|
-
)
|
|
1345
|
+
new_triplets = bezier_remap(inner_points, num_quadratics - 2)
|
|
1369
1346
|
else:
|
|
1370
1347
|
new_triplets = bezier_triplets
|
|
1371
1348
|
|
|
1372
1349
|
self.append_points(np.asarray(new_triplets).reshape(-1, 3))
|
|
1373
1350
|
self.append_points(
|
|
1374
|
-
|
|
1375
|
-
bezier_triplets[upper_index], 0, upper_residue
|
|
1376
|
-
),
|
|
1351
|
+
partial_bezier_points(bezier_triplets[upper_index], 0, upper_residue),
|
|
1377
1352
|
)
|
|
1378
1353
|
return self
|
|
1379
1354
|
|
|
@@ -1680,8 +1655,6 @@ class OpenGLVGroup(OpenGLVMobject):
|
|
|
1680
1655
|
"""
|
|
1681
1656
|
|
|
1682
1657
|
def __init__(self, *vmobjects, **kwargs):
|
|
1683
|
-
if not all(isinstance(m, OpenGLVMobject) for m in vmobjects):
|
|
1684
|
-
raise Exception("All submobjects must be of type OpenGLVMobject")
|
|
1685
1658
|
super().__init__(**kwargs)
|
|
1686
1659
|
self.add(*vmobjects)
|
|
1687
1660
|
|
|
@@ -1747,8 +1720,6 @@ class OpenGLVGroup(OpenGLVMobject):
|
|
|
1747
1720
|
(gr-circle_red).animate.shift(RIGHT)
|
|
1748
1721
|
)
|
|
1749
1722
|
"""
|
|
1750
|
-
if not all(isinstance(m, OpenGLVMobject) for m in vmobjects):
|
|
1751
|
-
raise TypeError("All submobjects must be of type OpenGLVMobject")
|
|
1752
1723
|
return super().add(*vmobjects)
|
|
1753
1724
|
|
|
1754
1725
|
def __add__(self, vmobject):
|
|
@@ -1794,8 +1765,7 @@ class OpenGLVGroup(OpenGLVMobject):
|
|
|
1794
1765
|
|
|
1795
1766
|
>>> config.renderer = original_renderer
|
|
1796
1767
|
"""
|
|
1797
|
-
|
|
1798
|
-
raise TypeError("All submobjects must be of type OpenGLVMobject")
|
|
1768
|
+
self._assert_valid_submobjects(tuplify(value))
|
|
1799
1769
|
self.submobjects[key] = value
|
|
1800
1770
|
|
|
1801
1771
|
|
|
@@ -1896,10 +1866,7 @@ class OpenGLDashedVMobject(OpenGLVMobject):
|
|
|
1896
1866
|
if num_dashes > 0:
|
|
1897
1867
|
# Assuming total length is 1
|
|
1898
1868
|
dash_len = r / n
|
|
1899
|
-
if vmobject.is_closed()
|
|
1900
|
-
void_len = (1 - r) / n
|
|
1901
|
-
else:
|
|
1902
|
-
void_len = (1 - r) / (n - 1)
|
|
1869
|
+
void_len = (1 - r) / n if vmobject.is_closed() else (1 - r) / (n - 1)
|
|
1903
1870
|
|
|
1904
1871
|
self.add(
|
|
1905
1872
|
*(
|
manim/mobject/svg/brace.py
CHANGED
|
@@ -4,7 +4,8 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
__all__ = ["Brace", "BraceLabel", "ArcBrace", "BraceText", "BraceBetweenPoints"]
|
|
6
6
|
|
|
7
|
-
from
|
|
7
|
+
from collections.abc import Sequence
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
8
9
|
|
|
9
10
|
import numpy as np
|
|
10
11
|
import svgelements as se
|
|
@@ -24,6 +25,12 @@ from ...mobject.types.vectorized_mobject import VMobject
|
|
|
24
25
|
from ...utils.color import BLACK
|
|
25
26
|
from ..svg.svg_mobject import VMobjectFromSVGPath
|
|
26
27
|
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from manim.typing import Point3DLike, Vector3D
|
|
30
|
+
from manim.utils.color.core import ParsableManimColor
|
|
31
|
+
|
|
32
|
+
__all__ = ["Brace", "BraceBetweenPoints", "BraceLabel", "ArcBrace"]
|
|
33
|
+
|
|
27
34
|
|
|
28
35
|
class Brace(VMobjectFromSVGPath):
|
|
29
36
|
"""Takes a mobject and draws a brace adjacent to it.
|
|
@@ -63,13 +70,13 @@ class Brace(VMobjectFromSVGPath):
|
|
|
63
70
|
def __init__(
|
|
64
71
|
self,
|
|
65
72
|
mobject: Mobject,
|
|
66
|
-
direction:
|
|
67
|
-
buff=0.2,
|
|
68
|
-
sharpness=2,
|
|
69
|
-
stroke_width=0,
|
|
70
|
-
fill_opacity=1.0,
|
|
71
|
-
background_stroke_width=0,
|
|
72
|
-
background_stroke_color=BLACK,
|
|
73
|
+
direction: Vector3D | None = DOWN,
|
|
74
|
+
buff: float = 0.2,
|
|
75
|
+
sharpness: float = 2,
|
|
76
|
+
stroke_width: float = 0,
|
|
77
|
+
fill_opacity: float = 1.0,
|
|
78
|
+
background_stroke_width: float = 0,
|
|
79
|
+
background_stroke_color: ParsableManimColor = BLACK,
|
|
73
80
|
**kwargs,
|
|
74
81
|
):
|
|
75
82
|
path_string_template = (
|
|
@@ -123,7 +130,20 @@ class Brace(VMobjectFromSVGPath):
|
|
|
123
130
|
for mob in mobject, self:
|
|
124
131
|
mob.rotate(angle, about_point=ORIGIN)
|
|
125
132
|
|
|
126
|
-
def put_at_tip(self, mob, use_next_to=True, **kwargs):
|
|
133
|
+
def put_at_tip(self, mob: Mobject, use_next_to: bool = True, **kwargs):
|
|
134
|
+
"""Puts the given mobject at the brace tip.
|
|
135
|
+
|
|
136
|
+
Parameters
|
|
137
|
+
----------
|
|
138
|
+
mob
|
|
139
|
+
The mobject to be placed at the tip.
|
|
140
|
+
use_next_to
|
|
141
|
+
If true, then :meth:`next_to` is used to place the mobject at the
|
|
142
|
+
tip.
|
|
143
|
+
kwargs
|
|
144
|
+
Any additional keyword arguments are passed to :meth:`next_to` which
|
|
145
|
+
is used to put the mobject next to the brace tip.
|
|
146
|
+
"""
|
|
127
147
|
if use_next_to:
|
|
128
148
|
mob.next_to(self.get_tip(), np.round(self.get_direction()), **kwargs)
|
|
129
149
|
else:
|
|
@@ -134,16 +154,45 @@ class Brace(VMobjectFromSVGPath):
|
|
|
134
154
|
return self
|
|
135
155
|
|
|
136
156
|
def get_text(self, *text, **kwargs):
|
|
157
|
+
"""Places the text at the brace tip.
|
|
158
|
+
|
|
159
|
+
Parameters
|
|
160
|
+
----------
|
|
161
|
+
text
|
|
162
|
+
The text to be placed at the brace tip.
|
|
163
|
+
kwargs
|
|
164
|
+
Any additional keyword arguments are passed to :meth:`.put_at_tip` which
|
|
165
|
+
is used to position the text at the brace tip.
|
|
166
|
+
|
|
167
|
+
Returns
|
|
168
|
+
-------
|
|
169
|
+
:class:`~.Tex`
|
|
170
|
+
"""
|
|
137
171
|
text_mob = Tex(*text)
|
|
138
172
|
self.put_at_tip(text_mob, **kwargs)
|
|
139
173
|
return text_mob
|
|
140
174
|
|
|
141
175
|
def get_tex(self, *tex, **kwargs):
|
|
176
|
+
"""Places the tex at the brace tip.
|
|
177
|
+
|
|
178
|
+
Parameters
|
|
179
|
+
----------
|
|
180
|
+
tex
|
|
181
|
+
The tex to be placed at the brace tip.
|
|
182
|
+
kwargs
|
|
183
|
+
Any further keyword arguments are passed to :meth:`.put_at_tip` which
|
|
184
|
+
is used to position the tex at the brace tip.
|
|
185
|
+
|
|
186
|
+
Returns
|
|
187
|
+
-------
|
|
188
|
+
:class:`~.MathTex`
|
|
189
|
+
"""
|
|
142
190
|
tex_mob = MathTex(*tex)
|
|
143
191
|
self.put_at_tip(tex_mob, **kwargs)
|
|
144
192
|
return tex_mob
|
|
145
193
|
|
|
146
194
|
def get_tip(self):
|
|
195
|
+
"""Returns the point at the brace tip."""
|
|
147
196
|
# Returns the position of the seventh point in the path, which is the tip.
|
|
148
197
|
if config["renderer"] == "opengl":
|
|
149
198
|
return self.points[34]
|
|
@@ -151,6 +200,7 @@ class Brace(VMobjectFromSVGPath):
|
|
|
151
200
|
return self.points[28] # = 7*4
|
|
152
201
|
|
|
153
202
|
def get_direction(self):
|
|
203
|
+
"""Returns the direction from the center to the brace tip."""
|
|
154
204
|
vect = self.get_tip() - self.get_center()
|
|
155
205
|
return vect / np.linalg.norm(vect)
|
|
156
206
|
|
|
@@ -199,7 +249,7 @@ class BraceLabel(VMobject, metaclass=ConvertToOpenGL):
|
|
|
199
249
|
self.brace = Brace(obj, brace_direction, buff, **brace_config)
|
|
200
250
|
|
|
201
251
|
if isinstance(text, (tuple, list)):
|
|
202
|
-
self.label = self.label_constructor(font_size=font_size,
|
|
252
|
+
self.label = self.label_constructor(*text, font_size=font_size, **kwargs)
|
|
203
253
|
else:
|
|
204
254
|
self.label = self.label_constructor(str(text), font_size=font_size)
|
|
205
255
|
|
|
@@ -267,9 +317,9 @@ class BraceBetweenPoints(Brace):
|
|
|
267
317
|
|
|
268
318
|
def __init__(
|
|
269
319
|
self,
|
|
270
|
-
point_1:
|
|
271
|
-
point_2:
|
|
272
|
-
direction:
|
|
320
|
+
point_1: Point3DLike | None,
|
|
321
|
+
point_2: Point3DLike | None,
|
|
322
|
+
direction: Vector3D | None = ORIGIN,
|
|
273
323
|
**kwargs,
|
|
274
324
|
):
|
|
275
325
|
if all(direction == ORIGIN):
|
manim/mobject/svg/svg_mobject.py
CHANGED
|
@@ -264,7 +264,8 @@ class SVGMobject(VMobject, metaclass=ConvertToOpenGL):
|
|
|
264
264
|
"""
|
|
265
265
|
result = []
|
|
266
266
|
for shape in svg.elements():
|
|
267
|
-
|
|
267
|
+
# can we combine the two continue cases into one?
|
|
268
|
+
if isinstance(shape, se.Group): # noqa: SIM114
|
|
268
269
|
continue
|
|
269
270
|
elif isinstance(shape, se.Path):
|
|
270
271
|
mob = self.path_to_mobject(shape)
|
|
@@ -441,9 +442,9 @@ class SVGMobject(VMobject, metaclass=ConvertToOpenGL):
|
|
|
441
442
|
if self.should_center:
|
|
442
443
|
self.center()
|
|
443
444
|
if self.svg_height is not None:
|
|
444
|
-
self.
|
|
445
|
+
self.set(height=self.svg_height)
|
|
445
446
|
if self.svg_width is not None:
|
|
446
|
-
self.
|
|
447
|
+
self.set(width=self.svg_width)
|
|
447
448
|
|
|
448
449
|
|
|
449
450
|
class VMobjectFromSVGPath(VMobject, metaclass=ConvertToOpenGL):
|
manim/mobject/table.py
CHANGED
|
@@ -65,7 +65,8 @@ __all__ = [
|
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
import itertools as it
|
|
68
|
-
from
|
|
68
|
+
from collections.abc import Iterable, Sequence
|
|
69
|
+
from typing import Callable
|
|
69
70
|
|
|
70
71
|
from manim.mobject.geometry.line import Line
|
|
71
72
|
from manim.mobject.geometry.polygram import Polygon
|
|
@@ -74,7 +75,6 @@ from manim.mobject.text.numbers import DecimalNumber, Integer
|
|
|
74
75
|
from manim.mobject.text.tex_mobject import MathTex
|
|
75
76
|
from manim.mobject.text.text_mobject import Paragraph
|
|
76
77
|
|
|
77
|
-
from .. import config
|
|
78
78
|
from ..animation.animation import Animation
|
|
79
79
|
from ..animation.composition import AnimationGroup
|
|
80
80
|
from ..animation.creation import Create, Write
|
|
@@ -85,7 +85,7 @@ from .utils import get_vectorized_mobject_class
|
|
|
85
85
|
|
|
86
86
|
|
|
87
87
|
class Table(VGroup):
|
|
88
|
-
"""A mobject that displays a table on the screen.
|
|
88
|
+
r"""A mobject that displays a table on the screen.
|
|
89
89
|
|
|
90
90
|
Parameters
|
|
91
91
|
----------
|
|
@@ -683,7 +683,6 @@ class Table(VGroup):
|
|
|
683
683
|
item.set_color(random_bright_color())
|
|
684
684
|
self.add(table)
|
|
685
685
|
"""
|
|
686
|
-
|
|
687
686
|
return VGroup(*self.row_labels)
|
|
688
687
|
|
|
689
688
|
def get_col_labels(self) -> VGroup:
|
|
@@ -712,7 +711,6 @@ class Table(VGroup):
|
|
|
712
711
|
item.set_color(random_bright_color())
|
|
713
712
|
self.add(table)
|
|
714
713
|
"""
|
|
715
|
-
|
|
716
714
|
return VGroup(*self.col_labels)
|
|
717
715
|
|
|
718
716
|
def get_labels(self) -> VGroup:
|
|
@@ -1067,7 +1065,7 @@ class MobjectTable(Table):
|
|
|
1067
1065
|
|
|
1068
1066
|
|
|
1069
1067
|
class IntegerTable(Table):
|
|
1070
|
-
"""A specialized :class:`~.Table` mobject for use with :class:`~.Integer`.
|
|
1068
|
+
r"""A specialized :class:`~.Table` mobject for use with :class:`~.Integer`.
|
|
1071
1069
|
|
|
1072
1070
|
Examples
|
|
1073
1071
|
--------
|
|
@@ -1081,14 +1079,14 @@ class IntegerTable(Table):
|
|
|
1081
1079
|
[[0,30,45,60,90],
|
|
1082
1080
|
[90,60,45,30,0]],
|
|
1083
1081
|
col_labels=[
|
|
1084
|
-
MathTex("
|
|
1085
|
-
MathTex("
|
|
1086
|
-
MathTex("
|
|
1087
|
-
MathTex("
|
|
1088
|
-
MathTex("
|
|
1089
|
-
row_labels=[MathTex("
|
|
1082
|
+
MathTex(r"\frac{\sqrt{0}}{2}"),
|
|
1083
|
+
MathTex(r"\frac{\sqrt{1}}{2}"),
|
|
1084
|
+
MathTex(r"\frac{\sqrt{2}}{2}"),
|
|
1085
|
+
MathTex(r"\frac{\sqrt{3}}{2}"),
|
|
1086
|
+
MathTex(r"\frac{\sqrt{4}}{2}")],
|
|
1087
|
+
row_labels=[MathTex(r"\sin"), MathTex(r"\cos")],
|
|
1090
1088
|
h_buff=1,
|
|
1091
|
-
element_to_mobject_config={"unit": "^{
|
|
1089
|
+
element_to_mobject_config={"unit": r"^{\circ}"})
|
|
1092
1090
|
self.add(t0)
|
|
1093
1091
|
"""
|
|
1094
1092
|
|