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.

Files changed (129) hide show
  1. manim/__main__.py +45 -12
  2. manim/_config/__init__.py +2 -2
  3. manim/_config/cli_colors.py +8 -4
  4. manim/_config/default.cfg +0 -2
  5. manim/_config/logger_utils.py +5 -0
  6. manim/_config/utils.py +29 -38
  7. manim/animation/animation.py +148 -8
  8. manim/animation/composition.py +16 -13
  9. manim/animation/creation.py +184 -8
  10. manim/animation/fading.py +5 -8
  11. manim/animation/indication.py +93 -26
  12. manim/animation/movement.py +21 -3
  13. manim/animation/rotation.py +2 -1
  14. manim/animation/specialized.py +3 -5
  15. manim/animation/speedmodifier.py +3 -3
  16. manim/animation/transform.py +4 -5
  17. manim/animation/updaters/mobject_update_utils.py +17 -14
  18. manim/camera/camera.py +2 -2
  19. manim/cli/__init__.py +17 -0
  20. manim/cli/cfg/group.py +52 -36
  21. manim/cli/checkhealth/checks.py +92 -76
  22. manim/cli/checkhealth/commands.py +12 -5
  23. manim/cli/default_group.py +148 -24
  24. manim/cli/init/commands.py +28 -23
  25. manim/cli/plugins/commands.py +13 -3
  26. manim/cli/render/commands.py +47 -42
  27. manim/cli/render/global_options.py +43 -9
  28. manim/cli/render/render_options.py +84 -19
  29. manim/constants.py +11 -4
  30. manim/mobject/frame.py +0 -1
  31. manim/mobject/geometry/arc.py +109 -75
  32. manim/mobject/geometry/boolean_ops.py +20 -17
  33. manim/mobject/geometry/labeled.py +300 -77
  34. manim/mobject/geometry/line.py +120 -60
  35. manim/mobject/geometry/polygram.py +109 -25
  36. manim/mobject/geometry/shape_matchers.py +35 -15
  37. manim/mobject/geometry/tips.py +36 -27
  38. manim/mobject/graph.py +48 -40
  39. manim/mobject/graphing/coordinate_systems.py +110 -45
  40. manim/mobject/graphing/functions.py +16 -10
  41. manim/mobject/graphing/number_line.py +23 -9
  42. manim/mobject/graphing/probability.py +2 -10
  43. manim/mobject/graphing/scale.py +6 -5
  44. manim/mobject/matrix.py +17 -19
  45. manim/mobject/mobject.py +149 -103
  46. manim/mobject/opengl/opengl_geometry.py +4 -8
  47. manim/mobject/opengl/opengl_mobject.py +506 -343
  48. manim/mobject/opengl/opengl_point_cloud_mobject.py +3 -7
  49. manim/mobject/opengl/opengl_surface.py +1 -2
  50. manim/mobject/opengl/opengl_vectorized_mobject.py +27 -65
  51. manim/mobject/svg/brace.py +61 -13
  52. manim/mobject/svg/svg_mobject.py +2 -1
  53. manim/mobject/table.py +11 -12
  54. manim/mobject/text/code_mobject.py +186 -550
  55. manim/mobject/text/numbers.py +7 -7
  56. manim/mobject/text/tex_mobject.py +22 -13
  57. manim/mobject/text/text_mobject.py +29 -20
  58. manim/mobject/three_d/polyhedra.py +98 -1
  59. manim/mobject/three_d/three_dimensions.py +59 -31
  60. manim/mobject/types/image_mobject.py +37 -23
  61. manim/mobject/types/point_cloud_mobject.py +103 -67
  62. manim/mobject/types/vectorized_mobject.py +387 -214
  63. manim/mobject/value_tracker.py +2 -1
  64. manim/mobject/vector_field.py +2 -4
  65. manim/opengl/__init__.py +3 -3
  66. manim/plugins/__init__.py +2 -3
  67. manim/plugins/plugins_flags.py +3 -3
  68. manim/renderer/cairo_renderer.py +11 -11
  69. manim/renderer/opengl_renderer.py +19 -20
  70. manim/renderer/shader.py +2 -3
  71. manim/renderer/shader_wrapper.py +3 -2
  72. manim/scene/moving_camera_scene.py +23 -0
  73. manim/scene/scene.py +72 -41
  74. manim/scene/scene_file_writer.py +313 -164
  75. manim/scene/section.py +15 -15
  76. manim/scene/three_d_scene.py +8 -15
  77. manim/scene/vector_space_scene.py +3 -6
  78. manim/typing.py +326 -66
  79. manim/utils/bezier.py +1658 -381
  80. manim/utils/caching.py +11 -5
  81. manim/utils/color/AS2700.py +2 -0
  82. manim/utils/color/BS381.py +2 -0
  83. manim/utils/color/DVIPSNAMES.py +96 -0
  84. manim/utils/color/SVGNAMES.py +179 -0
  85. manim/utils/color/X11.py +3 -0
  86. manim/utils/color/XKCD.py +2 -0
  87. manim/utils/color/__init__.py +8 -5
  88. manim/utils/color/core.py +818 -301
  89. manim/utils/color/manim_colors.py +7 -9
  90. manim/utils/commands.py +40 -19
  91. manim/utils/config_ops.py +18 -13
  92. manim/utils/debug.py +8 -6
  93. manim/utils/deprecation.py +92 -43
  94. manim/utils/docbuild/autoaliasattr_directive.py +45 -8
  95. manim/utils/docbuild/autocolor_directive.py +12 -13
  96. manim/utils/docbuild/manim_directive.py +35 -29
  97. manim/utils/docbuild/module_parsing.py +74 -27
  98. manim/utils/family.py +3 -3
  99. manim/utils/family_ops.py +12 -4
  100. manim/utils/file_ops.py +22 -16
  101. manim/utils/hashing.py +7 -7
  102. manim/utils/images.py +10 -4
  103. manim/utils/ipython_magic.py +12 -8
  104. manim/utils/iterables.py +161 -119
  105. manim/utils/module_ops.py +55 -19
  106. manim/utils/opengl.py +68 -23
  107. manim/utils/parameter_parsing.py +3 -2
  108. manim/utils/paths.py +11 -5
  109. manim/utils/polylabel.py +168 -0
  110. manim/utils/qhull.py +218 -0
  111. manim/utils/rate_functions.py +69 -32
  112. manim/utils/simple_functions.py +24 -15
  113. manim/utils/sounds.py +7 -1
  114. manim/utils/space_ops.py +48 -37
  115. manim/utils/testing/_frames_testers.py +13 -8
  116. manim/utils/testing/_show_diff.py +5 -3
  117. manim/utils/testing/_test_class_makers.py +33 -18
  118. manim/utils/testing/frames_comparison.py +20 -14
  119. manim/utils/tex.py +4 -2
  120. manim/utils/tex_file_writing.py +45 -45
  121. manim/utils/tex_templates.py +1 -1
  122. manim/utils/unit.py +6 -5
  123. {manim-0.18.1.dist-info → manim-0.19.0.dist-info}/METADATA +16 -9
  124. manim-0.19.0.dist-info/RECORD +221 -0
  125. {manim-0.18.1.dist-info → manim-0.19.0.dist-info}/WHEEL +1 -1
  126. manim-0.18.1.dist-info/RECORD +0 -217
  127. {manim-0.18.1.dist-info → manim-0.19.0.dist-info}/LICENSE +0 -0
  128. {manim-0.18.1.dist-info → manim-0.19.0.dist-info}/LICENSE.community +0 -0
  129. {manim-0.18.1.dist-info → manim-0.19.0.dist-info}/entry_points.txt +0 -0
@@ -13,6 +13,7 @@ __all__ = [
13
13
  "Square",
14
14
  "RoundedRectangle",
15
15
  "Cutout",
16
+ "ConvexHull",
16
17
  ]
17
18
 
18
19
 
@@ -27,12 +28,22 @@ from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
27
28
  from manim.mobject.types.vectorized_mobject import VGroup, VMobject
28
29
  from manim.utils.color import BLUE, WHITE, ParsableManimColor
29
30
  from manim.utils.iterables import adjacent_n_tuples, adjacent_pairs
31
+ from manim.utils.qhull import QuickHull
30
32
  from manim.utils.space_ops import angle_between_vectors, normalize, regular_vertices
31
33
 
32
34
  if TYPE_CHECKING:
35
+ from typing import Any, Literal
36
+
37
+ import numpy.typing as npt
33
38
  from typing_extensions import Self
34
39
 
35
- from manim.typing import Point3D, Point3D_Array
40
+ from manim.typing import (
41
+ ManimFloat,
42
+ Point3D,
43
+ Point3D_Array,
44
+ Point3DLike,
45
+ Point3DLike_Array,
46
+ )
36
47
  from manim.utils.color import ParsableManimColor
37
48
 
38
49
 
@@ -72,11 +83,16 @@ class Polygram(VMobject, metaclass=ConvertToOpenGL):
72
83
  """
73
84
 
74
85
  def __init__(
75
- self, *vertex_groups: Point3D, color: ParsableManimColor = BLUE, **kwargs
86
+ self,
87
+ *vertex_groups: Point3DLike_Array,
88
+ color: ParsableManimColor = BLUE,
89
+ **kwargs: Any,
76
90
  ):
77
91
  super().__init__(color=color, **kwargs)
78
92
 
79
93
  for vertices in vertex_groups:
94
+ # The inferred type for *vertices is Any, but it should be
95
+ # Point3D_Array
80
96
  first_vertex, *vertices = vertices
81
97
  first_vertex = np.array(first_vertex)
82
98
 
@@ -104,10 +120,9 @@ class Polygram(VMobject, metaclass=ConvertToOpenGL):
104
120
  [-1., -1., 0.],
105
121
  [ 1., -1., 0.]])
106
122
  """
107
-
108
123
  return self.get_start_anchors()
109
124
 
110
- def get_vertex_groups(self) -> np.ndarray[Point3D_Array]:
125
+ def get_vertex_groups(self) -> npt.NDArray[ManimFloat]:
111
126
  """Gets the vertex groups of the :class:`Polygram`.
112
127
 
113
128
  Returns
@@ -129,7 +144,6 @@ class Polygram(VMobject, metaclass=ConvertToOpenGL):
129
144
  [-1., 1., 0.],
130
145
  [-2., 0., 0.]]])
131
146
  """
132
-
133
147
  vertex_groups = []
134
148
 
135
149
  group = []
@@ -204,11 +218,10 @@ class Polygram(VMobject, metaclass=ConvertToOpenGL):
204
218
  shapes.arrange(RIGHT)
205
219
  self.add(shapes)
206
220
  """
207
-
208
221
  if radius == 0:
209
222
  return self
210
223
 
211
- new_points = []
224
+ new_points: list[Point3D] = []
212
225
 
213
226
  for vertices in self.get_vertex_groups():
214
227
  arcs = []
@@ -277,7 +290,7 @@ class Polygram(VMobject, metaclass=ConvertToOpenGL):
277
290
 
278
291
  new_points.extend(line.points)
279
292
 
280
- self.set_points(new_points)
293
+ self.set_points(np.array(new_points))
281
294
 
282
295
  return self
283
296
 
@@ -312,7 +325,7 @@ class Polygon(Polygram):
312
325
  self.add(isosceles, square_and_triangles)
313
326
  """
314
327
 
315
- def __init__(self, *vertices: Point3D, **kwargs) -> None:
328
+ def __init__(self, *vertices: Point3DLike, **kwargs: Any) -> None:
316
329
  super().__init__(vertices, **kwargs)
317
330
 
318
331
 
@@ -355,7 +368,7 @@ class RegularPolygram(Polygram):
355
368
  density: int = 2,
356
369
  radius: float = 1,
357
370
  start_angle: float | None = None,
358
- **kwargs,
371
+ **kwargs: Any,
359
372
  ) -> None:
360
373
  # Regular polygrams can be expressed by the number of their vertices
361
374
  # and their density. This relation can be expressed as its Schläfli
@@ -376,7 +389,7 @@ class RegularPolygram(Polygram):
376
389
 
377
390
  # Utility function for generating the individual
378
391
  # polygon vertices.
379
- def gen_polygon_vertices(start_angle):
392
+ def gen_polygon_vertices(start_angle: float | None) -> tuple[list[Any], float]:
380
393
  reg_vertices, start_angle = regular_vertices(
381
394
  num_vertices,
382
395
  radius=radius,
@@ -432,7 +445,7 @@ class RegularPolygon(RegularPolygram):
432
445
  self.add(poly_group)
433
446
  """
434
447
 
435
- def __init__(self, n: int = 6, **kwargs) -> None:
448
+ def __init__(self, n: int = 6, **kwargs: Any) -> None:
436
449
  super().__init__(n, density=1, **kwargs)
437
450
 
438
451
 
@@ -472,7 +485,6 @@ class Star(Polygon):
472
485
  Examples
473
486
  --------
474
487
  .. manim:: StarExample
475
- :save_as_gif:
476
488
 
477
489
  class StarExample(Scene):
478
490
  def construct(self):
@@ -503,7 +515,7 @@ class Star(Polygon):
503
515
  inner_radius: float | None = None,
504
516
  density: int = 2,
505
517
  start_angle: float | None = TAU / 4,
506
- **kwargs,
518
+ **kwargs: Any,
507
519
  ) -> None:
508
520
  inner_angle = TAU / (2 * n)
509
521
 
@@ -535,7 +547,7 @@ class Star(Polygon):
535
547
  start_angle=self.start_angle + inner_angle,
536
548
  )
537
549
 
538
- vertices = []
550
+ vertices: list[npt.NDArray] = []
539
551
  for pair in zip(outer_vertices, inner_vertices):
540
552
  vertices.extend(pair)
541
553
 
@@ -563,7 +575,7 @@ class Triangle(RegularPolygon):
563
575
  self.add(tri_group)
564
576
  """
565
577
 
566
- def __init__(self, **kwargs) -> None:
578
+ def __init__(self, **kwargs: Any) -> None:
567
579
  super().__init__(n=3, **kwargs)
568
580
 
569
581
 
@@ -614,7 +626,7 @@ class Rectangle(Polygon):
614
626
  grid_ystep: float | None = None,
615
627
  mark_paths_closed: bool = True,
616
628
  close_new_points: bool = True,
617
- **kwargs,
629
+ **kwargs: Any,
618
630
  ):
619
631
  super().__init__(UR, UL, DL, DR, color=color, **kwargs)
620
632
  self.stretch_to_fit_width(width)
@@ -685,10 +697,17 @@ class Square(Rectangle):
685
697
  self.add(square_1, square_2, square_3)
686
698
  """
687
699
 
688
- def __init__(self, side_length: float = 2.0, **kwargs) -> None:
689
- self.side_length = side_length
700
+ def __init__(self, side_length: float = 2.0, **kwargs: Any) -> None:
690
701
  super().__init__(height=side_length, width=side_length, **kwargs)
691
702
 
703
+ @property
704
+ def side_length(self) -> float:
705
+ return float(np.linalg.norm(self.get_vertices()[0] - self.get_vertices()[1]))
706
+
707
+ @side_length.setter
708
+ def side_length(self, value: float) -> None:
709
+ self.scale(value / self.side_length)
710
+
692
711
 
693
712
  class RoundedRectangle(Rectangle):
694
713
  """A rectangle with rounded corners.
@@ -714,7 +733,7 @@ class RoundedRectangle(Rectangle):
714
733
  self.add(rect_group)
715
734
  """
716
735
 
717
- def __init__(self, corner_radius: float | list[float] = 0.5, **kwargs):
736
+ def __init__(self, corner_radius: float | list[float] = 0.5, **kwargs: Any):
718
737
  super().__init__(**kwargs)
719
738
  self.corner_radius = corner_radius
720
739
  self.round_corners(self.corner_radius)
@@ -755,12 +774,77 @@ class Cutout(VMobject, metaclass=ConvertToOpenGL):
755
774
  self.wait()
756
775
  """
757
776
 
758
- def __init__(self, main_shape: VMobject, *mobjects: VMobject, **kwargs) -> None:
777
+ def __init__(
778
+ self, main_shape: VMobject, *mobjects: VMobject, **kwargs: Any
779
+ ) -> None:
759
780
  super().__init__(**kwargs)
760
781
  self.append_points(main_shape.points)
761
- if main_shape.get_direction() == "CW":
762
- sub_direction = "CCW"
763
- else:
764
- sub_direction = "CW"
782
+ sub_direction: Literal["CCW", "CW"] = (
783
+ "CCW" if main_shape.get_direction() == "CW" else "CW"
784
+ )
765
785
  for mobject in mobjects:
766
786
  self.append_points(mobject.force_direction(sub_direction).points)
787
+
788
+
789
+ class ConvexHull(Polygram):
790
+ """Constructs a convex hull for a set of points in no particular order.
791
+
792
+ Parameters
793
+ ----------
794
+ points
795
+ The points to consider.
796
+ tolerance
797
+ The tolerance used by quickhull.
798
+ kwargs
799
+ Forwarded to the parent constructor.
800
+
801
+ Examples
802
+ --------
803
+ .. manim:: ConvexHullExample
804
+ :save_last_frame:
805
+ :quality: high
806
+
807
+ class ConvexHullExample(Scene):
808
+ def construct(self):
809
+ points = [
810
+ [-2.35, -2.25, 0],
811
+ [1.65, -2.25, 0],
812
+ [2.65, -0.25, 0],
813
+ [1.65, 1.75, 0],
814
+ [-0.35, 2.75, 0],
815
+ [-2.35, 0.75, 0],
816
+ [-0.35, -1.25, 0],
817
+ [0.65, -0.25, 0],
818
+ [-1.35, 0.25, 0],
819
+ [0.15, 0.75, 0]
820
+ ]
821
+ hull = ConvexHull(*points, color=BLUE)
822
+ dots = VGroup(*[Dot(point) for point in points])
823
+ self.add(hull)
824
+ self.add(dots)
825
+ """
826
+
827
+ def __init__(
828
+ self, *points: Point3DLike, tolerance: float = 1e-5, **kwargs: Any
829
+ ) -> None:
830
+ # Build Convex Hull
831
+ array = np.array(points)[:, :2]
832
+ hull = QuickHull(tolerance)
833
+ hull.build(array)
834
+
835
+ # Extract Vertices
836
+ facets = set(hull.facets) - hull.removed
837
+ facet = facets.pop()
838
+ subfacets = list(facet.subfacets)
839
+ while len(subfacets) <= len(facets):
840
+ sf = subfacets[-1]
841
+ (facet,) = hull.neighbors[sf] - {facet}
842
+ (sf,) = facet.subfacets - {sf}
843
+ subfacets.append(sf)
844
+
845
+ # Setup Vertices as Point3D
846
+ coordinates = np.vstack([sf.coordinates for sf in subfacets])
847
+ vertices = np.hstack((coordinates, np.zeros((len(coordinates), 1))))
848
+
849
+ # Call Polygram
850
+ super().__init__(vertices, **kwargs)
@@ -8,8 +8,15 @@ from typing import Any
8
8
 
9
9
  from typing_extensions import Self
10
10
 
11
- from manim import config, logger
12
- from manim.constants import *
11
+ from manim import logger
12
+ from manim._config import config
13
+ from manim.constants import (
14
+ DOWN,
15
+ LEFT,
16
+ RIGHT,
17
+ SMALL_BUFF,
18
+ UP,
19
+ )
13
20
  from manim.mobject.geometry.line import Line
14
21
  from manim.mobject.geometry.polygram import RoundedRectangle
15
22
  from manim.mobject.mobject import Mobject
@@ -43,21 +50,29 @@ class SurroundingRectangle(RoundedRectangle):
43
50
 
44
51
  def __init__(
45
52
  self,
46
- mobject: Mobject,
53
+ *mobjects: Mobject,
47
54
  color: ParsableManimColor = YELLOW,
48
55
  buff: float = SMALL_BUFF,
49
56
  corner_radius: float = 0.0,
50
- **kwargs,
57
+ **kwargs: Any,
51
58
  ) -> None:
59
+ from manim.mobject.mobject import Group
60
+
61
+ if not all(isinstance(mob, Mobject) for mob in mobjects):
62
+ raise TypeError(
63
+ "Expected all inputs for parameter mobjects to be a Mobjects"
64
+ )
65
+
66
+ group = Group(*mobjects)
52
67
  super().__init__(
53
68
  color=color,
54
- width=mobject.width + 2 * buff,
55
- height=mobject.height + 2 * buff,
69
+ width=group.width + 2 * buff,
70
+ height=group.height + 2 * buff,
56
71
  corner_radius=corner_radius,
57
72
  **kwargs,
58
73
  )
59
74
  self.buff = buff
60
- self.move_to(mobject)
75
+ self.move_to(group)
61
76
 
62
77
 
63
78
  class BackgroundRectangle(SurroundingRectangle):
@@ -87,19 +102,19 @@ class BackgroundRectangle(SurroundingRectangle):
87
102
 
88
103
  def __init__(
89
104
  self,
90
- mobject: Mobject,
105
+ *mobjects: Mobject,
91
106
  color: ParsableManimColor | None = None,
92
107
  stroke_width: float = 0,
93
108
  stroke_opacity: float = 0,
94
109
  fill_opacity: float = 0.75,
95
110
  buff: float = 0,
96
- **kwargs,
97
- ):
111
+ **kwargs: Any,
112
+ ) -> None:
98
113
  if color is None:
99
114
  color = config.background_color
100
115
 
101
116
  super().__init__(
102
- mobject,
117
+ *mobjects,
103
118
  color=color,
104
119
  stroke_width=stroke_width,
105
120
  stroke_opacity=stroke_opacity,
@@ -113,7 +128,7 @@ class BackgroundRectangle(SurroundingRectangle):
113
128
  self.set_fill(opacity=b * self.original_fill_opacity)
114
129
  return self
115
130
 
116
- def set_style(self, fill_opacity: float, **kwargs) -> Self:
131
+ def set_style(self, fill_opacity: float, **kwargs: Any) -> Self: # type: ignore[override]
117
132
  # Unchangeable style, except for fill_opacity
118
133
  # All other style arguments are ignored
119
134
  super().set_style(
@@ -130,7 +145,10 @@ class BackgroundRectangle(SurroundingRectangle):
130
145
  return self
131
146
 
132
147
  def get_fill_color(self) -> ManimColor:
133
- return self.color
148
+ # The type of the color property is set to Any using the property decorator
149
+ # vectorized_mobject.py#L571
150
+ temp_color: ManimColor = self.color
151
+ return temp_color
134
152
 
135
153
 
136
154
  class Cross(VGroup):
@@ -164,7 +182,7 @@ class Cross(VGroup):
164
182
  stroke_color: ParsableManimColor = RED,
165
183
  stroke_width: float = 6.0,
166
184
  scale_factor: float = 1.0,
167
- **kwargs,
185
+ **kwargs: Any,
168
186
  ) -> None:
169
187
  super().__init__(
170
188
  Line(UP + LEFT, DOWN + RIGHT), Line(UP + RIGHT, DOWN + LEFT), **kwargs
@@ -190,7 +208,9 @@ class Underline(Line):
190
208
  self.add(man, ul)
191
209
  """
192
210
 
193
- def __init__(self, mobject: Mobject, buff: float = SMALL_BUFF, **kwargs) -> None:
211
+ def __init__(
212
+ self, mobject: Mobject, buff: float = SMALL_BUFF, **kwargs: Any
213
+ ) -> None:
194
214
  super().__init__(LEFT, RIGHT, buff=buff, **kwargs)
195
215
  self.match_width(mobject)
196
216
  self.next_to(mobject, DOWN, buff=self.buff)
@@ -25,6 +25,8 @@ from manim.mobject.types.vectorized_mobject import VMobject
25
25
  from manim.utils.space_ops import angle_of_vector
26
26
 
27
27
  if TYPE_CHECKING:
28
+ from typing import Any
29
+
28
30
  from manim.typing import Point3D, Vector3D
29
31
 
30
32
 
@@ -60,8 +62,9 @@ class ArrowTip(VMobject, metaclass=ConvertToOpenGL):
60
62
  ... RegularPolygon.__init__(self, n=5, **kwargs)
61
63
  ... self.width = length
62
64
  ... self.stretch_to_fit_height(length)
63
- >>> arr = Arrow(np.array([-2, -2, 0]), np.array([2, 2, 0]),
64
- ... tip_shape=MyCustomArrowTip)
65
+ >>> arr = Arrow(
66
+ ... np.array([-2, -2, 0]), np.array([2, 2, 0]), tip_shape=MyCustomArrowTip
67
+ ... )
65
68
  >>> isinstance(arr.tip, RegularPolygon)
66
69
  True
67
70
  >>> from manim import Scene, Create
@@ -111,7 +114,7 @@ class ArrowTip(VMobject, metaclass=ConvertToOpenGL):
111
114
  self.add(*big_arrows, *small_arrows, *labels)
112
115
  """
113
116
 
114
- def __init__(self, *args, **kwargs) -> None:
117
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
115
118
  raise NotImplementedError("Has to be implemented in inheriting subclasses.")
116
119
 
117
120
  @property
@@ -146,7 +149,11 @@ class ArrowTip(VMobject, metaclass=ConvertToOpenGL):
146
149
  array([2., 0., 0.])
147
150
 
148
151
  """
149
- return self.points[0]
152
+ # Type inference of extracting an element from a list, is not
153
+ # supported by numpy, see this numpy issue
154
+ # https://github.com/numpy/numpy/issues/16544
155
+ tip_point: Point3D = self.points[0]
156
+ return tip_point
150
157
 
151
158
  @property
152
159
  def vector(self) -> Vector3D:
@@ -174,14 +181,14 @@ class ArrowTip(VMobject, metaclass=ConvertToOpenGL):
174
181
 
175
182
  >>> from manim import Arrow
176
183
  >>> arrow = Arrow(np.array([0, 0, 0]), np.array([1, 1, 0]), buff=0)
177
- >>> round(arrow.tip.tip_angle, 5) == round(PI/4, 5)
184
+ >>> bool(round(arrow.tip.tip_angle, 5) == round(PI/4, 5))
178
185
  True
179
186
 
180
187
  """
181
188
  return angle_of_vector(self.vector)
182
189
 
183
190
  @property
184
- def length(self) -> np.floating:
191
+ def length(self) -> float:
185
192
  r"""The length of the arrow tip.
186
193
 
187
194
  Examples
@@ -194,7 +201,7 @@ class ArrowTip(VMobject, metaclass=ConvertToOpenGL):
194
201
  0.35
195
202
 
196
203
  """
197
- return np.linalg.norm(self.vector)
204
+ return float(np.linalg.norm(self.vector))
198
205
 
199
206
 
200
207
  class StealthTip(ArrowTip):
@@ -206,36 +213,38 @@ class StealthTip(ArrowTip):
206
213
 
207
214
  def __init__(
208
215
  self,
209
- fill_opacity=1,
210
- stroke_width=3,
211
- length=DEFAULT_ARROW_TIP_LENGTH / 2,
212
- start_angle=PI,
213
- **kwargs,
216
+ fill_opacity: float = 1,
217
+ stroke_width: float = 3,
218
+ length: float = DEFAULT_ARROW_TIP_LENGTH / 2,
219
+ start_angle: float = PI,
220
+ **kwargs: Any,
214
221
  ):
215
222
  self.start_angle = start_angle
216
223
  VMobject.__init__(
217
224
  self, fill_opacity=fill_opacity, stroke_width=stroke_width, **kwargs
218
225
  )
219
226
  self.set_points_as_corners(
220
- [
221
- [2, 0, 0], # tip
222
- [-1.2, 1.6, 0],
223
- [0, 0, 0], # base
224
- [-1.2, -1.6, 0],
225
- [2, 0, 0], # close path, back to tip
226
- ]
227
+ np.array(
228
+ [
229
+ [2, 0, 0], # tip
230
+ [-1.2, 1.6, 0],
231
+ [0, 0, 0], # base
232
+ [-1.2, -1.6, 0],
233
+ [2, 0, 0], # close path, back to tip
234
+ ]
235
+ )
227
236
  )
228
237
  self.scale(length / self.length)
229
238
 
230
239
  @property
231
- def length(self):
240
+ def length(self) -> float:
232
241
  """The length of the arrow tip.
233
242
 
234
243
  In this case, the length is computed as the height of
235
244
  the triangle encompassing the stealth tip (otherwise,
236
245
  the tip is scaled too large).
237
246
  """
238
- return np.linalg.norm(self.vector) * 1.6
247
+ return float(np.linalg.norm(self.vector) * 1.6)
239
248
 
240
249
 
241
250
  class ArrowTriangleTip(ArrowTip, Triangle):
@@ -248,7 +257,7 @@ class ArrowTriangleTip(ArrowTip, Triangle):
248
257
  length: float = DEFAULT_ARROW_TIP_LENGTH,
249
258
  width: float = DEFAULT_ARROW_TIP_LENGTH,
250
259
  start_angle: float = PI,
251
- **kwargs,
260
+ **kwargs: Any,
252
261
  ) -> None:
253
262
  Triangle.__init__(
254
263
  self,
@@ -270,7 +279,7 @@ class ArrowTriangleFilledTip(ArrowTriangleTip):
270
279
  """
271
280
 
272
281
  def __init__(
273
- self, fill_opacity: float = 1, stroke_width: float = 0, **kwargs
282
+ self, fill_opacity: float = 1, stroke_width: float = 0, **kwargs: Any
274
283
  ) -> None:
275
284
  super().__init__(fill_opacity=fill_opacity, stroke_width=stroke_width, **kwargs)
276
285
 
@@ -284,7 +293,7 @@ class ArrowCircleTip(ArrowTip, Circle):
284
293
  stroke_width: float = 3,
285
294
  length: float = DEFAULT_ARROW_TIP_LENGTH,
286
295
  start_angle: float = PI,
287
- **kwargs,
296
+ **kwargs: Any,
288
297
  ) -> None:
289
298
  self.start_angle = start_angle
290
299
  Circle.__init__(
@@ -298,7 +307,7 @@ class ArrowCircleFilledTip(ArrowCircleTip):
298
307
  r"""Circular arrow tip with filled tip."""
299
308
 
300
309
  def __init__(
301
- self, fill_opacity: float = 1, stroke_width: float = 0, **kwargs
310
+ self, fill_opacity: float = 1, stroke_width: float = 0, **kwargs: Any
302
311
  ) -> None:
303
312
  super().__init__(fill_opacity=fill_opacity, stroke_width=stroke_width, **kwargs)
304
313
 
@@ -312,7 +321,7 @@ class ArrowSquareTip(ArrowTip, Square):
312
321
  stroke_width: float = 3,
313
322
  length: float = DEFAULT_ARROW_TIP_LENGTH,
314
323
  start_angle: float = PI,
315
- **kwargs,
324
+ **kwargs: Any,
316
325
  ) -> None:
317
326
  self.start_angle = start_angle
318
327
  Square.__init__(
@@ -330,6 +339,6 @@ class ArrowSquareFilledTip(ArrowSquareTip):
330
339
  r"""Square arrow tip with filled tip."""
331
340
 
332
341
  def __init__(
333
- self, fill_opacity: float = 1, stroke_width: float = 0, **kwargs
342
+ self, fill_opacity: float = 1, stroke_width: float = 0, **kwargs: Any
334
343
  ) -> None:
335
344
  super().__init__(fill_opacity=fill_opacity, stroke_width=stroke_width, **kwargs)