manim 0.18.1__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/__main__.py +45 -12
- manim/_config/__init__.py +2 -2
- manim/_config/cli_colors.py +8 -4
- manim/_config/default.cfg +0 -2
- manim/_config/logger_utils.py +5 -0
- manim/_config/utils.py +29 -38
- manim/animation/animation.py +148 -8
- manim/animation/composition.py +16 -13
- manim/animation/creation.py +184 -8
- manim/animation/fading.py +5 -8
- manim/animation/indication.py +93 -26
- manim/animation/movement.py +21 -3
- manim/animation/rotation.py +2 -1
- manim/animation/specialized.py +3 -5
- manim/animation/speedmodifier.py +3 -3
- manim/animation/transform.py +4 -5
- manim/animation/updaters/mobject_update_utils.py +17 -14
- manim/camera/camera.py +2 -2
- manim/cli/__init__.py +17 -0
- manim/cli/cfg/group.py +52 -36
- manim/cli/checkhealth/checks.py +92 -76
- manim/cli/checkhealth/commands.py +12 -5
- manim/cli/default_group.py +148 -24
- manim/cli/init/commands.py +28 -23
- manim/cli/plugins/commands.py +13 -3
- manim/cli/render/commands.py +47 -42
- manim/cli/render/global_options.py +43 -9
- manim/cli/render/render_options.py +84 -19
- manim/constants.py +11 -4
- manim/mobject/frame.py +0 -1
- manim/mobject/geometry/arc.py +109 -75
- manim/mobject/geometry/boolean_ops.py +20 -17
- manim/mobject/geometry/labeled.py +300 -77
- manim/mobject/geometry/line.py +120 -60
- manim/mobject/geometry/polygram.py +109 -25
- manim/mobject/geometry/shape_matchers.py +35 -15
- manim/mobject/geometry/tips.py +36 -27
- manim/mobject/graph.py +48 -40
- manim/mobject/graphing/coordinate_systems.py +110 -45
- manim/mobject/graphing/functions.py +16 -10
- manim/mobject/graphing/number_line.py +23 -9
- manim/mobject/graphing/probability.py +2 -10
- manim/mobject/graphing/scale.py +6 -5
- manim/mobject/matrix.py +17 -19
- manim/mobject/mobject.py +149 -103
- manim/mobject/opengl/opengl_geometry.py +4 -8
- manim/mobject/opengl/opengl_mobject.py +506 -343
- manim/mobject/opengl/opengl_point_cloud_mobject.py +3 -7
- manim/mobject/opengl/opengl_surface.py +1 -2
- manim/mobject/opengl/opengl_vectorized_mobject.py +27 -65
- manim/mobject/svg/brace.py +61 -13
- manim/mobject/svg/svg_mobject.py +2 -1
- manim/mobject/table.py +11 -12
- manim/mobject/text/code_mobject.py +186 -550
- manim/mobject/text/numbers.py +7 -7
- manim/mobject/text/tex_mobject.py +22 -13
- manim/mobject/text/text_mobject.py +29 -20
- manim/mobject/three_d/polyhedra.py +98 -1
- manim/mobject/three_d/three_dimensions.py +59 -31
- manim/mobject/types/image_mobject.py +37 -23
- manim/mobject/types/point_cloud_mobject.py +103 -67
- manim/mobject/types/vectorized_mobject.py +387 -214
- manim/mobject/value_tracker.py +2 -1
- manim/mobject/vector_field.py +2 -4
- manim/opengl/__init__.py +3 -3
- manim/plugins/__init__.py +2 -3
- manim/plugins/plugins_flags.py +3 -3
- manim/renderer/cairo_renderer.py +11 -11
- manim/renderer/opengl_renderer.py +19 -20
- manim/renderer/shader.py +2 -3
- manim/renderer/shader_wrapper.py +3 -2
- manim/scene/moving_camera_scene.py +23 -0
- manim/scene/scene.py +72 -41
- manim/scene/scene_file_writer.py +313 -164
- manim/scene/section.py +15 -15
- manim/scene/three_d_scene.py +8 -15
- manim/scene/vector_space_scene.py +3 -6
- manim/typing.py +326 -66
- manim/utils/bezier.py +1658 -381
- manim/utils/caching.py +11 -5
- manim/utils/color/AS2700.py +2 -0
- manim/utils/color/BS381.py +2 -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 +2 -0
- manim/utils/color/__init__.py +8 -5
- manim/utils/color/core.py +818 -301
- manim/utils/color/manim_colors.py +7 -9
- manim/utils/commands.py +40 -19
- manim/utils/config_ops.py +18 -13
- manim/utils/debug.py +8 -6
- manim/utils/deprecation.py +92 -43
- manim/utils/docbuild/autoaliasattr_directive.py +45 -8
- manim/utils/docbuild/autocolor_directive.py +12 -13
- manim/utils/docbuild/manim_directive.py +35 -29
- manim/utils/docbuild/module_parsing.py +74 -27
- manim/utils/family.py +3 -3
- manim/utils/family_ops.py +12 -4
- manim/utils/file_ops.py +22 -16
- manim/utils/hashing.py +7 -7
- manim/utils/images.py +10 -4
- manim/utils/ipython_magic.py +12 -8
- manim/utils/iterables.py +161 -119
- manim/utils/module_ops.py +55 -19
- manim/utils/opengl.py +68 -23
- manim/utils/parameter_parsing.py +3 -2
- manim/utils/paths.py +11 -5
- manim/utils/polylabel.py +168 -0
- manim/utils/qhull.py +218 -0
- manim/utils/rate_functions.py +69 -32
- manim/utils/simple_functions.py +24 -15
- manim/utils/sounds.py +7 -1
- manim/utils/space_ops.py +48 -37
- 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 +20 -14
- manim/utils/tex.py +4 -2
- manim/utils/tex_file_writing.py +45 -45
- manim/utils/tex_templates.py +1 -1
- manim/utils/unit.py +6 -5
- {manim-0.18.1.dist-info → manim-0.19.0.dist-info}/METADATA +16 -9
- manim-0.19.0.dist-info/RECORD +221 -0
- {manim-0.18.1.dist-info → manim-0.19.0.dist-info}/WHEEL +1 -1
- manim-0.18.1.dist-info/RECORD +0 -217
- {manim-0.18.1.dist-info → manim-0.19.0.dist-info}/LICENSE +0 -0
- {manim-0.18.1.dist-info → manim-0.19.0.dist-info}/LICENSE.community +0 -0
- {manim-0.18.1.dist-info → manim-0.19.0.dist-info}/entry_points.txt +0 -0
|
@@ -65,13 +65,11 @@ class OpenGLPMobject(OpenGLMobject):
|
|
|
65
65
|
return self
|
|
66
66
|
|
|
67
67
|
def thin_out(self, factor=5):
|
|
68
|
-
"""
|
|
69
|
-
Removes all but every nth point for n = factor
|
|
70
|
-
"""
|
|
68
|
+
"""Removes all but every nth point for n = factor"""
|
|
71
69
|
for mob in self.family_members_with_points():
|
|
72
70
|
num_points = mob.get_num_points()
|
|
73
71
|
|
|
74
|
-
def thin_func():
|
|
72
|
+
def thin_func(num_points=num_points):
|
|
75
73
|
return np.arange(0, num_points, factor)
|
|
76
74
|
|
|
77
75
|
if len(mob.points) == len(mob.rgbas):
|
|
@@ -126,9 +124,7 @@ class OpenGLPMobject(OpenGLMobject):
|
|
|
126
124
|
return self
|
|
127
125
|
|
|
128
126
|
def sort_points(self, function=lambda p: p[0]):
|
|
129
|
-
"""
|
|
130
|
-
function is any map from R^3 to R
|
|
131
|
-
"""
|
|
127
|
+
"""function is any map from R^3 to R"""
|
|
132
128
|
for mob in self.family_members_with_points():
|
|
133
129
|
indices = np.argsort(np.apply_along_axis(function, 1, mob.points))
|
|
134
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,7 +12,6 @@ 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
|
|
@@ -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,
|
|
@@ -160,6 +161,9 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
160
161
|
if stroke_color is not None:
|
|
161
162
|
self.stroke_color = ManimColor.parse(stroke_color)
|
|
162
163
|
|
|
164
|
+
def _assert_valid_submobjects(self, submobjects: Iterable[OpenGLVMobject]) -> Self:
|
|
165
|
+
return self._assert_valid_submobjects_internal(submobjects, OpenGLVMobject)
|
|
166
|
+
|
|
163
167
|
def get_group_class(self):
|
|
164
168
|
return OpenGLVGroup
|
|
165
169
|
|
|
@@ -265,7 +269,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
265
269
|
|
|
266
270
|
if width is not None:
|
|
267
271
|
for mob in self.get_family(recurse):
|
|
268
|
-
mob.stroke_width = np.array([[width] for width in
|
|
272
|
+
mob.stroke_width = np.array([[width] for width in tuplify(width)])
|
|
269
273
|
|
|
270
274
|
if background is not None:
|
|
271
275
|
for mob in self.get_family(recurse):
|
|
@@ -320,6 +324,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
320
324
|
vmobject_style = vmobject.get_style()
|
|
321
325
|
if config.renderer == RendererType.OPENGL:
|
|
322
326
|
vmobject_style["stroke_width"] = vmobject_style["stroke_width"][0][0]
|
|
327
|
+
vmobject_style["fill_opacity"] = self.get_fill_opacity()
|
|
323
328
|
self.set_style(**vmobject_style, recurse=False)
|
|
324
329
|
if recurse:
|
|
325
330
|
# Does its best to match up submobject lists, and
|
|
@@ -401,7 +406,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
401
406
|
return self.get_stroke_opacities()[0]
|
|
402
407
|
|
|
403
408
|
def get_color(self):
|
|
404
|
-
if self.
|
|
409
|
+
if not self.has_fill():
|
|
405
410
|
return self.get_stroke_color()
|
|
406
411
|
return self.get_fill_color()
|
|
407
412
|
|
|
@@ -467,9 +472,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
467
472
|
self.append_points(new_points)
|
|
468
473
|
|
|
469
474
|
def add_cubic_bezier_curve_to(self, handle1, handle2, anchor):
|
|
470
|
-
"""
|
|
471
|
-
Add cubic bezier curve to the path.
|
|
472
|
-
"""
|
|
475
|
+
"""Add cubic bezier curve to the path."""
|
|
473
476
|
self.throw_error_if_no_points()
|
|
474
477
|
quadratic_approx = get_quadratic_approximation_of_cubic(
|
|
475
478
|
self.get_last_point(),
|
|
@@ -554,7 +557,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
554
557
|
alphas = np.linspace(0, 1, n + 1)
|
|
555
558
|
new_points.extend(
|
|
556
559
|
[
|
|
557
|
-
|
|
560
|
+
partial_bezier_points(tup, a1, a2)
|
|
558
561
|
for a1, a2 in zip(alphas, alphas[1:])
|
|
559
562
|
],
|
|
560
563
|
)
|
|
@@ -812,7 +815,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
812
815
|
length : :class:`float`
|
|
813
816
|
The length of the nth curve.
|
|
814
817
|
"""
|
|
815
|
-
|
|
816
818
|
if sample_points is None:
|
|
817
819
|
sample_points = 10
|
|
818
820
|
|
|
@@ -852,7 +854,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
852
854
|
length : :class:`float`
|
|
853
855
|
The length of the nth curve.
|
|
854
856
|
"""
|
|
855
|
-
|
|
856
857
|
_, length = self.get_nth_curve_function_with_length(n, sample_points)
|
|
857
858
|
|
|
858
859
|
return length
|
|
@@ -867,7 +868,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
867
868
|
Iterable[Callable[[float], np.ndarray]]
|
|
868
869
|
The functions for the curves.
|
|
869
870
|
"""
|
|
870
|
-
|
|
871
871
|
num_curves = self.get_num_curves()
|
|
872
872
|
|
|
873
873
|
for n in range(num_curves):
|
|
@@ -917,7 +917,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
917
917
|
Iterable[Tuple[Callable[[float], np.ndarray], float]]
|
|
918
918
|
The functions and lengths of the curves.
|
|
919
919
|
"""
|
|
920
|
-
|
|
921
920
|
num_curves = self.get_num_curves()
|
|
922
921
|
|
|
923
922
|
for n in range(num_curves):
|
|
@@ -943,7 +942,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
943
942
|
:exc:`Exception`
|
|
944
943
|
If the :class:`OpenGLVMobject` has no points.
|
|
945
944
|
"""
|
|
946
|
-
|
|
947
945
|
if alpha < 0 or alpha > 1:
|
|
948
946
|
raise ValueError(f"Alpha {alpha} not between 0 and 1.")
|
|
949
947
|
|
|
@@ -1098,7 +1096,6 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1098
1096
|
float
|
|
1099
1097
|
The length of the :class:`OpenGLVMobject`.
|
|
1100
1098
|
"""
|
|
1101
|
-
|
|
1102
1099
|
return np.sum(
|
|
1103
1100
|
length
|
|
1104
1101
|
for _, length in self.get_curve_functions_with_lengths(
|
|
@@ -1219,8 +1216,8 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1219
1216
|
return path
|
|
1220
1217
|
|
|
1221
1218
|
for n in range(n_subpaths):
|
|
1222
|
-
sp1 = get_nth_subpath(subpaths1, n)
|
|
1223
|
-
sp2 = get_nth_subpath(subpaths2, n)
|
|
1219
|
+
sp1 = np.asarray(get_nth_subpath(subpaths1, n))
|
|
1220
|
+
sp2 = np.asarray(get_nth_subpath(subpaths2, n))
|
|
1224
1221
|
diff1 = max(0, (len(sp2) - len(sp1)) // nppc)
|
|
1225
1222
|
diff2 = max(0, (len(sp1) - len(sp2)) // nppc)
|
|
1226
1223
|
sp1 = self.insert_n_curves_to_point_list(diff1, sp1)
|
|
@@ -1274,33 +1271,12 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1274
1271
|
if len(points) == 1:
|
|
1275
1272
|
return np.repeat(points, nppc * n, 0)
|
|
1276
1273
|
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
else:
|
|
1284
|
-
ipc = np.round(n * norms / sum(norms)).astype(int)
|
|
1285
|
-
|
|
1286
|
-
diff = n - sum(ipc)
|
|
1287
|
-
for _ in range(diff):
|
|
1288
|
-
ipc[np.argmin(ipc)] += 1
|
|
1289
|
-
for _ in range(-diff):
|
|
1290
|
-
ipc[np.argmax(ipc)] -= 1
|
|
1291
|
-
|
|
1292
|
-
new_length = sum(x + 1 for x in ipc)
|
|
1293
|
-
new_points = np.empty((new_length, nppc, 3))
|
|
1294
|
-
i = 0
|
|
1295
|
-
for group, n_inserts in zip(bezier_groups, ipc):
|
|
1296
|
-
# What was once a single quadratic curve defined
|
|
1297
|
-
# by "group" will now be broken into n_inserts + 1
|
|
1298
|
-
# smaller quadratic curves
|
|
1299
|
-
alphas = np.linspace(0, 1, n_inserts + 2)
|
|
1300
|
-
for a1, a2 in zip(alphas, alphas[1:]):
|
|
1301
|
-
new_points[i] = partial_quadratic_bezier_points(group, a1, a2)
|
|
1302
|
-
i = i + 1
|
|
1303
|
-
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
|
|
1304
1280
|
|
|
1305
1281
|
def interpolate(self, mobject1, mobject2, alpha, *args, **kwargs):
|
|
1306
1282
|
super().interpolate(mobject1, mobject2, alpha, *args, **kwargs)
|
|
@@ -1353,7 +1329,7 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1353
1329
|
return self
|
|
1354
1330
|
if lower_index == upper_index:
|
|
1355
1331
|
self.append_points(
|
|
1356
|
-
|
|
1332
|
+
partial_bezier_points(
|
|
1357
1333
|
bezier_triplets[lower_index],
|
|
1358
1334
|
lower_residue,
|
|
1359
1335
|
upper_residue,
|
|
@@ -1361,24 +1337,18 @@ class OpenGLVMobject(OpenGLMobject):
|
|
|
1361
1337
|
)
|
|
1362
1338
|
else:
|
|
1363
1339
|
self.append_points(
|
|
1364
|
-
|
|
1365
|
-
bezier_triplets[lower_index], lower_residue, 1
|
|
1366
|
-
),
|
|
1340
|
+
partial_bezier_points(bezier_triplets[lower_index], lower_residue, 1),
|
|
1367
1341
|
)
|
|
1368
1342
|
inner_points = bezier_triplets[lower_index + 1 : upper_index]
|
|
1369
1343
|
if len(inner_points) > 0:
|
|
1370
1344
|
if remap:
|
|
1371
|
-
new_triplets =
|
|
1372
|
-
inner_points, num_quadratics - 2
|
|
1373
|
-
)
|
|
1345
|
+
new_triplets = bezier_remap(inner_points, num_quadratics - 2)
|
|
1374
1346
|
else:
|
|
1375
1347
|
new_triplets = bezier_triplets
|
|
1376
1348
|
|
|
1377
1349
|
self.append_points(np.asarray(new_triplets).reshape(-1, 3))
|
|
1378
1350
|
self.append_points(
|
|
1379
|
-
|
|
1380
|
-
bezier_triplets[upper_index], 0, upper_residue
|
|
1381
|
-
),
|
|
1351
|
+
partial_bezier_points(bezier_triplets[upper_index], 0, upper_residue),
|
|
1382
1352
|
)
|
|
1383
1353
|
return self
|
|
1384
1354
|
|
|
@@ -1685,8 +1655,6 @@ class OpenGLVGroup(OpenGLVMobject):
|
|
|
1685
1655
|
"""
|
|
1686
1656
|
|
|
1687
1657
|
def __init__(self, *vmobjects, **kwargs):
|
|
1688
|
-
if not all(isinstance(m, OpenGLVMobject) for m in vmobjects):
|
|
1689
|
-
raise Exception("All submobjects must be of type OpenGLVMobject")
|
|
1690
1658
|
super().__init__(**kwargs)
|
|
1691
1659
|
self.add(*vmobjects)
|
|
1692
1660
|
|
|
@@ -1752,8 +1720,6 @@ class OpenGLVGroup(OpenGLVMobject):
|
|
|
1752
1720
|
(gr-circle_red).animate.shift(RIGHT)
|
|
1753
1721
|
)
|
|
1754
1722
|
"""
|
|
1755
|
-
if not all(isinstance(m, OpenGLVMobject) for m in vmobjects):
|
|
1756
|
-
raise TypeError("All submobjects must be of type OpenGLVMobject")
|
|
1757
1723
|
return super().add(*vmobjects)
|
|
1758
1724
|
|
|
1759
1725
|
def __add__(self, vmobject):
|
|
@@ -1799,8 +1765,7 @@ class OpenGLVGroup(OpenGLVMobject):
|
|
|
1799
1765
|
|
|
1800
1766
|
>>> config.renderer = original_renderer
|
|
1801
1767
|
"""
|
|
1802
|
-
|
|
1803
|
-
raise TypeError("All submobjects must be of type OpenGLVMobject")
|
|
1768
|
+
self._assert_valid_submobjects(tuplify(value))
|
|
1804
1769
|
self.submobjects[key] = value
|
|
1805
1770
|
|
|
1806
1771
|
|
|
@@ -1901,10 +1866,7 @@ class OpenGLDashedVMobject(OpenGLVMobject):
|
|
|
1901
1866
|
if num_dashes > 0:
|
|
1902
1867
|
# Assuming total length is 1
|
|
1903
1868
|
dash_len = r / n
|
|
1904
|
-
if vmobject.is_closed()
|
|
1905
|
-
void_len = (1 - r) / n
|
|
1906
|
-
else:
|
|
1907
|
-
void_len = (1 - r) / (n - 1)
|
|
1869
|
+
void_len = (1 - r) / n if vmobject.is_closed() else (1 - r) / (n - 1)
|
|
1908
1870
|
|
|
1909
1871
|
self.add(
|
|
1910
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,10 @@ 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
|
+
|
|
27
32
|
__all__ = ["Brace", "BraceBetweenPoints", "BraceLabel", "ArcBrace"]
|
|
28
33
|
|
|
29
34
|
|
|
@@ -65,13 +70,13 @@ class Brace(VMobjectFromSVGPath):
|
|
|
65
70
|
def __init__(
|
|
66
71
|
self,
|
|
67
72
|
mobject: Mobject,
|
|
68
|
-
direction:
|
|
69
|
-
buff=0.2,
|
|
70
|
-
sharpness=2,
|
|
71
|
-
stroke_width=0,
|
|
72
|
-
fill_opacity=1.0,
|
|
73
|
-
background_stroke_width=0,
|
|
74
|
-
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,
|
|
75
80
|
**kwargs,
|
|
76
81
|
):
|
|
77
82
|
path_string_template = (
|
|
@@ -125,7 +130,20 @@ class Brace(VMobjectFromSVGPath):
|
|
|
125
130
|
for mob in mobject, self:
|
|
126
131
|
mob.rotate(angle, about_point=ORIGIN)
|
|
127
132
|
|
|
128
|
-
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
|
+
"""
|
|
129
147
|
if use_next_to:
|
|
130
148
|
mob.next_to(self.get_tip(), np.round(self.get_direction()), **kwargs)
|
|
131
149
|
else:
|
|
@@ -136,16 +154,45 @@ class Brace(VMobjectFromSVGPath):
|
|
|
136
154
|
return self
|
|
137
155
|
|
|
138
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
|
+
"""
|
|
139
171
|
text_mob = Tex(*text)
|
|
140
172
|
self.put_at_tip(text_mob, **kwargs)
|
|
141
173
|
return text_mob
|
|
142
174
|
|
|
143
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
|
+
"""
|
|
144
190
|
tex_mob = MathTex(*tex)
|
|
145
191
|
self.put_at_tip(tex_mob, **kwargs)
|
|
146
192
|
return tex_mob
|
|
147
193
|
|
|
148
194
|
def get_tip(self):
|
|
195
|
+
"""Returns the point at the brace tip."""
|
|
149
196
|
# Returns the position of the seventh point in the path, which is the tip.
|
|
150
197
|
if config["renderer"] == "opengl":
|
|
151
198
|
return self.points[34]
|
|
@@ -153,6 +200,7 @@ class Brace(VMobjectFromSVGPath):
|
|
|
153
200
|
return self.points[28] # = 7*4
|
|
154
201
|
|
|
155
202
|
def get_direction(self):
|
|
203
|
+
"""Returns the direction from the center to the brace tip."""
|
|
156
204
|
vect = self.get_tip() - self.get_center()
|
|
157
205
|
return vect / np.linalg.norm(vect)
|
|
158
206
|
|
|
@@ -201,7 +249,7 @@ class BraceLabel(VMobject, metaclass=ConvertToOpenGL):
|
|
|
201
249
|
self.brace = Brace(obj, brace_direction, buff, **brace_config)
|
|
202
250
|
|
|
203
251
|
if isinstance(text, (tuple, list)):
|
|
204
|
-
self.label = self.label_constructor(font_size=font_size,
|
|
252
|
+
self.label = self.label_constructor(*text, font_size=font_size, **kwargs)
|
|
205
253
|
else:
|
|
206
254
|
self.label = self.label_constructor(str(text), font_size=font_size)
|
|
207
255
|
|
|
@@ -269,9 +317,9 @@ class BraceBetweenPoints(Brace):
|
|
|
269
317
|
|
|
270
318
|
def __init__(
|
|
271
319
|
self,
|
|
272
|
-
point_1:
|
|
273
|
-
point_2:
|
|
274
|
-
direction:
|
|
320
|
+
point_1: Point3DLike | None,
|
|
321
|
+
point_2: Point3DLike | None,
|
|
322
|
+
direction: Vector3D | None = ORIGIN,
|
|
275
323
|
**kwargs,
|
|
276
324
|
):
|
|
277
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)
|
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
|
|
@@ -84,7 +85,7 @@ from .utils import get_vectorized_mobject_class
|
|
|
84
85
|
|
|
85
86
|
|
|
86
87
|
class Table(VGroup):
|
|
87
|
-
"""A mobject that displays a table on the screen.
|
|
88
|
+
r"""A mobject that displays a table on the screen.
|
|
88
89
|
|
|
89
90
|
Parameters
|
|
90
91
|
----------
|
|
@@ -682,7 +683,6 @@ class Table(VGroup):
|
|
|
682
683
|
item.set_color(random_bright_color())
|
|
683
684
|
self.add(table)
|
|
684
685
|
"""
|
|
685
|
-
|
|
686
686
|
return VGroup(*self.row_labels)
|
|
687
687
|
|
|
688
688
|
def get_col_labels(self) -> VGroup:
|
|
@@ -711,7 +711,6 @@ class Table(VGroup):
|
|
|
711
711
|
item.set_color(random_bright_color())
|
|
712
712
|
self.add(table)
|
|
713
713
|
"""
|
|
714
|
-
|
|
715
714
|
return VGroup(*self.col_labels)
|
|
716
715
|
|
|
717
716
|
def get_labels(self) -> VGroup:
|
|
@@ -1066,7 +1065,7 @@ class MobjectTable(Table):
|
|
|
1066
1065
|
|
|
1067
1066
|
|
|
1068
1067
|
class IntegerTable(Table):
|
|
1069
|
-
"""A specialized :class:`~.Table` mobject for use with :class:`~.Integer`.
|
|
1068
|
+
r"""A specialized :class:`~.Table` mobject for use with :class:`~.Integer`.
|
|
1070
1069
|
|
|
1071
1070
|
Examples
|
|
1072
1071
|
--------
|
|
@@ -1080,14 +1079,14 @@ class IntegerTable(Table):
|
|
|
1080
1079
|
[[0,30,45,60,90],
|
|
1081
1080
|
[90,60,45,30,0]],
|
|
1082
1081
|
col_labels=[
|
|
1083
|
-
MathTex("
|
|
1084
|
-
MathTex("
|
|
1085
|
-
MathTex("
|
|
1086
|
-
MathTex("
|
|
1087
|
-
MathTex("
|
|
1088
|
-
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")],
|
|
1089
1088
|
h_buff=1,
|
|
1090
|
-
element_to_mobject_config={"unit": "^{
|
|
1089
|
+
element_to_mobject_config={"unit": r"^{\circ}"})
|
|
1091
1090
|
self.add(t0)
|
|
1092
1091
|
"""
|
|
1093
1092
|
|