manim 0.17.3__py3-none-any.whl → 0.18.0.post0__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 +1 -0
- manim/__main__.py +2 -0
- manim/_config/__init__.py +0 -1
- manim/_config/logger_utils.py +1 -0
- manim/_config/utils.py +14 -5
- manim/animation/changing.py +9 -5
- manim/animation/creation.py +8 -3
- manim/animation/indication.py +4 -4
- manim/animation/speedmodifier.py +2 -4
- manim/animation/updaters/mobject_update_utils.py +134 -16
- manim/camera/camera.py +31 -17
- manim/cli/checkhealth/__init__.py +0 -0
- manim/cli/checkhealth/checks.py +173 -0
- manim/cli/checkhealth/commands.py +81 -0
- manim/cli/render/global_options.py +6 -0
- manim/constants.py +58 -54
- manim/mobject/geometry/__init__.py +1 -0
- manim/mobject/geometry/arc.py +126 -91
- manim/mobject/geometry/boolean_ops.py +6 -10
- manim/mobject/geometry/labeled.py +155 -0
- manim/mobject/geometry/line.py +66 -50
- manim/mobject/geometry/polygram.py +23 -15
- manim/mobject/geometry/shape_matchers.py +24 -15
- manim/mobject/geometry/tips.py +62 -40
- manim/mobject/graph.py +3 -4
- manim/mobject/graphing/coordinate_systems.py +190 -139
- manim/mobject/graphing/number_line.py +5 -2
- manim/mobject/graphing/probability.py +4 -3
- manim/mobject/graphing/scale.py +7 -7
- manim/mobject/logo.py +108 -22
- manim/mobject/matrix.py +33 -37
- manim/mobject/mobject.py +327 -260
- manim/mobject/opengl/opengl_image_mobject.py +1 -1
- manim/mobject/opengl/opengl_mobject.py +18 -12
- manim/mobject/opengl/opengl_point_cloud_mobject.py +1 -1
- manim/mobject/opengl/opengl_surface.py +1 -1
- manim/mobject/opengl/opengl_vectorized_mobject.py +21 -17
- manim/mobject/svg/brace.py +3 -1
- manim/mobject/svg/svg_mobject.py +9 -11
- manim/mobject/table.py +50 -54
- manim/mobject/text/numbers.py +48 -6
- manim/mobject/text/tex_mobject.py +8 -12
- manim/mobject/text/text_mobject.py +32 -24
- manim/mobject/three_d/three_d_utils.py +13 -8
- manim/mobject/three_d/three_dimensions.py +61 -43
- manim/mobject/types/image_mobject.py +5 -4
- manim/mobject/types/point_cloud_mobject.py +8 -6
- manim/mobject/types/vectorized_mobject.py +385 -258
- manim/mobject/vector_field.py +19 -11
- manim/plugins/import_plugins.py +1 -1
- manim/plugins/plugins_flags.py +1 -6
- manim/renderer/shader.py +2 -2
- manim/scene/scene.py +15 -7
- manim/scene/scene_file_writer.py +1 -2
- manim/scene/three_d_scene.py +1 -1
- manim/scene/vector_space_scene.py +17 -7
- manim/typing.py +133 -0
- manim/utils/bezier.py +267 -83
- manim/utils/color/AS2700.py +234 -0
- manim/utils/color/BS381.py +315 -0
- manim/utils/color/X11.py +530 -0
- manim/utils/color/XKCD.py +949 -0
- manim/utils/color/__init__.py +58 -0
- manim/utils/color/core.py +1036 -0
- manim/utils/color/manim_colors.py +220 -0
- manim/utils/docbuild/autocolor_directive.py +92 -0
- manim/utils/docbuild/manim_directive.py +40 -6
- manim/utils/file_ops.py +1 -1
- manim/utils/hashing.py +1 -1
- manim/utils/iterables.py +1 -1
- manim/utils/rate_functions.py +33 -0
- manim/utils/simple_functions.py +0 -18
- manim/utils/space_ops.py +55 -42
- manim/utils/testing/frames_comparison.py +9 -0
- manim/utils/tex.py +2 -0
- manim/utils/tex_file_writing.py +29 -2
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/METADATA +14 -14
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/RECORD +82 -71
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/WHEEL +1 -1
- manim/communitycolors.py +0 -9
- manim/utils/color.py +0 -552
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/LICENSE +0 -0
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/LICENSE.community +0 -0
- {manim-0.17.3.dist-info → manim-0.18.0.post0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
r"""Mobjects that inherit from lines and contain a label along the length."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = ["LabeledLine", "LabeledArrow"]
|
|
6
|
+
|
|
7
|
+
from manim.constants import *
|
|
8
|
+
from manim.mobject.geometry.line import Arrow, Line
|
|
9
|
+
from manim.mobject.geometry.shape_matchers import (
|
|
10
|
+
BackgroundRectangle,
|
|
11
|
+
SurroundingRectangle,
|
|
12
|
+
)
|
|
13
|
+
from manim.mobject.text.tex_mobject import MathTex, Tex
|
|
14
|
+
from manim.mobject.text.text_mobject import Text
|
|
15
|
+
from manim.utils.color import WHITE, ManimColor, ParsableManimColor
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class LabeledLine(Line):
|
|
19
|
+
"""Constructs a line containing a label box somewhere along its length.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
label : str | Tex | MathTex | Text
|
|
24
|
+
Label that will be displayed on the line.
|
|
25
|
+
label_position : float | optional
|
|
26
|
+
A ratio in the range [0-1] to indicate the position of the label with respect to the length of the line. Default value is 0.5.
|
|
27
|
+
font_size : float | optional
|
|
28
|
+
Control font size for the label. This parameter is only used when `label` is of type `str`.
|
|
29
|
+
label_color: ParsableManimColor | optional
|
|
30
|
+
The color of the label's text. This parameter is only used when `label` is of type `str`.
|
|
31
|
+
label_frame : Bool | optional
|
|
32
|
+
Add a `SurroundingRectangle` frame to the label box.
|
|
33
|
+
frame_fill_color : ParsableManimColor | optional
|
|
34
|
+
Background color to fill the label box. If no value is provided, the background color of the canvas will be used.
|
|
35
|
+
frame_fill_opacity : float | optional
|
|
36
|
+
Determine the opacity of the label box by passing a value in the range [0-1], where 0 indicates complete transparency and 1 means full opacity.
|
|
37
|
+
|
|
38
|
+
.. seealso::
|
|
39
|
+
:class:`LabeledArrow`
|
|
40
|
+
|
|
41
|
+
Examples
|
|
42
|
+
--------
|
|
43
|
+
.. manim:: LabeledLineExample
|
|
44
|
+
:save_last_frame:
|
|
45
|
+
|
|
46
|
+
class LabeledLineExample(Scene):
|
|
47
|
+
def construct(self):
|
|
48
|
+
line = LabeledLine(
|
|
49
|
+
label = '0.5',
|
|
50
|
+
label_position = 0.8,
|
|
51
|
+
font_size = 20,
|
|
52
|
+
label_color = WHITE,
|
|
53
|
+
label_frame = True,
|
|
54
|
+
|
|
55
|
+
start=LEFT+DOWN,
|
|
56
|
+
end=RIGHT+UP)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
line.set_length(line.get_length() * 2)
|
|
60
|
+
self.add(line)
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
def __init__(
|
|
64
|
+
self,
|
|
65
|
+
label: str | Tex | MathTex | Text,
|
|
66
|
+
label_position: float = 0.5,
|
|
67
|
+
font_size: float = DEFAULT_FONT_SIZE,
|
|
68
|
+
label_color: ParsableManimColor = WHITE,
|
|
69
|
+
label_frame: bool = True,
|
|
70
|
+
frame_fill_color: ParsableManimColor = None,
|
|
71
|
+
frame_fill_opacity: float = 1,
|
|
72
|
+
*args,
|
|
73
|
+
**kwargs,
|
|
74
|
+
) -> None:
|
|
75
|
+
label_color = ManimColor(label_color)
|
|
76
|
+
frame_fill_color = ManimColor(frame_fill_color)
|
|
77
|
+
if isinstance(label, str):
|
|
78
|
+
from manim import MathTex
|
|
79
|
+
|
|
80
|
+
rendered_label = MathTex(label, color=label_color, font_size=font_size)
|
|
81
|
+
else:
|
|
82
|
+
rendered_label = label
|
|
83
|
+
|
|
84
|
+
super().__init__(*args, **kwargs)
|
|
85
|
+
|
|
86
|
+
# calculating the vector for the label position
|
|
87
|
+
line_start, line_end = self.get_start_and_end()
|
|
88
|
+
new_vec = (line_end - line_start) * label_position
|
|
89
|
+
label_coords = line_start + new_vec
|
|
90
|
+
|
|
91
|
+
# rendered_label.move_to(self.get_vector() * label_position)
|
|
92
|
+
rendered_label.move_to(label_coords)
|
|
93
|
+
|
|
94
|
+
box = BackgroundRectangle(
|
|
95
|
+
rendered_label,
|
|
96
|
+
buff=0.05,
|
|
97
|
+
color=frame_fill_color,
|
|
98
|
+
fill_opacity=frame_fill_opacity,
|
|
99
|
+
stroke_width=0.5,
|
|
100
|
+
)
|
|
101
|
+
self.add(box)
|
|
102
|
+
|
|
103
|
+
if label_frame:
|
|
104
|
+
box_frame = SurroundingRectangle(
|
|
105
|
+
rendered_label, buff=0.05, color=label_color, stroke_width=0.5
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
self.add(box_frame)
|
|
109
|
+
|
|
110
|
+
self.add(rendered_label)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class LabeledArrow(LabeledLine, Arrow):
|
|
114
|
+
"""Constructs an arrow containing a label box somewhere along its length.
|
|
115
|
+
This class inherits its label properties from `LabeledLine`, so the main parameters controlling it are the same.
|
|
116
|
+
|
|
117
|
+
Parameters
|
|
118
|
+
----------
|
|
119
|
+
label : str | Tex | MathTex | Text
|
|
120
|
+
Label that will be displayed on the line.
|
|
121
|
+
label_position : float | optional
|
|
122
|
+
A ratio in the range [0-1] to indicate the position of the label with respect to the length of the line. Default value is 0.5.
|
|
123
|
+
font_size : float | optional
|
|
124
|
+
Control font size for the label. This parameter is only used when `label` is of type `str`.
|
|
125
|
+
label_color: ParsableManimColor | optional
|
|
126
|
+
The color of the label's text. This parameter is only used when `label` is of type `str`.
|
|
127
|
+
label_frame : Bool | optional
|
|
128
|
+
Add a `SurroundingRectangle` frame to the label box.
|
|
129
|
+
frame_fill_color : ParsableManimColor | optional
|
|
130
|
+
Background color to fill the label box. If no value is provided, the background color of the canvas will be used.
|
|
131
|
+
frame_fill_opacity : float | optional
|
|
132
|
+
Determine the opacity of the label box by passing a value in the range [0-1], where 0 indicates complete transparency and 1 means full opacity.
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
.. seealso::
|
|
136
|
+
:class:`LabeledLine`
|
|
137
|
+
|
|
138
|
+
Examples
|
|
139
|
+
--------
|
|
140
|
+
.. manim:: LabeledArrowExample
|
|
141
|
+
:save_last_frame:
|
|
142
|
+
|
|
143
|
+
class LabeledArrowExample(Scene):
|
|
144
|
+
def construct(self):
|
|
145
|
+
l_arrow = LabeledArrow("0.5", start=LEFT*3, end=RIGHT*3 + UP*2, label_position=0.5)
|
|
146
|
+
|
|
147
|
+
self.add(l_arrow)
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
def __init__(
|
|
151
|
+
self,
|
|
152
|
+
*args,
|
|
153
|
+
**kwargs,
|
|
154
|
+
) -> None:
|
|
155
|
+
super().__init__(*args, **kwargs)
|
manim/mobject/geometry/line.py
CHANGED
|
@@ -14,10 +14,10 @@ __all__ = [
|
|
|
14
14
|
"RightAngle",
|
|
15
15
|
]
|
|
16
16
|
|
|
17
|
-
from typing import
|
|
17
|
+
from typing import TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
|
-
from
|
|
20
|
+
from typing_extensions import Self
|
|
21
21
|
|
|
22
22
|
from manim import config
|
|
23
23
|
from manim.constants import *
|
|
@@ -27,20 +27,32 @@ from manim.mobject.mobject import Mobject
|
|
|
27
27
|
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
|
|
28
28
|
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
|
|
29
29
|
from manim.mobject.types.vectorized_mobject import DashedVMobject, VGroup, VMobject
|
|
30
|
-
from manim.utils.color import
|
|
31
|
-
from manim.utils.color import Colors
|
|
30
|
+
from manim.utils.color import WHITE
|
|
32
31
|
from manim.utils.space_ops import angle_of_vector, line_intersection, normalize
|
|
33
32
|
|
|
33
|
+
if TYPE_CHECKING:
|
|
34
|
+
from manim.typing import Point2D, Point3D, Vector
|
|
35
|
+
from manim.utils.color import ParsableManimColor
|
|
36
|
+
|
|
37
|
+
from ..matrix import Matrix # Avoid circular import
|
|
38
|
+
|
|
34
39
|
|
|
35
40
|
class Line(TipableVMobject):
|
|
36
|
-
def __init__(
|
|
41
|
+
def __init__(
|
|
42
|
+
self,
|
|
43
|
+
start: Point3D = LEFT,
|
|
44
|
+
end: Point3D = RIGHT,
|
|
45
|
+
buff: float = 0,
|
|
46
|
+
path_arc: float | None = None,
|
|
47
|
+
**kwargs,
|
|
48
|
+
) -> None:
|
|
37
49
|
self.dim = 3
|
|
38
50
|
self.buff = buff
|
|
39
51
|
self.path_arc = path_arc
|
|
40
52
|
self._set_start_and_end_attrs(start, end)
|
|
41
53
|
super().__init__(**kwargs)
|
|
42
54
|
|
|
43
|
-
def generate_points(self):
|
|
55
|
+
def generate_points(self) -> None:
|
|
44
56
|
self.set_points_by_ends(
|
|
45
57
|
start=self.start,
|
|
46
58
|
end=self.end,
|
|
@@ -48,7 +60,13 @@ class Line(TipableVMobject):
|
|
|
48
60
|
path_arc=self.path_arc,
|
|
49
61
|
)
|
|
50
62
|
|
|
51
|
-
def set_points_by_ends(
|
|
63
|
+
def set_points_by_ends(
|
|
64
|
+
self,
|
|
65
|
+
start: Point3D,
|
|
66
|
+
end: Point3D,
|
|
67
|
+
buff: float = 0,
|
|
68
|
+
path_arc: float = 0,
|
|
69
|
+
) -> None:
|
|
52
70
|
if path_arc:
|
|
53
71
|
arc = ArcBetweenPoints(self.start, self.end, angle=self.path_arc)
|
|
54
72
|
self.set_points(arc.points)
|
|
@@ -59,7 +77,7 @@ class Line(TipableVMobject):
|
|
|
59
77
|
|
|
60
78
|
init_points = generate_points
|
|
61
79
|
|
|
62
|
-
def _account_for_buff(self, buff):
|
|
80
|
+
def _account_for_buff(self, buff: float) -> Self:
|
|
63
81
|
if buff == 0:
|
|
64
82
|
return
|
|
65
83
|
#
|
|
@@ -74,7 +92,7 @@ class Line(TipableVMobject):
|
|
|
74
92
|
self.pointwise_become_partial(self, buff_proportion, 1 - buff_proportion)
|
|
75
93
|
return self
|
|
76
94
|
|
|
77
|
-
def _set_start_and_end_attrs(self, start, end):
|
|
95
|
+
def _set_start_and_end_attrs(self, start: Point3D, end: Point3D) -> None:
|
|
78
96
|
# If either start or end are Mobjects, this
|
|
79
97
|
# gives their centers
|
|
80
98
|
rough_start = self._pointify(start)
|
|
@@ -88,9 +106,9 @@ class Line(TipableVMobject):
|
|
|
88
106
|
|
|
89
107
|
def _pointify(
|
|
90
108
|
self,
|
|
91
|
-
mob_or_point: Mobject |
|
|
92
|
-
direction:
|
|
93
|
-
) ->
|
|
109
|
+
mob_or_point: Mobject | Point3D,
|
|
110
|
+
direction: Vector | None = None,
|
|
111
|
+
) -> Point3D:
|
|
94
112
|
"""Transforms a mobject into its corresponding point. Does nothing if a point is passed.
|
|
95
113
|
|
|
96
114
|
``direction`` determines the location of the point along its bounding box in that direction.
|
|
@@ -110,11 +128,11 @@ class Line(TipableVMobject):
|
|
|
110
128
|
return mob.get_boundary_point(direction)
|
|
111
129
|
return np.array(mob_or_point)
|
|
112
130
|
|
|
113
|
-
def set_path_arc(self, new_value):
|
|
131
|
+
def set_path_arc(self, new_value: float) -> None:
|
|
114
132
|
self.path_arc = new_value
|
|
115
133
|
self.init_points()
|
|
116
134
|
|
|
117
|
-
def put_start_and_end_on(self, start:
|
|
135
|
+
def put_start_and_end_on(self, start: Point3D, end: Point3D) -> Self:
|
|
118
136
|
"""Sets starts and end coordinates of a line.
|
|
119
137
|
|
|
120
138
|
Examples
|
|
@@ -145,16 +163,16 @@ class Line(TipableVMobject):
|
|
|
145
163
|
self.generate_points()
|
|
146
164
|
return super().put_start_and_end_on(start, end)
|
|
147
165
|
|
|
148
|
-
def get_vector(self):
|
|
166
|
+
def get_vector(self) -> Vector:
|
|
149
167
|
return self.get_end() - self.get_start()
|
|
150
168
|
|
|
151
|
-
def get_unit_vector(self):
|
|
169
|
+
def get_unit_vector(self) -> Vector:
|
|
152
170
|
return normalize(self.get_vector())
|
|
153
171
|
|
|
154
|
-
def get_angle(self):
|
|
172
|
+
def get_angle(self) -> float:
|
|
155
173
|
return angle_of_vector(self.get_vector())
|
|
156
174
|
|
|
157
|
-
def get_projection(self, point:
|
|
175
|
+
def get_projection(self, point: Point3D) -> Vector:
|
|
158
176
|
"""Returns the projection of a point onto a line.
|
|
159
177
|
|
|
160
178
|
Parameters
|
|
@@ -168,10 +186,10 @@ class Line(TipableVMobject):
|
|
|
168
186
|
unit_vect = normalize(end - start)
|
|
169
187
|
return start + np.dot(point - start, unit_vect) * unit_vect
|
|
170
188
|
|
|
171
|
-
def get_slope(self):
|
|
189
|
+
def get_slope(self) -> float:
|
|
172
190
|
return np.tan(self.get_angle())
|
|
173
191
|
|
|
174
|
-
def set_angle(self, angle, about_point=None):
|
|
192
|
+
def set_angle(self, angle: float, about_point: Point3D | None = None) -> Self:
|
|
175
193
|
if about_point is None:
|
|
176
194
|
about_point = self.get_start()
|
|
177
195
|
|
|
@@ -182,7 +200,7 @@ class Line(TipableVMobject):
|
|
|
182
200
|
|
|
183
201
|
return self
|
|
184
202
|
|
|
185
|
-
def set_length(self, length):
|
|
203
|
+
def set_length(self, length: float) -> Self:
|
|
186
204
|
return self.scale(length / self.get_length())
|
|
187
205
|
|
|
188
206
|
|
|
@@ -222,11 +240,11 @@ class DashedLine(Line):
|
|
|
222
240
|
|
|
223
241
|
def __init__(
|
|
224
242
|
self,
|
|
225
|
-
*args
|
|
243
|
+
*args,
|
|
226
244
|
dash_length: float = DEFAULT_DASH_LENGTH,
|
|
227
245
|
dashed_ratio: float = 0.5,
|
|
228
246
|
**kwargs,
|
|
229
|
-
):
|
|
247
|
+
) -> None:
|
|
230
248
|
self.dash_length = dash_length
|
|
231
249
|
self.dashed_ratio = dashed_ratio
|
|
232
250
|
super().__init__(*args, **kwargs)
|
|
@@ -255,7 +273,7 @@ class DashedLine(Line):
|
|
|
255
273
|
int(np.ceil((self.get_length() / self.dash_length) * self.dashed_ratio)),
|
|
256
274
|
)
|
|
257
275
|
|
|
258
|
-
def get_start(self) ->
|
|
276
|
+
def get_start(self) -> Point3D:
|
|
259
277
|
"""Returns the start point of the line.
|
|
260
278
|
|
|
261
279
|
Examples
|
|
@@ -271,7 +289,7 @@ class DashedLine(Line):
|
|
|
271
289
|
else:
|
|
272
290
|
return super().get_start()
|
|
273
291
|
|
|
274
|
-
def get_end(self) ->
|
|
292
|
+
def get_end(self) -> Point3D:
|
|
275
293
|
"""Returns the end point of the line.
|
|
276
294
|
|
|
277
295
|
Examples
|
|
@@ -287,7 +305,7 @@ class DashedLine(Line):
|
|
|
287
305
|
else:
|
|
288
306
|
return super().get_end()
|
|
289
307
|
|
|
290
|
-
def get_first_handle(self) ->
|
|
308
|
+
def get_first_handle(self) -> Point3D:
|
|
291
309
|
"""Returns the point of the first handle.
|
|
292
310
|
|
|
293
311
|
Examples
|
|
@@ -300,7 +318,7 @@ class DashedLine(Line):
|
|
|
300
318
|
|
|
301
319
|
return self.submobjects[0].points[1]
|
|
302
320
|
|
|
303
|
-
def get_last_handle(self) ->
|
|
321
|
+
def get_last_handle(self) -> Point3D:
|
|
304
322
|
"""Returns the point of the last handle.
|
|
305
323
|
|
|
306
324
|
Examples
|
|
@@ -354,7 +372,7 @@ class TangentLine(Line):
|
|
|
354
372
|
length: float = 1,
|
|
355
373
|
d_alpha: float = 1e-6,
|
|
356
374
|
**kwargs,
|
|
357
|
-
):
|
|
375
|
+
) -> None:
|
|
358
376
|
self.length = length
|
|
359
377
|
self.d_alpha = d_alpha
|
|
360
378
|
da = self.d_alpha
|
|
@@ -396,7 +414,7 @@ class Elbow(VMobject, metaclass=ConvertToOpenGL):
|
|
|
396
414
|
self.add(elbow_group)
|
|
397
415
|
"""
|
|
398
416
|
|
|
399
|
-
def __init__(self, width: float = 0.2, angle: float = 0, **kwargs):
|
|
417
|
+
def __init__(self, width: float = 0.2, angle: float = 0, **kwargs) -> None:
|
|
400
418
|
self.angle = angle
|
|
401
419
|
super().__init__(**kwargs)
|
|
402
420
|
self.set_points_as_corners([UP, UP + RIGHT, RIGHT])
|
|
@@ -494,13 +512,13 @@ class Arrow(Line):
|
|
|
494
512
|
|
|
495
513
|
def __init__(
|
|
496
514
|
self,
|
|
497
|
-
*args
|
|
515
|
+
*args,
|
|
498
516
|
stroke_width: float = 6,
|
|
499
517
|
buff: float = MED_SMALL_BUFF,
|
|
500
518
|
max_tip_length_to_length_ratio: float = 0.25,
|
|
501
519
|
max_stroke_width_to_length_ratio: float = 5,
|
|
502
520
|
**kwargs,
|
|
503
|
-
):
|
|
521
|
+
) -> None:
|
|
504
522
|
self.max_tip_length_to_length_ratio = max_tip_length_to_length_ratio
|
|
505
523
|
self.max_stroke_width_to_length_ratio = max_stroke_width_to_length_ratio
|
|
506
524
|
tip_shape = kwargs.pop("tip_shape", ArrowTriangleFilledTip)
|
|
@@ -511,7 +529,7 @@ class Arrow(Line):
|
|
|
511
529
|
self.add_tip(tip_shape=tip_shape)
|
|
512
530
|
self._set_stroke_width_from_length()
|
|
513
531
|
|
|
514
|
-
def scale(self, factor, scale_tips=False, **kwargs):
|
|
532
|
+
def scale(self, factor: float, scale_tips: bool = False, **kwargs) -> Self:
|
|
515
533
|
r"""Scale an arrow, but keep stroke width and arrow tip size fixed.
|
|
516
534
|
|
|
517
535
|
|
|
@@ -561,7 +579,7 @@ class Arrow(Line):
|
|
|
561
579
|
self.add_tip(tip=old_tips[1], at_start=True)
|
|
562
580
|
return self
|
|
563
581
|
|
|
564
|
-
def get_normal_vector(self) ->
|
|
582
|
+
def get_normal_vector(self) -> Vector:
|
|
565
583
|
"""Returns the normal of a vector.
|
|
566
584
|
|
|
567
585
|
Examples
|
|
@@ -575,7 +593,7 @@ class Arrow(Line):
|
|
|
575
593
|
p0, p1, p2 = self.tip.get_start_anchors()[:3]
|
|
576
594
|
return normalize(np.cross(p2 - p1, p1 - p0))
|
|
577
595
|
|
|
578
|
-
def reset_normal_vector(self):
|
|
596
|
+
def reset_normal_vector(self) -> Self:
|
|
579
597
|
"""Resets the normal of a vector"""
|
|
580
598
|
self.normal_vector = self.get_normal_vector()
|
|
581
599
|
return self
|
|
@@ -595,7 +613,7 @@ class Arrow(Line):
|
|
|
595
613
|
max_ratio = self.max_tip_length_to_length_ratio
|
|
596
614
|
return min(self.tip_length, max_ratio * self.get_length())
|
|
597
615
|
|
|
598
|
-
def _set_stroke_width_from_length(self):
|
|
616
|
+
def _set_stroke_width_from_length(self) -> Self:
|
|
599
617
|
"""Sets stroke width based on length."""
|
|
600
618
|
max_ratio = self.max_stroke_width_to_length_ratio
|
|
601
619
|
if config.renderer == RendererType.OPENGL:
|
|
@@ -636,7 +654,7 @@ class Vector(Arrow):
|
|
|
636
654
|
self.add(plane, vector_1, vector_2)
|
|
637
655
|
"""
|
|
638
656
|
|
|
639
|
-
def __init__(self, direction:
|
|
657
|
+
def __init__(self, direction: Vector = RIGHT, buff: float = 0, **kwargs) -> None:
|
|
640
658
|
self.buff = buff
|
|
641
659
|
if len(direction) == 2:
|
|
642
660
|
direction = np.hstack([direction, 0])
|
|
@@ -647,9 +665,9 @@ class Vector(Arrow):
|
|
|
647
665
|
self,
|
|
648
666
|
integer_labels: bool = True,
|
|
649
667
|
n_dim: int = 2,
|
|
650
|
-
color:
|
|
668
|
+
color: ParsableManimColor | None = None,
|
|
651
669
|
**kwargs,
|
|
652
|
-
):
|
|
670
|
+
) -> Matrix:
|
|
653
671
|
"""Creates a label based on the coordinates of the vector.
|
|
654
672
|
|
|
655
673
|
Parameters
|
|
@@ -752,7 +770,7 @@ class DoubleArrow(Arrow):
|
|
|
752
770
|
self.add(box, d1, d2, d3)
|
|
753
771
|
"""
|
|
754
772
|
|
|
755
|
-
def __init__(self, *args
|
|
773
|
+
def __init__(self, *args, **kwargs) -> None:
|
|
756
774
|
if "tip_shape_end" in kwargs:
|
|
757
775
|
kwargs["tip_shape"] = kwargs.pop("tip_shape_end")
|
|
758
776
|
tip_shape_start = kwargs.pop("tip_shape_start", ArrowTriangleFilledTip)
|
|
@@ -873,16 +891,16 @@ class Angle(VMobject, metaclass=ConvertToOpenGL):
|
|
|
873
891
|
self,
|
|
874
892
|
line1: Line,
|
|
875
893
|
line2: Line,
|
|
876
|
-
radius: float = None,
|
|
877
|
-
quadrant:
|
|
894
|
+
radius: float | None = None,
|
|
895
|
+
quadrant: Point2D = (1, 1),
|
|
878
896
|
other_angle: bool = False,
|
|
879
897
|
dot: bool = False,
|
|
880
898
|
dot_radius: float | None = None,
|
|
881
899
|
dot_distance: float = 0.55,
|
|
882
|
-
dot_color:
|
|
900
|
+
dot_color: ParsableManimColor = WHITE,
|
|
883
901
|
elbow: bool = False,
|
|
884
902
|
**kwargs,
|
|
885
|
-
):
|
|
903
|
+
) -> None:
|
|
886
904
|
super().__init__(**kwargs)
|
|
887
905
|
self.lines = (line1, line2)
|
|
888
906
|
self.quadrant = quadrant
|
|
@@ -1019,14 +1037,10 @@ class Angle(VMobject, metaclass=ConvertToOpenGL):
|
|
|
1019
1037
|
self.add(line1, line2, angle, value)
|
|
1020
1038
|
"""
|
|
1021
1039
|
|
|
1022
|
-
if degrees
|
|
1023
|
-
return self.angle_value / DEGREES
|
|
1024
|
-
return self.angle_value
|
|
1040
|
+
return self.angle_value / DEGREES if degrees else self.angle_value
|
|
1025
1041
|
|
|
1026
1042
|
@staticmethod
|
|
1027
|
-
def from_three_points(
|
|
1028
|
-
A: np.ndarray, B: np.ndarray, C: np.ndarray, **kwargs
|
|
1029
|
-
) -> Angle:
|
|
1043
|
+
def from_three_points(A: Point3D, B: Point3D, C: Point3D, **kwargs) -> Angle:
|
|
1030
1044
|
"""The angle between the lines AB and BC.
|
|
1031
1045
|
|
|
1032
1046
|
This constructs the angle :math:`\\angle ABC`.
|
|
@@ -1101,5 +1115,7 @@ class RightAngle(Angle):
|
|
|
1101
1115
|
self.add(plots)
|
|
1102
1116
|
"""
|
|
1103
1117
|
|
|
1104
|
-
def __init__(
|
|
1118
|
+
def __init__(
|
|
1119
|
+
self, line1: Line, line2: Line, length: float | None = None, **kwargs
|
|
1120
|
+
) -> None:
|
|
1105
1121
|
super().__init__(line1, line2, radius=length, elbow=True, **kwargs)
|
|
@@ -15,20 +15,26 @@ __all__ = [
|
|
|
15
15
|
"Cutout",
|
|
16
16
|
]
|
|
17
17
|
|
|
18
|
+
|
|
18
19
|
from math import ceil
|
|
19
|
-
from typing import
|
|
20
|
+
from typing import TYPE_CHECKING
|
|
20
21
|
|
|
21
22
|
import numpy as np
|
|
22
|
-
from colour import Color
|
|
23
23
|
|
|
24
24
|
from manim.constants import *
|
|
25
25
|
from manim.mobject.geometry.arc import ArcBetweenPoints
|
|
26
26
|
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
|
|
27
27
|
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
|
|
28
|
-
from manim.utils.color import
|
|
28
|
+
from manim.utils.color import BLUE, WHITE, ParsableManimColor
|
|
29
29
|
from manim.utils.iterables import adjacent_n_tuples, adjacent_pairs
|
|
30
30
|
from manim.utils.space_ops import angle_between_vectors, normalize, regular_vertices
|
|
31
31
|
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from typing_extensions import Self
|
|
34
|
+
|
|
35
|
+
from manim.typing import Point3D, Point3D_Array
|
|
36
|
+
from manim.utils.color import ParsableManimColor
|
|
37
|
+
|
|
32
38
|
|
|
33
39
|
class Polygram(VMobject, metaclass=ConvertToOpenGL):
|
|
34
40
|
"""A generalized :class:`Polygon`, allowing for disconnected sets of edges.
|
|
@@ -65,7 +71,9 @@ class Polygram(VMobject, metaclass=ConvertToOpenGL):
|
|
|
65
71
|
self.wait()
|
|
66
72
|
"""
|
|
67
73
|
|
|
68
|
-
def __init__(
|
|
74
|
+
def __init__(
|
|
75
|
+
self, *vertex_groups: Point3D, color: ParsableManimColor = BLUE, **kwargs
|
|
76
|
+
):
|
|
69
77
|
super().__init__(color=color, **kwargs)
|
|
70
78
|
|
|
71
79
|
for vertices in vertex_groups:
|
|
@@ -77,7 +85,7 @@ class Polygram(VMobject, metaclass=ConvertToOpenGL):
|
|
|
77
85
|
[*(np.array(vertex) for vertex in vertices), first_vertex],
|
|
78
86
|
)
|
|
79
87
|
|
|
80
|
-
def get_vertices(self) ->
|
|
88
|
+
def get_vertices(self) -> Point3D_Array:
|
|
81
89
|
"""Gets the vertices of the :class:`Polygram`.
|
|
82
90
|
|
|
83
91
|
Returns
|
|
@@ -99,7 +107,7 @@ class Polygram(VMobject, metaclass=ConvertToOpenGL):
|
|
|
99
107
|
|
|
100
108
|
return self.get_start_anchors()
|
|
101
109
|
|
|
102
|
-
def get_vertex_groups(self) -> np.ndarray:
|
|
110
|
+
def get_vertex_groups(self) -> np.ndarray[Point3D_Array]:
|
|
103
111
|
"""Gets the vertex groups of the :class:`Polygram`.
|
|
104
112
|
|
|
105
113
|
Returns
|
|
@@ -139,7 +147,7 @@ class Polygram(VMobject, metaclass=ConvertToOpenGL):
|
|
|
139
147
|
radius: float | list[float] = 0.5,
|
|
140
148
|
evenly_distribute_anchors: bool = False,
|
|
141
149
|
components_per_rounded_corner: int = 2,
|
|
142
|
-
):
|
|
150
|
+
) -> Self:
|
|
143
151
|
"""Rounds off the corners of the :class:`Polygram`.
|
|
144
152
|
|
|
145
153
|
Parameters
|
|
@@ -304,7 +312,7 @@ class Polygon(Polygram):
|
|
|
304
312
|
self.add(isosceles, square_and_triangles)
|
|
305
313
|
"""
|
|
306
314
|
|
|
307
|
-
def __init__(self, *vertices:
|
|
315
|
+
def __init__(self, *vertices: Point3D, **kwargs) -> None:
|
|
308
316
|
super().__init__(vertices, **kwargs)
|
|
309
317
|
|
|
310
318
|
|
|
@@ -348,7 +356,7 @@ class RegularPolygram(Polygram):
|
|
|
348
356
|
radius: float = 1,
|
|
349
357
|
start_angle: float | None = None,
|
|
350
358
|
**kwargs,
|
|
351
|
-
):
|
|
359
|
+
) -> None:
|
|
352
360
|
# Regular polygrams can be expressed by the number of their vertices
|
|
353
361
|
# and their density. This relation can be expressed as its Schläfli
|
|
354
362
|
# symbol: {num_vertices/density}.
|
|
@@ -424,7 +432,7 @@ class RegularPolygon(RegularPolygram):
|
|
|
424
432
|
self.add(poly_group)
|
|
425
433
|
"""
|
|
426
434
|
|
|
427
|
-
def __init__(self, n: int = 6, **kwargs):
|
|
435
|
+
def __init__(self, n: int = 6, **kwargs) -> None:
|
|
428
436
|
super().__init__(n, density=1, **kwargs)
|
|
429
437
|
|
|
430
438
|
|
|
@@ -496,7 +504,7 @@ class Star(Polygon):
|
|
|
496
504
|
density: int = 2,
|
|
497
505
|
start_angle: float | None = TAU / 4,
|
|
498
506
|
**kwargs,
|
|
499
|
-
):
|
|
507
|
+
) -> None:
|
|
500
508
|
inner_angle = TAU / (2 * n)
|
|
501
509
|
|
|
502
510
|
if inner_radius is None:
|
|
@@ -555,7 +563,7 @@ class Triangle(RegularPolygon):
|
|
|
555
563
|
self.add(tri_group)
|
|
556
564
|
"""
|
|
557
565
|
|
|
558
|
-
def __init__(self, **kwargs):
|
|
566
|
+
def __init__(self, **kwargs) -> None:
|
|
559
567
|
super().__init__(n=3, **kwargs)
|
|
560
568
|
|
|
561
569
|
|
|
@@ -597,7 +605,7 @@ class Rectangle(Polygon):
|
|
|
597
605
|
|
|
598
606
|
def __init__(
|
|
599
607
|
self,
|
|
600
|
-
color:
|
|
608
|
+
color: ParsableManimColor = WHITE,
|
|
601
609
|
height: float = 2.0,
|
|
602
610
|
width: float = 4.0,
|
|
603
611
|
grid_xstep: float | None = None,
|
|
@@ -665,7 +673,7 @@ class Square(Rectangle):
|
|
|
665
673
|
self.add(square_1, square_2, square_3)
|
|
666
674
|
"""
|
|
667
675
|
|
|
668
|
-
def __init__(self, side_length: float = 2.0, **kwargs):
|
|
676
|
+
def __init__(self, side_length: float = 2.0, **kwargs) -> None:
|
|
669
677
|
self.side_length = side_length
|
|
670
678
|
super().__init__(height=side_length, width=side_length, **kwargs)
|
|
671
679
|
|
|
@@ -735,7 +743,7 @@ class Cutout(VMobject, metaclass=ConvertToOpenGL):
|
|
|
735
743
|
self.wait()
|
|
736
744
|
"""
|
|
737
745
|
|
|
738
|
-
def __init__(self, main_shape: VMobject, *mobjects: VMobject, **kwargs):
|
|
746
|
+
def __init__(self, main_shape: VMobject, *mobjects: VMobject, **kwargs) -> None:
|
|
739
747
|
super().__init__(**kwargs)
|
|
740
748
|
self.append_points(main_shape.points)
|
|
741
749
|
if main_shape.get_direction() == "CW":
|