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.

Files changed (146) hide show
  1. manim/__init__.py +3 -6
  2. manim/__main__.py +61 -20
  3. manim/_config/__init__.py +6 -3
  4. manim/_config/cli_colors.py +16 -8
  5. manim/_config/default.cfg +1 -3
  6. manim/_config/logger_utils.py +14 -8
  7. manim/_config/utils.py +651 -472
  8. manim/animation/animation.py +152 -5
  9. manim/animation/composition.py +80 -39
  10. manim/animation/creation.py +196 -14
  11. manim/animation/fading.py +5 -9
  12. manim/animation/indication.py +103 -47
  13. manim/animation/movement.py +22 -5
  14. manim/animation/rotation.py +3 -2
  15. manim/animation/specialized.py +4 -6
  16. manim/animation/speedmodifier.py +10 -5
  17. manim/animation/transform.py +4 -5
  18. manim/animation/transform_matching_parts.py +1 -1
  19. manim/animation/updaters/mobject_update_utils.py +17 -14
  20. manim/camera/camera.py +15 -6
  21. manim/cli/__init__.py +17 -0
  22. manim/cli/cfg/group.py +70 -44
  23. manim/cli/checkhealth/checks.py +93 -75
  24. manim/cli/checkhealth/commands.py +14 -5
  25. manim/cli/default_group.py +157 -25
  26. manim/cli/init/commands.py +32 -24
  27. manim/cli/plugins/commands.py +16 -3
  28. manim/cli/render/commands.py +72 -60
  29. manim/cli/render/ease_of_access_options.py +4 -3
  30. manim/cli/render/global_options.py +51 -15
  31. manim/cli/render/output_options.py +6 -5
  32. manim/cli/render/render_options.py +97 -32
  33. manim/constants.py +65 -19
  34. manim/gui/gui.py +2 -0
  35. manim/mobject/frame.py +0 -1
  36. manim/mobject/geometry/arc.py +112 -78
  37. manim/mobject/geometry/boolean_ops.py +32 -25
  38. manim/mobject/geometry/labeled.py +300 -77
  39. manim/mobject/geometry/line.py +132 -64
  40. manim/mobject/geometry/polygram.py +126 -30
  41. manim/mobject/geometry/shape_matchers.py +35 -15
  42. manim/mobject/geometry/tips.py +38 -29
  43. manim/mobject/graph.py +414 -133
  44. manim/mobject/graphing/coordinate_systems.py +126 -64
  45. manim/mobject/graphing/functions.py +25 -15
  46. manim/mobject/graphing/number_line.py +24 -10
  47. manim/mobject/graphing/probability.py +2 -10
  48. manim/mobject/graphing/scale.py +6 -5
  49. manim/mobject/matrix.py +17 -19
  50. manim/mobject/mobject.py +314 -165
  51. manim/mobject/opengl/opengl_compatibility.py +2 -0
  52. manim/mobject/opengl/opengl_geometry.py +30 -9
  53. manim/mobject/opengl/opengl_image_mobject.py +2 -0
  54. manim/mobject/opengl/opengl_mobject.py +509 -343
  55. manim/mobject/opengl/opengl_point_cloud_mobject.py +5 -7
  56. manim/mobject/opengl/opengl_surface.py +3 -2
  57. manim/mobject/opengl/opengl_three_dimensions.py +2 -0
  58. manim/mobject/opengl/opengl_vectorized_mobject.py +46 -79
  59. manim/mobject/svg/brace.py +63 -13
  60. manim/mobject/svg/svg_mobject.py +4 -3
  61. manim/mobject/table.py +11 -13
  62. manim/mobject/text/code_mobject.py +186 -548
  63. manim/mobject/text/numbers.py +9 -7
  64. manim/mobject/text/tex_mobject.py +23 -14
  65. manim/mobject/text/text_mobject.py +70 -24
  66. manim/mobject/three_d/polyhedra.py +98 -1
  67. manim/mobject/three_d/three_d_utils.py +4 -4
  68. manim/mobject/three_d/three_dimensions.py +62 -34
  69. manim/mobject/types/image_mobject.py +42 -24
  70. manim/mobject/types/point_cloud_mobject.py +105 -67
  71. manim/mobject/types/vectorized_mobject.py +496 -228
  72. manim/mobject/value_tracker.py +5 -4
  73. manim/mobject/vector_field.py +5 -5
  74. manim/opengl/__init__.py +3 -3
  75. manim/plugins/__init__.py +14 -1
  76. manim/plugins/plugins_flags.py +14 -8
  77. manim/renderer/cairo_renderer.py +20 -10
  78. manim/renderer/opengl_renderer.py +21 -23
  79. manim/renderer/opengl_renderer_window.py +2 -0
  80. manim/renderer/shader.py +2 -3
  81. manim/renderer/shader_wrapper.py +5 -2
  82. manim/renderer/vectorized_mobject_rendering.py +5 -0
  83. manim/scene/moving_camera_scene.py +23 -0
  84. manim/scene/scene.py +90 -43
  85. manim/scene/scene_file_writer.py +316 -165
  86. manim/scene/section.py +17 -15
  87. manim/scene/three_d_scene.py +13 -21
  88. manim/scene/vector_space_scene.py +22 -9
  89. manim/typing.py +830 -70
  90. manim/utils/bezier.py +1667 -399
  91. manim/utils/caching.py +13 -5
  92. manim/utils/color/AS2700.py +2 -0
  93. manim/utils/color/BS381.py +3 -0
  94. manim/utils/color/DVIPSNAMES.py +96 -0
  95. manim/utils/color/SVGNAMES.py +179 -0
  96. manim/utils/color/X11.py +3 -0
  97. manim/utils/color/XKCD.py +3 -0
  98. manim/utils/color/__init__.py +8 -5
  99. manim/utils/color/core.py +844 -309
  100. manim/utils/color/manim_colors.py +7 -9
  101. manim/utils/commands.py +48 -20
  102. manim/utils/config_ops.py +18 -13
  103. manim/utils/debug.py +8 -7
  104. manim/utils/deprecation.py +90 -40
  105. manim/utils/docbuild/__init__.py +17 -0
  106. manim/utils/docbuild/autoaliasattr_directive.py +234 -0
  107. manim/utils/docbuild/autocolor_directive.py +21 -17
  108. manim/utils/docbuild/manim_directive.py +50 -35
  109. manim/utils/docbuild/module_parsing.py +245 -0
  110. manim/utils/exceptions.py +6 -0
  111. manim/utils/family.py +5 -3
  112. manim/utils/family_ops.py +17 -4
  113. manim/utils/file_ops.py +26 -16
  114. manim/utils/hashing.py +9 -7
  115. manim/utils/images.py +10 -4
  116. manim/utils/ipython_magic.py +14 -8
  117. manim/utils/iterables.py +161 -119
  118. manim/utils/module_ops.py +57 -19
  119. manim/utils/opengl.py +83 -24
  120. manim/utils/parameter_parsing.py +32 -0
  121. manim/utils/paths.py +21 -23
  122. manim/utils/polylabel.py +168 -0
  123. manim/utils/qhull.py +218 -0
  124. manim/utils/rate_functions.py +74 -39
  125. manim/utils/simple_functions.py +24 -15
  126. manim/utils/sounds.py +7 -1
  127. manim/utils/space_ops.py +125 -69
  128. manim/utils/testing/__init__.py +17 -0
  129. manim/utils/testing/_frames_testers.py +13 -8
  130. manim/utils/testing/_show_diff.py +5 -3
  131. manim/utils/testing/_test_class_makers.py +33 -18
  132. manim/utils/testing/frames_comparison.py +27 -19
  133. manim/utils/tex.py +127 -197
  134. manim/utils/tex_file_writing.py +47 -45
  135. manim/utils/tex_templates.py +2 -1
  136. manim/utils/unit.py +6 -5
  137. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/LICENSE.community +1 -1
  138. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/METADATA +40 -39
  139. manim-0.19.0.dist-info/RECORD +221 -0
  140. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/WHEEL +1 -1
  141. manim/cli/new/__init__.py +0 -0
  142. manim/cli/new/group.py +0 -189
  143. manim/plugins/import_plugins.py +0 -43
  144. manim-0.18.0.post0.dist-info/RECORD +0 -217
  145. {manim-0.18.0.post0.dist-info → manim-0.19.0.dist-info}/LICENSE +0 -0
  146. {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, Iterable, Sequence
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
- partial_quadratic_bezier_points,
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 listify, make_even, resize_with_interpolation
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 listify(width)])
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.has_stroke():
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
- partial_quadratic_bezier_points(tup, a1, a2)
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(length for _, length in curves_and_lengths)
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
- return np.array(
1061
- list(
1062
- it.chain(
1063
- *zip(
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
- bezier_groups = self.get_bezier_tuples_from_points(points)
1273
- norms = np.array([np.linalg.norm(bg[nppc - 1] - bg[0]) for bg in bezier_groups])
1274
- total_norm = sum(norms)
1275
- # Calculate insertions per curve (ipc)
1276
- if total_norm < 1e-6:
1277
- ipc = [n] + [0] * (len(bezier_groups) - 1)
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
- partial_quadratic_bezier_points(
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
- partial_quadratic_bezier_points(
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 = quadratic_bezier_remap(
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
- partial_quadratic_bezier_points(
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
- if not all(isinstance(m, OpenGLVMobject) for m in value):
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
  *(
@@ -4,7 +4,8 @@ from __future__ import annotations
4
4
 
5
5
  __all__ = ["Brace", "BraceLabel", "ArcBrace", "BraceText", "BraceBetweenPoints"]
6
6
 
7
- from typing import Sequence
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: Sequence[float] | None = DOWN,
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, *text, **kwargs)
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: Sequence[float] | None,
271
- point_2: Sequence[float] | None,
272
- direction: Sequence[float] | None = ORIGIN,
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):
@@ -264,7 +264,8 @@ class SVGMobject(VMobject, metaclass=ConvertToOpenGL):
264
264
  """
265
265
  result = []
266
266
  for shape in svg.elements():
267
- if isinstance(shape, se.Group):
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.set_height(self.svg_height)
445
+ self.set(height=self.svg_height)
445
446
  if self.svg_width is not None:
446
- self.set_width(self.svg_width)
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 typing import Callable, Iterable, Sequence
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("\\\\frac{\\sqrt{0}}{2}"),
1085
- MathTex("\\\\frac{\\sqrt{1}}{2}"),
1086
- MathTex("\\\\frac{\\sqrt{2}}{2}"),
1087
- MathTex("\\\\frac{\\sqrt{3}}{2}"),
1088
- MathTex("\\\\frac{\\sqrt{4}}{2}")],
1089
- row_labels=[MathTex("\\sin"), MathTex("\\cos")],
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": "^{\\circ}"})
1089
+ element_to_mobject_config={"unit": r"^{\circ}"})
1092
1090
  self.add(t0)
1093
1091
  """
1094
1092