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.

Files changed (115) hide show
  1. manim/__init__.py +3 -6
  2. manim/__main__.py +18 -10
  3. manim/_config/__init__.py +5 -2
  4. manim/_config/cli_colors.py +12 -8
  5. manim/_config/default.cfg +1 -1
  6. manim/_config/logger_utils.py +9 -8
  7. manim/_config/utils.py +637 -449
  8. manim/animation/animation.py +9 -2
  9. manim/animation/composition.py +78 -40
  10. manim/animation/creation.py +12 -6
  11. manim/animation/fading.py +0 -1
  12. manim/animation/indication.py +10 -21
  13. manim/animation/movement.py +1 -2
  14. manim/animation/rotation.py +1 -1
  15. manim/animation/specialized.py +1 -1
  16. manim/animation/speedmodifier.py +7 -2
  17. manim/animation/transform_matching_parts.py +1 -1
  18. manim/camera/camera.py +13 -4
  19. manim/cli/cfg/group.py +18 -8
  20. manim/cli/checkhealth/checks.py +2 -0
  21. manim/cli/checkhealth/commands.py +2 -0
  22. manim/cli/default_group.py +13 -5
  23. manim/cli/init/commands.py +4 -1
  24. manim/cli/plugins/commands.py +3 -0
  25. manim/cli/render/commands.py +27 -20
  26. manim/cli/render/ease_of_access_options.py +4 -3
  27. manim/cli/render/global_options.py +9 -7
  28. manim/cli/render/output_options.py +6 -5
  29. manim/cli/render/render_options.py +13 -13
  30. manim/constants.py +54 -15
  31. manim/gui/gui.py +2 -0
  32. manim/mobject/geometry/arc.py +4 -4
  33. manim/mobject/geometry/boolean_ops.py +13 -9
  34. manim/mobject/geometry/line.py +16 -8
  35. manim/mobject/geometry/polygram.py +17 -5
  36. manim/mobject/geometry/tips.py +2 -2
  37. manim/mobject/graph.py +379 -106
  38. manim/mobject/graphing/coordinate_systems.py +17 -20
  39. manim/mobject/graphing/functions.py +14 -10
  40. manim/mobject/graphing/number_line.py +1 -1
  41. manim/mobject/mobject.py +175 -72
  42. manim/mobject/opengl/opengl_compatibility.py +2 -0
  43. manim/mobject/opengl/opengl_geometry.py +26 -1
  44. manim/mobject/opengl/opengl_image_mobject.py +2 -0
  45. manim/mobject/opengl/opengl_mobject.py +3 -0
  46. manim/mobject/opengl/opengl_point_cloud_mobject.py +2 -0
  47. manim/mobject/opengl/opengl_surface.py +2 -0
  48. manim/mobject/opengl/opengl_three_dimensions.py +2 -0
  49. manim/mobject/opengl/opengl_vectorized_mobject.py +19 -14
  50. manim/mobject/svg/brace.py +2 -0
  51. manim/mobject/svg/svg_mobject.py +10 -12
  52. manim/mobject/table.py +0 -1
  53. manim/mobject/text/code_mobject.py +2 -0
  54. manim/mobject/text/numbers.py +2 -0
  55. manim/mobject/text/tex_mobject.py +1 -1
  56. manim/mobject/text/text_mobject.py +43 -6
  57. manim/mobject/three_d/three_d_utils.py +4 -4
  58. manim/mobject/three_d/three_dimensions.py +4 -4
  59. manim/mobject/types/image_mobject.py +5 -1
  60. manim/mobject/types/point_cloud_mobject.py +2 -0
  61. manim/mobject/types/vectorized_mobject.py +124 -29
  62. manim/mobject/value_tracker.py +3 -3
  63. manim/mobject/vector_field.py +3 -1
  64. manim/plugins/__init__.py +15 -1
  65. manim/plugins/plugins_flags.py +11 -5
  66. manim/renderer/cairo_renderer.py +12 -2
  67. manim/renderer/opengl_renderer.py +2 -3
  68. manim/renderer/opengl_renderer_window.py +2 -0
  69. manim/renderer/shader_wrapper.py +2 -0
  70. manim/renderer/vectorized_mobject_rendering.py +5 -0
  71. manim/scene/scene.py +22 -6
  72. manim/scene/scene_file_writer.py +3 -1
  73. manim/scene/section.py +2 -0
  74. manim/scene/three_d_scene.py +5 -6
  75. manim/scene/vector_space_scene.py +21 -5
  76. manim/typing.py +567 -67
  77. manim/utils/bezier.py +9 -18
  78. manim/utils/caching.py +2 -0
  79. manim/utils/color/BS381.py +1 -0
  80. manim/utils/color/XKCD.py +1 -0
  81. manim/utils/color/core.py +31 -13
  82. manim/utils/commands.py +8 -1
  83. manim/utils/debug.py +0 -1
  84. manim/utils/deprecation.py +3 -2
  85. manim/utils/docbuild/__init__.py +17 -0
  86. manim/utils/docbuild/autoaliasattr_directive.py +197 -0
  87. manim/utils/docbuild/autocolor_directive.py +9 -4
  88. manim/utils/docbuild/manim_directive.py +18 -9
  89. manim/utils/docbuild/module_parsing.py +198 -0
  90. manim/utils/exceptions.py +6 -0
  91. manim/utils/family.py +2 -0
  92. manim/utils/family_ops.py +5 -0
  93. manim/utils/file_ops.py +6 -2
  94. manim/utils/hashing.py +2 -0
  95. manim/utils/ipython_magic.py +2 -0
  96. manim/utils/module_ops.py +2 -0
  97. manim/utils/opengl.py +14 -0
  98. manim/utils/parameter_parsing.py +31 -0
  99. manim/utils/paths.py +12 -20
  100. manim/utils/rate_functions.py +6 -8
  101. manim/utils/space_ops.py +81 -36
  102. manim/utils/testing/__init__.py +17 -0
  103. manim/utils/testing/frames_comparison.py +7 -5
  104. manim/utils/tex.py +124 -196
  105. manim/utils/tex_file_writing.py +2 -0
  106. manim/utils/tex_templates.py +1 -0
  107. {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/LICENSE.community +1 -1
  108. {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/METADATA +29 -35
  109. {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/RECORD +112 -112
  110. {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/WHEEL +1 -1
  111. manim/cli/new/__init__.py +0 -0
  112. manim/cli/new/group.py +0 -189
  113. manim/plugins/import_plugins.py +0 -43
  114. {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/LICENSE +0 -0
  115. {manim-0.18.0.dist-info → manim-0.18.1.dist-info}/entry_points.txt +0 -0
@@ -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
- @click.argument("file", type=Path, required=True)
34
- @click.argument("scene_names", required=False, nargs=-1)
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
- req_info = requests.get(manim_info_url, timeout=10)
127
- req_info.raise_for_status()
128
-
129
- stable = req_info.json()["info"]["version"]
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 click
4
- from cloup import option, option_group
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=click.Choice(
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 click
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
- if TYPE_CHECKING:
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: OptionGroupDecorator = option_group(
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=click.Choice(
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 click
4
- from cloup import option, option_group
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=click.IntRange(0, 9),
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=click.Path(),
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=click.Path(),
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 click
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=click.Choice(["png", "gif", "mp4", "webm", "mov"], case_sensitive=False),
59
+ type=Choice(["png", "gif", "mp4", "webm", "mov"], case_sensitive=False),
59
60
  default=None,
60
61
  ),
61
- option("-s", "--save_last_frame", is_flag=True, default=None),
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=click.Choice(
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=click.Choice(
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 Vector3
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: Vector3 = np.array((0.0, 0.0, 0.0))
126
+ ORIGIN: Vector3D = np.array((0.0, 0.0, 0.0))
126
127
  """The center of the coordinate system."""
127
128
 
128
- UP: Vector3 = np.array((0.0, 1.0, 0.0))
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: Vector3 = np.array((0.0, -1.0, 0.0))
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: Vector3 = np.array((1.0, 0.0, 0.0))
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: Vector3 = np.array((-1.0, 0.0, 0.0))
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: Vector3 = np.array((0.0, 0.0, -1.0))
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: Vector3 = np.array((0.0, 0.0, 1.0))
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: Vector3 = np.array((1.0, 0.0, 0.0))
148
- Y_AXIS: Vector3 = np.array((0.0, 1.0, 0.0))
149
- Z_AXIS: Vector3 = np.array((0.0, 0.0, 1.0))
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: Vector3 = UP + LEFT
153
+ UL: Vector3D = UP + LEFT
153
154
  """One step up plus one step left."""
154
155
 
155
- UR: Vector3 = UP + RIGHT
156
+ UR: Vector3D = UP + RIGHT
156
157
  """One step up plus one step right."""
157
158
 
158
- DL: Vector3 = DOWN + LEFT
159
+ DL: Vector3D = DOWN + LEFT
159
160
  """One step down plus one step left."""
160
161
 
161
- DR: Vector3 = DOWN + RIGHT
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
@@ -13,6 +13,8 @@ except ImportError:
13
13
  from .. import __version__, config
14
14
  from ..utils.module_ops import scene_classes_from_file
15
15
 
16
+ __all__ = ["configure_pygui"]
17
+
16
18
  if dearpygui_imported:
17
19
  dpg.create_context()
18
20
  window = dpg.generate_uuid()
@@ -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, Vector
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: Vector = OUT,
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: Vector = 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
- from manim.typing import Point2D_Array
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
- ) -> list[np.ndarray]:
30
- """Converts an iterable with coordinates in 2d to 3d by adding
31
- :attr:`z_dim` as the z coordinate.
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 which has the coordinates.
40
+ An iterable of points.
37
41
  z_dim:
38
- The default value of z coordinate.
42
+ Default value for the Z coordinate.
39
43
 
40
44
  Returns
41
45
  -------
42
- Point2D_Array
43
- A list of array converted to 3d.
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()
@@ -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 manim.typing import Point2D, Point3D, Vector
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: Vector | None = None,
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) -> Vector:
167
+ def get_vector(self) -> Vector3D:
167
168
  return self.get_end() - self.get_start()
168
169
 
169
- def get_unit_vector(self) -> Vector:
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) -> Vector:
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) -> Vector:
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__(self, direction: Vector = RIGHT, buff: float = 0, **kwargs) -> None:
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
- if grid_xstep is not None:
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
- if grid_ystep is not None:
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):
@@ -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, Vector
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) -> Vector:
152
+ def vector(self) -> Vector3D:
153
153
  r"""The vector pointing from the base point to the tip point.
154
154
 
155
155
  Examples