manim 0.18.0__py3-none-any.whl → 0.18.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of manim might be problematic. Click here for more details.
- manim/__init__.py +3 -6
- manim/__main__.py +18 -10
- manim/_config/__init__.py +5 -2
- manim/_config/cli_colors.py +12 -8
- manim/_config/default.cfg +1 -1
- manim/_config/logger_utils.py +9 -8
- manim/_config/utils.py +637 -449
- manim/animation/animation.py +9 -2
- manim/animation/composition.py +78 -40
- manim/animation/creation.py +12 -6
- manim/animation/fading.py +0 -1
- manim/animation/indication.py +10 -21
- manim/animation/movement.py +1 -2
- manim/animation/rotation.py +1 -1
- manim/animation/specialized.py +1 -1
- manim/animation/speedmodifier.py +7 -2
- manim/animation/transform_matching_parts.py +1 -1
- manim/camera/camera.py +13 -4
- manim/cli/cfg/group.py +18 -8
- manim/cli/checkhealth/checks.py +2 -0
- manim/cli/checkhealth/commands.py +2 -0
- manim/cli/default_group.py +13 -5
- manim/cli/init/commands.py +4 -1
- manim/cli/plugins/commands.py +3 -0
- manim/cli/render/commands.py +27 -20
- manim/cli/render/ease_of_access_options.py +4 -3
- manim/cli/render/global_options.py +9 -7
- manim/cli/render/output_options.py +6 -5
- manim/cli/render/render_options.py +13 -13
- manim/constants.py +54 -15
- manim/gui/gui.py +2 -0
- manim/mobject/geometry/arc.py +4 -4
- manim/mobject/geometry/boolean_ops.py +13 -9
- manim/mobject/geometry/line.py +16 -8
- manim/mobject/geometry/polygram.py +17 -5
- manim/mobject/geometry/tips.py +2 -2
- manim/mobject/graph.py +379 -106
- manim/mobject/graphing/coordinate_systems.py +17 -20
- manim/mobject/graphing/functions.py +14 -10
- manim/mobject/graphing/number_line.py +1 -1
- manim/mobject/mobject.py +175 -72
- manim/mobject/opengl/opengl_compatibility.py +2 -0
- manim/mobject/opengl/opengl_geometry.py +26 -1
- manim/mobject/opengl/opengl_image_mobject.py +2 -0
- manim/mobject/opengl/opengl_mobject.py +3 -0
- manim/mobject/opengl/opengl_point_cloud_mobject.py +2 -0
- manim/mobject/opengl/opengl_surface.py +2 -0
- manim/mobject/opengl/opengl_three_dimensions.py +2 -0
- manim/mobject/opengl/opengl_vectorized_mobject.py +19 -14
- manim/mobject/svg/brace.py +2 -0
- manim/mobject/svg/svg_mobject.py +10 -12
- manim/mobject/table.py +0 -1
- manim/mobject/text/code_mobject.py +2 -0
- manim/mobject/text/numbers.py +2 -0
- manim/mobject/text/tex_mobject.py +1 -1
- manim/mobject/text/text_mobject.py +43 -6
- manim/mobject/three_d/three_d_utils.py +4 -4
- manim/mobject/three_d/three_dimensions.py +4 -4
- manim/mobject/types/image_mobject.py +5 -1
- manim/mobject/types/point_cloud_mobject.py +2 -0
- manim/mobject/types/vectorized_mobject.py +124 -29
- manim/mobject/value_tracker.py +3 -3
- manim/mobject/vector_field.py +3 -1
- manim/plugins/__init__.py +15 -1
- manim/plugins/plugins_flags.py +11 -5
- manim/renderer/cairo_renderer.py +12 -2
- manim/renderer/opengl_renderer.py +2 -3
- manim/renderer/opengl_renderer_window.py +2 -0
- manim/renderer/shader_wrapper.py +2 -0
- manim/renderer/vectorized_mobject_rendering.py +5 -0
- manim/scene/scene.py +22 -6
- manim/scene/scene_file_writer.py +3 -1
- manim/scene/section.py +2 -0
- manim/scene/three_d_scene.py +5 -6
- manim/scene/vector_space_scene.py +21 -5
- manim/typing.py +567 -67
- manim/utils/bezier.py +9 -18
- manim/utils/caching.py +2 -0
- manim/utils/color/BS381.py +1 -0
- manim/utils/color/XKCD.py +1 -0
- manim/utils/color/core.py +31 -13
- manim/utils/commands.py +8 -1
- manim/utils/debug.py +0 -1
- manim/utils/deprecation.py +3 -2
- manim/utils/docbuild/__init__.py +17 -0
- manim/utils/docbuild/autoaliasattr_directive.py +197 -0
- manim/utils/docbuild/autocolor_directive.py +9 -4
- manim/utils/docbuild/manim_directive.py +18 -9
- manim/utils/docbuild/module_parsing.py +198 -0
- manim/utils/exceptions.py +6 -0
- manim/utils/family.py +2 -0
- manim/utils/family_ops.py +5 -0
- manim/utils/file_ops.py +6 -2
- manim/utils/hashing.py +2 -0
- manim/utils/ipython_magic.py +2 -0
- manim/utils/module_ops.py +2 -0
- manim/utils/opengl.py +14 -0
- manim/utils/parameter_parsing.py +31 -0
- manim/utils/paths.py +12 -20
- manim/utils/rate_functions.py +6 -8
- manim/utils/space_ops.py +81 -36
- manim/utils/testing/__init__.py +17 -0
- manim/utils/testing/frames_comparison.py +7 -5
- manim/utils/tex.py +124 -196
- manim/utils/tex_file_writing.py +2 -0
- manim/utils/tex_templates.py +1 -0
- {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/LICENSE.community +1 -1
- {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/METADATA +29 -35
- {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/RECORD +112 -112
- {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/WHEEL +1 -1
- manim/cli/new/__init__.py +0 -0
- manim/cli/new/group.py +0 -189
- manim/plugins/import_plugins.py +0 -43
- {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/LICENSE +0 -0
- {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/entry_points.txt +0 -0
manim/cli/render/commands.py
CHANGED
|
@@ -5,15 +5,18 @@ Manim's render subcommand is accessed in the command-line interface via
|
|
|
5
5
|
can specify options, and arguments for the render command.
|
|
6
6
|
|
|
7
7
|
"""
|
|
8
|
+
|
|
8
9
|
from __future__ import annotations
|
|
9
10
|
|
|
11
|
+
import http.client
|
|
10
12
|
import json
|
|
11
13
|
import sys
|
|
14
|
+
import urllib.error
|
|
15
|
+
import urllib.request
|
|
12
16
|
from pathlib import Path
|
|
17
|
+
from typing import cast
|
|
13
18
|
|
|
14
|
-
import click
|
|
15
19
|
import cloup
|
|
16
|
-
import requests
|
|
17
20
|
|
|
18
21
|
from ... import __version__, config, console, error_console, logger
|
|
19
22
|
from ..._config import tempconfig
|
|
@@ -24,14 +27,16 @@ from .global_options import global_options
|
|
|
24
27
|
from .output_options import output_options
|
|
25
28
|
from .render_options import render_options
|
|
26
29
|
|
|
30
|
+
__all__ = ["render"]
|
|
31
|
+
|
|
27
32
|
|
|
28
33
|
@cloup.command(
|
|
29
34
|
context_settings=None,
|
|
30
35
|
no_args_is_help=True,
|
|
31
36
|
epilog=EPILOG,
|
|
32
37
|
)
|
|
33
|
-
@
|
|
34
|
-
@
|
|
38
|
+
@cloup.argument("file", type=Path, required=True)
|
|
39
|
+
@cloup.argument("scene_names", required=False, nargs=-1)
|
|
35
40
|
@global_options
|
|
36
41
|
@output_options
|
|
37
42
|
@render_options # type: ignore
|
|
@@ -120,13 +125,26 @@ def render(
|
|
|
120
125
|
if config.notify_outdated_version:
|
|
121
126
|
manim_info_url = "https://pypi.org/pypi/manim/json"
|
|
122
127
|
warn_prompt = "Cannot check if latest release of manim is installed"
|
|
123
|
-
req_info = {}
|
|
124
128
|
|
|
125
129
|
try:
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
with urllib.request.urlopen(
|
|
131
|
+
urllib.request.Request(manim_info_url),
|
|
132
|
+
timeout=10,
|
|
133
|
+
) as response:
|
|
134
|
+
response = cast(http.client.HTTPResponse, response)
|
|
135
|
+
json_data = json.loads(response.read())
|
|
136
|
+
except urllib.error.HTTPError:
|
|
137
|
+
logger.debug("HTTP Error: %s", warn_prompt)
|
|
138
|
+
except urllib.error.URLError:
|
|
139
|
+
logger.debug("URL Error: %s", warn_prompt)
|
|
140
|
+
except json.JSONDecodeError:
|
|
141
|
+
logger.debug(
|
|
142
|
+
"Error while decoding JSON from %r: %s", manim_info_url, warn_prompt
|
|
143
|
+
)
|
|
144
|
+
except Exception:
|
|
145
|
+
logger.debug("Something went wrong: %s", warn_prompt)
|
|
146
|
+
else:
|
|
147
|
+
stable = json_data["info"]["version"]
|
|
130
148
|
if stable != __version__:
|
|
131
149
|
console.print(
|
|
132
150
|
f"You are using manim version [red]v{__version__}[/red], but version [green]v{stable}[/green] is available.",
|
|
@@ -134,16 +152,5 @@ def render(
|
|
|
134
152
|
console.print(
|
|
135
153
|
"You should consider upgrading via [yellow]pip install -U manim[/yellow]",
|
|
136
154
|
)
|
|
137
|
-
except requests.exceptions.HTTPError:
|
|
138
|
-
logger.debug(f"HTTP Error: {warn_prompt}")
|
|
139
|
-
except requests.exceptions.ConnectionError:
|
|
140
|
-
logger.debug(f"Connection Error: {warn_prompt}")
|
|
141
|
-
except requests.exceptions.Timeout:
|
|
142
|
-
logger.debug(f"Timed Out: {warn_prompt}")
|
|
143
|
-
except json.JSONDecodeError:
|
|
144
|
-
logger.debug(warn_prompt)
|
|
145
|
-
logger.debug(f"Error decoding JSON from {manim_info_url}")
|
|
146
|
-
except Exception:
|
|
147
|
-
logger.debug(f"Something went wrong: {warn_prompt}")
|
|
148
155
|
|
|
149
156
|
return args
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
3
|
+
from cloup import Choice, option, option_group
|
|
4
|
+
|
|
5
|
+
__all__ = ["ease_of_access_options"]
|
|
5
6
|
|
|
6
7
|
ease_of_access_options = option_group(
|
|
7
8
|
"Ease of access options",
|
|
@@ -9,7 +10,7 @@ ease_of_access_options = option_group(
|
|
|
9
10
|
"--progress_bar",
|
|
10
11
|
default=None,
|
|
11
12
|
show_default=False,
|
|
12
|
-
type=
|
|
13
|
+
type=Choice(
|
|
13
14
|
["display", "leave", "none"],
|
|
14
15
|
case_sensitive=False,
|
|
15
16
|
),
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
5
4
|
|
|
6
|
-
import
|
|
7
|
-
from cloup import option, option_group
|
|
5
|
+
from cloup import Choice, option, option_group
|
|
8
6
|
|
|
9
7
|
from ... import logger
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
from cloup._option_groups import OptionGroupDecorator
|
|
9
|
+
__all__ = ["global_options"]
|
|
13
10
|
|
|
14
11
|
|
|
15
12
|
def validate_gui_location(ctx, param, value):
|
|
@@ -22,7 +19,7 @@ def validate_gui_location(ctx, param, value):
|
|
|
22
19
|
exit()
|
|
23
20
|
|
|
24
21
|
|
|
25
|
-
global_options
|
|
22
|
+
global_options = option_group(
|
|
26
23
|
"Global options",
|
|
27
24
|
option(
|
|
28
25
|
"-c",
|
|
@@ -53,7 +50,7 @@ global_options: OptionGroupDecorator = option_group(
|
|
|
53
50
|
option(
|
|
54
51
|
"-v",
|
|
55
52
|
"--verbosity",
|
|
56
|
-
type=
|
|
53
|
+
type=Choice(
|
|
57
54
|
["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
|
|
58
55
|
case_sensitive=False,
|
|
59
56
|
),
|
|
@@ -108,4 +105,9 @@ global_options: OptionGroupDecorator = option_group(
|
|
|
108
105
|
help="Prevents deletion of .aux, .dvi, and .log files produced by Tex and MathTex.",
|
|
109
106
|
default=False,
|
|
110
107
|
),
|
|
108
|
+
option(
|
|
109
|
+
"--preview_command",
|
|
110
|
+
help="The command used to preview the output file (for example vlc for video files)",
|
|
111
|
+
default="",
|
|
112
|
+
),
|
|
111
113
|
)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
3
|
+
from cloup import IntRange, Path, option, option_group
|
|
4
|
+
|
|
5
|
+
__all__ = ["output_options"]
|
|
5
6
|
|
|
6
7
|
output_options = option_group(
|
|
7
8
|
"Output options",
|
|
@@ -15,7 +16,7 @@ output_options = option_group(
|
|
|
15
16
|
option(
|
|
16
17
|
"-0",
|
|
17
18
|
"--zero_pad",
|
|
18
|
-
type=
|
|
19
|
+
type=IntRange(0, 9),
|
|
19
20
|
default=None,
|
|
20
21
|
help="Zero padding for PNG file names.",
|
|
21
22
|
),
|
|
@@ -27,13 +28,13 @@ output_options = option_group(
|
|
|
27
28
|
),
|
|
28
29
|
option(
|
|
29
30
|
"--media_dir",
|
|
30
|
-
type=
|
|
31
|
+
type=Path(),
|
|
31
32
|
default=None,
|
|
32
33
|
help="Path to store rendered videos and latex.",
|
|
33
34
|
),
|
|
34
35
|
option(
|
|
35
36
|
"--log_dir",
|
|
36
|
-
type=
|
|
37
|
+
type=Path(),
|
|
37
38
|
help="Path to store render logs.",
|
|
38
39
|
default=None,
|
|
39
40
|
),
|
|
@@ -2,13 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
from cloup import option, option_group
|
|
5
|
+
from cloup import Choice, option, option_group
|
|
7
6
|
|
|
8
7
|
from manim.constants import QUALITIES, RendererType
|
|
9
8
|
|
|
10
9
|
from ... import logger
|
|
11
10
|
|
|
11
|
+
__all__ = ["render_options"]
|
|
12
|
+
|
|
12
13
|
|
|
13
14
|
def validate_scene_range(ctx, param, value):
|
|
14
15
|
try:
|
|
@@ -55,15 +56,21 @@ render_options = option_group(
|
|
|
55
56
|
),
|
|
56
57
|
option(
|
|
57
58
|
"--format",
|
|
58
|
-
type=
|
|
59
|
+
type=Choice(["png", "gif", "mp4", "webm", "mov"], case_sensitive=False),
|
|
59
60
|
default=None,
|
|
60
61
|
),
|
|
61
|
-
option(
|
|
62
|
+
option(
|
|
63
|
+
"-s",
|
|
64
|
+
"--save_last_frame",
|
|
65
|
+
default=None,
|
|
66
|
+
is_flag=True,
|
|
67
|
+
help="Render and save only the last frame of a scene as a PNG image.",
|
|
68
|
+
),
|
|
62
69
|
option(
|
|
63
70
|
"-q",
|
|
64
71
|
"--quality",
|
|
65
72
|
default=None,
|
|
66
|
-
type=
|
|
73
|
+
type=Choice(
|
|
67
74
|
list(reversed([q["flag"] for q in QUALITIES.values() if q["flag"]])), # type: ignore
|
|
68
75
|
case_sensitive=False,
|
|
69
76
|
),
|
|
@@ -95,7 +102,7 @@ render_options = option_group(
|
|
|
95
102
|
),
|
|
96
103
|
option(
|
|
97
104
|
"--renderer",
|
|
98
|
-
type=
|
|
105
|
+
type=Choice(
|
|
99
106
|
[renderer_type.value for renderer_type in RendererType],
|
|
100
107
|
case_sensitive=False,
|
|
101
108
|
),
|
|
@@ -122,13 +129,6 @@ render_options = option_group(
|
|
|
122
129
|
is_flag=True,
|
|
123
130
|
help="Save section videos in addition to movie file.",
|
|
124
131
|
),
|
|
125
|
-
option(
|
|
126
|
-
"-s",
|
|
127
|
-
"--save_last_frame",
|
|
128
|
-
default=None,
|
|
129
|
-
is_flag=True,
|
|
130
|
-
help="Save last frame as png (Deprecated).",
|
|
131
|
-
),
|
|
132
132
|
option(
|
|
133
133
|
"-t",
|
|
134
134
|
"--transparent",
|
manim/constants.py
CHANGED
|
@@ -10,7 +10,7 @@ import numpy as np
|
|
|
10
10
|
from cloup import Context
|
|
11
11
|
from PIL.Image import Resampling
|
|
12
12
|
|
|
13
|
-
from manim.typing import
|
|
13
|
+
from manim.typing import Vector3D
|
|
14
14
|
|
|
15
15
|
__all__ = [
|
|
16
16
|
"SCENE_NOT_FOUND_MESSAGE",
|
|
@@ -76,6 +76,7 @@ __all__ = [
|
|
|
76
76
|
"CTRL_VALUE",
|
|
77
77
|
"RendererType",
|
|
78
78
|
"LineJointType",
|
|
79
|
+
"CapStyleType",
|
|
79
80
|
]
|
|
80
81
|
# Messages
|
|
81
82
|
|
|
@@ -122,43 +123,43 @@ RESAMPLING_ALGORITHMS = {
|
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
# Geometry: directions
|
|
125
|
-
ORIGIN:
|
|
126
|
+
ORIGIN: Vector3D = np.array((0.0, 0.0, 0.0))
|
|
126
127
|
"""The center of the coordinate system."""
|
|
127
128
|
|
|
128
|
-
UP:
|
|
129
|
+
UP: Vector3D = np.array((0.0, 1.0, 0.0))
|
|
129
130
|
"""One unit step in the positive Y direction."""
|
|
130
131
|
|
|
131
|
-
DOWN:
|
|
132
|
+
DOWN: Vector3D = np.array((0.0, -1.0, 0.0))
|
|
132
133
|
"""One unit step in the negative Y direction."""
|
|
133
134
|
|
|
134
|
-
RIGHT:
|
|
135
|
+
RIGHT: Vector3D = np.array((1.0, 0.0, 0.0))
|
|
135
136
|
"""One unit step in the positive X direction."""
|
|
136
137
|
|
|
137
|
-
LEFT:
|
|
138
|
+
LEFT: Vector3D = np.array((-1.0, 0.0, 0.0))
|
|
138
139
|
"""One unit step in the negative X direction."""
|
|
139
140
|
|
|
140
|
-
IN:
|
|
141
|
+
IN: Vector3D = np.array((0.0, 0.0, -1.0))
|
|
141
142
|
"""One unit step in the negative Z direction."""
|
|
142
143
|
|
|
143
|
-
OUT:
|
|
144
|
+
OUT: Vector3D = np.array((0.0, 0.0, 1.0))
|
|
144
145
|
"""One unit step in the positive Z direction."""
|
|
145
146
|
|
|
146
147
|
# Geometry: axes
|
|
147
|
-
X_AXIS:
|
|
148
|
-
Y_AXIS:
|
|
149
|
-
Z_AXIS:
|
|
148
|
+
X_AXIS: Vector3D = np.array((1.0, 0.0, 0.0))
|
|
149
|
+
Y_AXIS: Vector3D = np.array((0.0, 1.0, 0.0))
|
|
150
|
+
Z_AXIS: Vector3D = np.array((0.0, 0.0, 1.0))
|
|
150
151
|
|
|
151
152
|
# Geometry: useful abbreviations for diagonals
|
|
152
|
-
UL:
|
|
153
|
+
UL: Vector3D = UP + LEFT
|
|
153
154
|
"""One step up plus one step left."""
|
|
154
155
|
|
|
155
|
-
UR:
|
|
156
|
+
UR: Vector3D = UP + RIGHT
|
|
156
157
|
"""One step up plus one step right."""
|
|
157
158
|
|
|
158
|
-
DL:
|
|
159
|
+
DL: Vector3D = DOWN + LEFT
|
|
159
160
|
"""One step down plus one step left."""
|
|
160
161
|
|
|
161
|
-
DR:
|
|
162
|
+
DR: Vector3D = DOWN + RIGHT
|
|
162
163
|
"""One step down plus one step right."""
|
|
163
164
|
|
|
164
165
|
# Geometry
|
|
@@ -305,3 +306,41 @@ class LineJointType(Enum):
|
|
|
305
306
|
ROUND = 1
|
|
306
307
|
BEVEL = 2
|
|
307
308
|
MITER = 3
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
class CapStyleType(Enum):
|
|
312
|
+
"""Collection of available cap styles.
|
|
313
|
+
|
|
314
|
+
See the example below for a visual illustration of the different
|
|
315
|
+
cap styles.
|
|
316
|
+
|
|
317
|
+
Examples
|
|
318
|
+
--------
|
|
319
|
+
|
|
320
|
+
.. manim:: CapStyleVariants
|
|
321
|
+
:save_last_frame:
|
|
322
|
+
|
|
323
|
+
class CapStyleVariants(Scene):
|
|
324
|
+
def construct(self):
|
|
325
|
+
arcs = VGroup(*[
|
|
326
|
+
Arc(
|
|
327
|
+
radius=1,
|
|
328
|
+
start_angle=0,
|
|
329
|
+
angle=TAU / 4,
|
|
330
|
+
stroke_width=20,
|
|
331
|
+
color=GREEN,
|
|
332
|
+
cap_style=cap_style,
|
|
333
|
+
)
|
|
334
|
+
for cap_style in CapStyleType
|
|
335
|
+
])
|
|
336
|
+
arcs.arrange(RIGHT, buff=1)
|
|
337
|
+
self.add(arcs)
|
|
338
|
+
for arc in arcs:
|
|
339
|
+
label = Text(arc.cap_style.name, font_size=24).next_to(arc, DOWN)
|
|
340
|
+
self.add(label)
|
|
341
|
+
"""
|
|
342
|
+
|
|
343
|
+
AUTO = 0
|
|
344
|
+
ROUND = 1
|
|
345
|
+
BUTT = 2
|
|
346
|
+
SQUARE = 3
|
manim/gui/gui.py
CHANGED
manim/mobject/geometry/arc.py
CHANGED
|
@@ -67,7 +67,7 @@ if TYPE_CHECKING:
|
|
|
67
67
|
from manim.mobject.mobject import Mobject
|
|
68
68
|
from manim.mobject.text.tex_mobject import SingleStringMathTex, Tex
|
|
69
69
|
from manim.mobject.text.text_mobject import Text
|
|
70
|
-
from manim.typing import CubicBezierPoints, Point3D, QuadraticBezierPoints,
|
|
70
|
+
from manim.typing import CubicBezierPoints, Point3D, QuadraticBezierPoints, Vector3D
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
class TipableVMobject(VMobject, metaclass=ConvertToOpenGL):
|
|
@@ -91,12 +91,12 @@ class TipableVMobject(VMobject, metaclass=ConvertToOpenGL):
|
|
|
91
91
|
def __init__(
|
|
92
92
|
self,
|
|
93
93
|
tip_length: float = DEFAULT_ARROW_TIP_LENGTH,
|
|
94
|
-
normal_vector:
|
|
94
|
+
normal_vector: Vector3D = OUT,
|
|
95
95
|
tip_style: dict = {},
|
|
96
96
|
**kwargs,
|
|
97
97
|
) -> None:
|
|
98
98
|
self.tip_length: float = tip_length
|
|
99
|
-
self.normal_vector:
|
|
99
|
+
self.normal_vector: Vector3D = normal_vector
|
|
100
100
|
self.tip_style: dict = tip_style
|
|
101
101
|
super().__init__(**kwargs)
|
|
102
102
|
|
|
@@ -389,7 +389,7 @@ class Arc(TipableVMobject):
|
|
|
389
389
|
# For a1 and a2 to lie at the same point arc radius
|
|
390
390
|
# must be zero. Thus arc_center will also lie at
|
|
391
391
|
# that point.
|
|
392
|
-
return a1
|
|
392
|
+
return np.copy(a1)
|
|
393
393
|
# Tangent vectors
|
|
394
394
|
t1 = h1 - a1
|
|
395
395
|
t2 = h2 - a2
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
5
7
|
import numpy as np
|
|
6
8
|
from pathops import Path as SkiaPath
|
|
7
9
|
from pathops import PathVerb, difference, intersection, union, xor
|
|
@@ -9,7 +11,9 @@ from pathops import PathVerb, difference, intersection, union, xor
|
|
|
9
11
|
from manim import config
|
|
10
12
|
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
|
|
11
13
|
from manim.mobject.types.vectorized_mobject import VMobject
|
|
12
|
-
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from manim.typing import Point2D_Array, Point3D_Array
|
|
13
17
|
|
|
14
18
|
from ...constants import RendererType
|
|
15
19
|
|
|
@@ -26,21 +30,21 @@ class _BooleanOps(VMobject, metaclass=ConvertToOpenGL):
|
|
|
26
30
|
self,
|
|
27
31
|
points: Point2D_Array,
|
|
28
32
|
z_dim: float = 0.0,
|
|
29
|
-
) ->
|
|
30
|
-
"""Converts an iterable with coordinates in
|
|
31
|
-
:attr:`z_dim` as the
|
|
33
|
+
) -> Point3D_Array:
|
|
34
|
+
"""Converts an iterable with coordinates in 2D to 3D by adding
|
|
35
|
+
:attr:`z_dim` as the Z coordinate.
|
|
32
36
|
|
|
33
37
|
Parameters
|
|
34
38
|
----------
|
|
35
39
|
points:
|
|
36
|
-
An iterable
|
|
40
|
+
An iterable of points.
|
|
37
41
|
z_dim:
|
|
38
|
-
|
|
42
|
+
Default value for the Z coordinate.
|
|
39
43
|
|
|
40
44
|
Returns
|
|
41
45
|
-------
|
|
42
|
-
|
|
43
|
-
A list of
|
|
46
|
+
Point3D_Array
|
|
47
|
+
A list of the points converted to 3D.
|
|
44
48
|
|
|
45
49
|
Example
|
|
46
50
|
-------
|
|
@@ -66,7 +70,7 @@ class _BooleanOps(VMobject, metaclass=ConvertToOpenGL):
|
|
|
66
70
|
|
|
67
71
|
Returns
|
|
68
72
|
-------
|
|
69
|
-
SkiaPath
|
|
73
|
+
SkiaPath
|
|
70
74
|
The converted path.
|
|
71
75
|
"""
|
|
72
76
|
path = SkiaPath()
|
manim/mobject/geometry/line.py
CHANGED
|
@@ -17,7 +17,6 @@ __all__ = [
|
|
|
17
17
|
from typing import TYPE_CHECKING
|
|
18
18
|
|
|
19
19
|
import numpy as np
|
|
20
|
-
from typing_extensions import Self
|
|
21
20
|
|
|
22
21
|
from manim import config
|
|
23
22
|
from manim.constants import *
|
|
@@ -31,7 +30,9 @@ from manim.utils.color import WHITE
|
|
|
31
30
|
from manim.utils.space_ops import angle_of_vector, line_intersection, normalize
|
|
32
31
|
|
|
33
32
|
if TYPE_CHECKING:
|
|
34
|
-
from
|
|
33
|
+
from typing_extensions import Self
|
|
34
|
+
|
|
35
|
+
from manim.typing import Point2D, Point3D, Vector3D
|
|
35
36
|
from manim.utils.color import ParsableManimColor
|
|
36
37
|
|
|
37
38
|
from ..matrix import Matrix # Avoid circular import
|
|
@@ -107,7 +108,7 @@ class Line(TipableVMobject):
|
|
|
107
108
|
def _pointify(
|
|
108
109
|
self,
|
|
109
110
|
mob_or_point: Mobject | Point3D,
|
|
110
|
-
direction:
|
|
111
|
+
direction: Vector3D | None = None,
|
|
111
112
|
) -> Point3D:
|
|
112
113
|
"""Transforms a mobject into its corresponding point. Does nothing if a point is passed.
|
|
113
114
|
|
|
@@ -163,16 +164,16 @@ class Line(TipableVMobject):
|
|
|
163
164
|
self.generate_points()
|
|
164
165
|
return super().put_start_and_end_on(start, end)
|
|
165
166
|
|
|
166
|
-
def get_vector(self) ->
|
|
167
|
+
def get_vector(self) -> Vector3D:
|
|
167
168
|
return self.get_end() - self.get_start()
|
|
168
169
|
|
|
169
|
-
def get_unit_vector(self) ->
|
|
170
|
+
def get_unit_vector(self) -> Vector3D:
|
|
170
171
|
return normalize(self.get_vector())
|
|
171
172
|
|
|
172
173
|
def get_angle(self) -> float:
|
|
173
174
|
return angle_of_vector(self.get_vector())
|
|
174
175
|
|
|
175
|
-
def get_projection(self, point: Point3D) ->
|
|
176
|
+
def get_projection(self, point: Point3D) -> Vector3D:
|
|
176
177
|
"""Returns the projection of a point onto a line.
|
|
177
178
|
|
|
178
179
|
Parameters
|
|
@@ -579,7 +580,7 @@ class Arrow(Line):
|
|
|
579
580
|
self.add_tip(tip=old_tips[1], at_start=True)
|
|
580
581
|
return self
|
|
581
582
|
|
|
582
|
-
def get_normal_vector(self) ->
|
|
583
|
+
def get_normal_vector(self) -> Vector3D:
|
|
583
584
|
"""Returns the normal of a vector.
|
|
584
585
|
|
|
585
586
|
Examples
|
|
@@ -632,6 +633,11 @@ class Arrow(Line):
|
|
|
632
633
|
class Vector(Arrow):
|
|
633
634
|
"""A vector specialized for use in graphs.
|
|
634
635
|
|
|
636
|
+
.. caution::
|
|
637
|
+
Do not confuse with the :class:`~.Vector2D`,
|
|
638
|
+
:class:`~.Vector3D` or :class:`~.VectorND` type aliases,
|
|
639
|
+
which are not Mobjects!
|
|
640
|
+
|
|
635
641
|
Parameters
|
|
636
642
|
----------
|
|
637
643
|
direction
|
|
@@ -654,7 +660,9 @@ class Vector(Arrow):
|
|
|
654
660
|
self.add(plane, vector_1, vector_2)
|
|
655
661
|
"""
|
|
656
662
|
|
|
657
|
-
def __init__(
|
|
663
|
+
def __init__(
|
|
664
|
+
self, direction: Point2D | Point3D = RIGHT, buff: float = 0, **kwargs
|
|
665
|
+
) -> None:
|
|
658
666
|
self.buff = buff
|
|
659
667
|
if len(direction) == 2:
|
|
660
668
|
direction = np.hstack([direction, 0])
|
|
@@ -598,8 +598,10 @@ class Rectangle(Polygon):
|
|
|
598
598
|
def construct(self):
|
|
599
599
|
rect1 = Rectangle(width=4.0, height=2.0, grid_xstep=1.0, grid_ystep=0.5)
|
|
600
600
|
rect2 = Rectangle(width=1.0, height=4.0)
|
|
601
|
+
rect3 = Rectangle(width=2.0, height=2.0, grid_xstep=1.0, grid_ystep=1.0)
|
|
602
|
+
rect3.grid_lines.set_stroke(width=1)
|
|
601
603
|
|
|
602
|
-
rects = Group(rect1,rect2).arrange(buff=1)
|
|
604
|
+
rects = Group(rect1, rect2, rect3).arrange(buff=1)
|
|
603
605
|
self.add(rects)
|
|
604
606
|
"""
|
|
605
607
|
|
|
@@ -617,10 +619,16 @@ class Rectangle(Polygon):
|
|
|
617
619
|
super().__init__(UR, UL, DL, DR, color=color, **kwargs)
|
|
618
620
|
self.stretch_to_fit_width(width)
|
|
619
621
|
self.stretch_to_fit_height(height)
|
|
622
|
+
|
|
620
623
|
v = self.get_vertices()
|
|
621
|
-
|
|
624
|
+
self.grid_lines = VGroup()
|
|
625
|
+
|
|
626
|
+
if grid_xstep or grid_ystep:
|
|
622
627
|
from manim.mobject.geometry.line import Line
|
|
623
628
|
|
|
629
|
+
v = self.get_vertices()
|
|
630
|
+
|
|
631
|
+
if grid_xstep:
|
|
624
632
|
grid_xstep = abs(grid_xstep)
|
|
625
633
|
count = int(width / grid_xstep)
|
|
626
634
|
grid = VGroup(
|
|
@@ -633,8 +641,9 @@ class Rectangle(Polygon):
|
|
|
633
641
|
for i in range(1, count)
|
|
634
642
|
)
|
|
635
643
|
)
|
|
636
|
-
self.add(grid)
|
|
637
|
-
|
|
644
|
+
self.grid_lines.add(grid)
|
|
645
|
+
|
|
646
|
+
if grid_ystep:
|
|
638
647
|
grid_ystep = abs(grid_ystep)
|
|
639
648
|
count = int(height / grid_ystep)
|
|
640
649
|
grid = VGroup(
|
|
@@ -647,7 +656,10 @@ class Rectangle(Polygon):
|
|
|
647
656
|
for i in range(1, count)
|
|
648
657
|
)
|
|
649
658
|
)
|
|
650
|
-
self.add(grid)
|
|
659
|
+
self.grid_lines.add(grid)
|
|
660
|
+
|
|
661
|
+
if self.grid_lines:
|
|
662
|
+
self.add(self.grid_lines)
|
|
651
663
|
|
|
652
664
|
|
|
653
665
|
class Square(Rectangle):
|
manim/mobject/geometry/tips.py
CHANGED
|
@@ -25,7 +25,7 @@ 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 manim.typing import Point3D,
|
|
28
|
+
from manim.typing import Point3D, Vector3D
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
class ArrowTip(VMobject, metaclass=ConvertToOpenGL):
|
|
@@ -149,7 +149,7 @@ class ArrowTip(VMobject, metaclass=ConvertToOpenGL):
|
|
|
149
149
|
return self.points[0]
|
|
150
150
|
|
|
151
151
|
@property
|
|
152
|
-
def vector(self) ->
|
|
152
|
+
def vector(self) -> Vector3D:
|
|
153
153
|
r"""The vector pointing from the base point to the tip point.
|
|
154
154
|
|
|
155
155
|
Examples
|