Skip to content

Commit db7b4a6

Browse files
committed
Merge branch 'main' of https://github.com/ManimCommunity/manim into iterable-vgroup
2 parents afe1810 + 1aad0c7 commit db7b4a6

File tree

17 files changed

+310
-111
lines changed

17 files changed

+310
-111
lines changed

.flake8

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Exclude the grpc generated code
33
exclude = ./manim/grpc/gen/*, __pycache__,.git,
44
per-file-ignores = __init__.py:F401
5-
max-complexity = 15
5+
max-complexity = 29
66
max-line-length = 88
77
statistics = True
88
# Prevents some flake8-rst-docstrings errors
@@ -27,9 +27,6 @@ extend-ignore = E203, W503, D202, D212, D213, D404
2727
# Plug-in: flake8-simplify
2828
SIM105, SIM106, SIM119,
2929

30-
# Plug-in: flake8-comprehensions
31-
C901
32-
3330
# Plug-in: flake8-pytest-style
3431
PT001, PT004, PT006, PT011, PT018, PT022, PT023,
3532

manim/__main__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from __future__ import annotations
22

3-
import sys
4-
53
import click
64
import cloup
75

manim/mobject/geometry/line.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from typing import TYPE_CHECKING
1818

1919
import numpy as np
20-
from typing_extensions import Self
2120

2221
from manim import config
2322
from manim.constants import *
@@ -31,6 +30,8 @@
3130
from manim.utils.space_ops import angle_of_vector, line_intersection, normalize
3231

3332
if TYPE_CHECKING:
33+
from typing_extensions import Self
34+
3435
from manim.typing import Point2D, Point3D, Vector3D
3536
from manim.utils.color import ParsableManimColor
3637

@@ -659,7 +660,9 @@ def construct(self):
659660
self.add(plane, vector_1, vector_2)
660661
"""
661662

662-
def __init__(self, direction: Vector3D = RIGHT, buff: float = 0, **kwargs) -> None:
663+
def __init__(
664+
self, direction: Point2D | Point3D = RIGHT, buff: float = 0, **kwargs
665+
) -> None:
663666
self.buff = buff
664667
if len(direction) == 2:
665668
direction = np.hstack([direction, 0])

manim/mobject/mobject.py

Lines changed: 80 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ def has_time_based_updater(self) -> bool:
882882
883883
Returns
884884
-------
885-
class:`bool`
885+
:class:`bool`
886886
``True`` if at least one updater uses the ``dt`` parameter, ``False``
887887
otherwise.
888888
@@ -1905,7 +1905,17 @@ def fade(self, darkness: float = 0.5, family: bool = True) -> Self:
19051905
return self
19061906

19071907
def get_color(self) -> ManimColor:
1908-
"""Returns the color of the :class:`~.Mobject`"""
1908+
"""Returns the color of the :class:`~.Mobject`
1909+
1910+
Examples
1911+
--------
1912+
::
1913+
1914+
>>> from manim import Square, RED
1915+
>>> Square(color=RED).get_color() == RED
1916+
True
1917+
1918+
"""
19091919
return self.color
19101920

19111921
##
@@ -2700,13 +2710,13 @@ def push_self_into_submobjects(self) -> Self:
27002710

27012711
def add_n_more_submobjects(self, n: int) -> Self | None:
27022712
if n == 0:
2703-
return
2713+
return None
27042714

27052715
curr = len(self.submobjects)
27062716
if curr == 0:
27072717
# If empty, simply add n point mobjects
27082718
self.submobjects = [self.get_point_mobject() for k in range(n)]
2709-
return
2719+
return None
27102720

27112721
target = curr + n
27122722
# TODO, factor this out to utils so as to reuse
@@ -2761,7 +2771,6 @@ def interpolate_color(self, mobject1: Mobject, mobject2: Mobject, alpha: float):
27612771
def become(
27622772
self,
27632773
mobject: Mobject,
2764-
copy_submobjects: bool = True,
27652774
match_height: bool = False,
27662775
match_width: bool = False,
27672776
match_depth: bool = False,
@@ -2774,20 +2783,25 @@ def become(
27742783
.. note::
27752784
27762785
If both match_height and match_width are ``True`` then the transformed :class:`~.Mobject`
2777-
will match the height first and then the width
2786+
will match the height first and then the width.
27782787
27792788
Parameters
27802789
----------
27812790
match_height
2782-
If ``True``, then the transformed :class:`~.Mobject` will match the height of the original
2791+
Whether or not to preserve the height of the original
2792+
:class:`~.Mobject`.
27832793
match_width
2784-
If ``True``, then the transformed :class:`~.Mobject` will match the width of the original
2794+
Whether or not to preserve the width of the original
2795+
:class:`~.Mobject`.
27852796
match_depth
2786-
If ``True``, then the transformed :class:`~.Mobject` will match the depth of the original
2797+
Whether or not to preserve the depth of the original
2798+
:class:`~.Mobject`.
27872799
match_center
2788-
If ``True``, then the transformed :class:`~.Mobject` will match the center of the original
2800+
Whether or not to preserve the center of the original
2801+
:class:`~.Mobject`.
27892802
stretch
2790-
If ``True``, then the transformed :class:`~.Mobject` will stretch to fit the proportions of the original
2803+
Whether or not to stretch the target mobject to match the
2804+
the proportions of the original :class:`~.Mobject`.
27912805
27922806
Examples
27932807
--------
@@ -2801,8 +2815,62 @@ def construct(self):
28012815
self.wait(0.5)
28022816
circ.become(square)
28032817
self.wait(0.5)
2804-
"""
28052818
2819+
2820+
The following examples illustrate how mobject measurements
2821+
change when using the ``match_...`` and ``stretch`` arguments.
2822+
We start with a rectangle that is 2 units high and 4 units wide,
2823+
which we want to turn into a circle of radius 3::
2824+
2825+
>>> from manim import Rectangle, Circle
2826+
>>> import numpy as np
2827+
>>> rect = Rectangle(height=2, width=4)
2828+
>>> circ = Circle(radius=3)
2829+
2830+
With ``stretch=True``, the target circle is deformed to match
2831+
the proportions of the rectangle, which results in the target
2832+
mobject being an ellipse with height 2 and width 4. We can
2833+
check that the resulting points satisfy the ellipse equation
2834+
:math:`x^2/a^2 + y^2/b^2 = 1` with :math:`a = 4/2` and :math:`b = 2/2`
2835+
being the semi-axes::
2836+
2837+
>>> result = rect.copy().become(circ, stretch=True)
2838+
>>> result.height, result.width
2839+
(2.0, 4.0)
2840+
>>> ellipse_eq = np.sum(result.get_anchors()**2 * [1/4, 1, 0], axis=1)
2841+
>>> np.allclose(ellipse_eq, 1)
2842+
True
2843+
2844+
With ``match_height=True`` and ``match_width=True`` the circle is
2845+
scaled such that the height or the width of the rectangle will
2846+
be preserved, respectively.
2847+
The points of the resulting mobject satisfy the circle equation
2848+
:math:`x^2 + y^2 = r^2` for the corresponding radius :math:`r`::
2849+
2850+
>>> result = rect.copy().become(circ, match_height=True)
2851+
>>> result.height, result.width
2852+
(2.0, 2.0)
2853+
>>> circle_eq = np.sum(result.get_anchors()**2, axis=1)
2854+
>>> np.allclose(circle_eq, 1)
2855+
True
2856+
>>> result = rect.copy().become(circ, match_width=True)
2857+
>>> result.height, result.width
2858+
(4.0, 4.0)
2859+
>>> circle_eq = np.sum(result.get_anchors()**2, axis=1)
2860+
>>> np.allclose(circle_eq, 2**2)
2861+
True
2862+
2863+
With ``match_center=True``, the resulting mobject is moved such that
2864+
its center is the same as the center of the original mobject::
2865+
2866+
>>> rect = rect.shift(np.array([0, 1, 0]))
2867+
>>> np.allclose(rect.get_center(), circ.get_center())
2868+
False
2869+
>>> result = rect.copy().become(circ, match_center=True)
2870+
>>> np.allclose(rect.get_center(), result.get_center())
2871+
True
2872+
"""
2873+
mobject = mobject.copy()
28062874
if stretch:
28072875
mobject.stretch_to_fit_height(self.height)
28082876
mobject.stretch_to_fit_width(self.width)

manim/mobject/opengl/opengl_geometry.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
)
2424

2525
DEFAULT_DOT_RADIUS = 0.08
26-
DEFAULT_SMALL_DOT_RADIUS = 0.04
2726
DEFAULT_DASH_LENGTH = 0.05
2827
DEFAULT_ARROW_TIP_LENGTH = 0.35
2928
DEFAULT_ARROW_TIP_WIDTH = 0.35

manim/mobject/svg/svg_mobject.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -510,17 +510,15 @@ def handle_commands(self) -> None:
510510
all_points: list[np.ndarray] = []
511511
last_move = None
512512
curve_start = None
513+
last_true_move = None
513514

514-
# These lambdas behave the same as similar functions in
515-
# vectorized_mobject, except they add to a list of points instead
516-
# of updating this Mobject's numpy array of points. This way,
517-
# we don't observe O(n^2) behavior for complex paths due to
518-
# numpy's need to re-allocate memory on every append.
519-
def move_pen(pt):
520-
nonlocal last_move, curve_start
515+
def move_pen(pt, *, true_move: bool = False):
516+
nonlocal last_move, curve_start, last_true_move
521517
last_move = pt
522518
if curve_start is None:
523519
curve_start = last_move
520+
if true_move:
521+
last_true_move = last_move
524522

525523
if self.n_points_per_curve == 4:
526524

@@ -568,7 +566,7 @@ def add_line(start, end):
568566
for segment in self.path_obj:
569567
segment_class = segment.__class__
570568
if segment_class == se.Move:
571-
move_pen(_convert_point_to_3d(*segment.end))
569+
move_pen(_convert_point_to_3d(*segment.end), true_move=True)
572570
elif segment_class == se.Line:
573571
add_line(last_move, _convert_point_to_3d(*segment.end))
574572
elif segment_class == se.QuadraticBezier:
@@ -588,8 +586,8 @@ def add_line(start, end):
588586
# If the SVG path naturally ends at the beginning of the curve,
589587
# we do *not* need to draw a closing line. To account for floating
590588
# point precision, we use a small value to compare the two points.
591-
if abs(np.linalg.norm(last_move - curve_start)) > 0.0001:
592-
add_line(last_move, curve_start)
589+
if abs(np.linalg.norm(last_move - last_true_move)) > 0.0001:
590+
add_line(last_move, last_true_move)
593591
curve_start = None
594592
else:
595593
raise AssertionError(f"Not implemented: {segment_class}")

manim/mobject/table.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ def construct(self):
7474
from manim.mobject.text.tex_mobject import MathTex
7575
from manim.mobject.text.text_mobject import Paragraph
7676

77-
from .. import config
7877
from ..animation.animation import Animation
7978
from ..animation.composition import AnimationGroup
8079
from ..animation.creation import Create, Write

manim/mobject/text/tex_mobject.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from manim.constants import *
3535
from manim.mobject.geometry.line import Line
3636
from manim.mobject.svg.svg_mobject import SVGMobject
37-
from manim.mobject.types.vectorized_mobject import VectorizedPoint, VGroup, VMobject
37+
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
3838
from manim.utils.tex import TexTemplate
3939
from manim.utils.tex_file_writing import tex_to_svg_file
4040

0 commit comments

Comments
 (0)