mirror of
https://github.com/ManimCommunity/manim.git
synced 2026-06-22 10:01:47 +00:00
Add VectorNDLike type aliases (#4068)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
7eb88562c2
commit
d18dc8f89b
15 changed files with 317 additions and 229 deletions
|
|
@ -85,14 +85,8 @@ typed as a :class:`~.Point3D`, because it represents a direction along
|
|||
which to shift a :class:`~.Mobject`, not a position in space.
|
||||
|
||||
As a general rule, if a parameter is called ``direction`` or ``axis``,
|
||||
it should be type hinted as some form of :class:`~.VectorND`.
|
||||
|
||||
.. warning::
|
||||
|
||||
This is not always true. For example, as of Manim 0.18.0, the direction
|
||||
parameter of the :class:`.Vector` Mobject should be
|
||||
``Point2DLike | Point3DLike``, as it can also accept ``tuple[float, float]``
|
||||
and ``tuple[float, float, float]``.
|
||||
it should be type hinted as some form of :class:`~.VectorND` or
|
||||
:class:`~.VectorNDLike`.
|
||||
|
||||
Colors
|
||||
------
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ if TYPE_CHECKING:
|
|||
Point3D,
|
||||
Point3DLike,
|
||||
QuadraticSpline,
|
||||
Vector3D,
|
||||
Vector3DLike,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -99,12 +99,12 @@ class TipableVMobject(VMobject, metaclass=ConvertToOpenGL):
|
|||
def __init__(
|
||||
self,
|
||||
tip_length: float = DEFAULT_ARROW_TIP_LENGTH,
|
||||
normal_vector: Vector3D = OUT,
|
||||
normal_vector: Vector3DLike = OUT,
|
||||
tip_style: dict = {},
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
self.tip_length: float = tip_length
|
||||
self.normal_vector: Vector3D = normal_vector
|
||||
self.normal_vector = normal_vector
|
||||
self.tip_style: dict = tip_style
|
||||
super().__init__(**kwargs)
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ if TYPE_CHECKING:
|
|||
|
||||
from typing_extensions import Literal, Self, TypeAlias
|
||||
|
||||
from manim.typing import Point2DLike, Point3D, Point3DLike, Vector3D
|
||||
from manim.typing import Point3D, Point3DLike, Vector2DLike, Vector3D, Vector3DLike
|
||||
from manim.utils.color import ParsableManimColor
|
||||
|
||||
from ..matrix import Matrix # Avoid circular import
|
||||
|
|
@ -175,7 +175,7 @@ class Line(TipableVMobject):
|
|||
def _pointify(
|
||||
self,
|
||||
mob_or_point: Mobject | Point3DLike,
|
||||
direction: Vector3D | None = None,
|
||||
direction: Vector3DLike | None = None,
|
||||
) -> Point3D:
|
||||
"""Transforms a mobject into its corresponding point. Does nothing if a point is passed.
|
||||
|
||||
|
|
@ -738,7 +738,7 @@ class Vector(Arrow):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
direction: Point2DLike | Point3DLike = RIGHT,
|
||||
direction: Vector2DLike | Vector3DLike = RIGHT,
|
||||
buff: float = 0,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ if TYPE_CHECKING:
|
|||
Point3D,
|
||||
Point3DLike,
|
||||
Vector3D,
|
||||
Vector3DLike,
|
||||
)
|
||||
|
||||
LineType = TypeVar("LineType", bound=Line)
|
||||
|
|
@ -353,8 +354,8 @@ class CoordinateSystem:
|
|||
self,
|
||||
label: float | str | VMobject,
|
||||
axis: Mobject,
|
||||
edge: Vector3D,
|
||||
direction: Vector3D,
|
||||
edge: Vector3DLike,
|
||||
direction: Vector3DLike,
|
||||
buff: float = SMALL_BUFF,
|
||||
) -> Mobject:
|
||||
"""Gets the label for an axis.
|
||||
|
|
@ -2432,7 +2433,7 @@ class ThreeDAxes(Axes):
|
|||
y_length: float | None = config.frame_height + 2.5,
|
||||
z_length: float | None = config.frame_height - 1.5,
|
||||
z_axis_config: dict[str, Any] | None = None,
|
||||
z_normal: Vector3D = DOWN,
|
||||
z_normal: Vector3DLike = DOWN,
|
||||
num_axis_pieces: int = 20,
|
||||
light_source: Point3DLike = 9 * DOWN + 7 * LEFT + 10 * OUT,
|
||||
# opengl stuff (?)
|
||||
|
|
@ -2519,11 +2520,11 @@ class ThreeDAxes(Axes):
|
|||
def get_y_axis_label(
|
||||
self,
|
||||
label: float | str | VMobject,
|
||||
edge: Vector3D = UR,
|
||||
direction: Vector3D = UR,
|
||||
edge: Vector3DLike = UR,
|
||||
direction: Vector3DLike = UR,
|
||||
buff: float = SMALL_BUFF,
|
||||
rotation: float = PI / 2,
|
||||
rotation_axis: Vector3D = OUT,
|
||||
rotation_axis: Vector3DLike = OUT,
|
||||
**kwargs: dict[str, Any],
|
||||
) -> Mobject:
|
||||
"""Generate a y-axis label.
|
||||
|
|
@ -2569,11 +2570,11 @@ class ThreeDAxes(Axes):
|
|||
def get_z_axis_label(
|
||||
self,
|
||||
label: float | str | VMobject,
|
||||
edge: Vector3D = OUT,
|
||||
direction: Vector3D = RIGHT,
|
||||
edge: Vector3DLike = OUT,
|
||||
direction: Vector3DLike = RIGHT,
|
||||
buff: float = SMALL_BUFF,
|
||||
rotation: float = PI / 2,
|
||||
rotation_axis: Vector3D = RIGHT,
|
||||
rotation_axis: Vector3DLike = RIGHT,
|
||||
**kwargs: Any,
|
||||
) -> Mobject:
|
||||
"""Generate a z-axis label.
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ if TYPE_CHECKING:
|
|||
Point3D,
|
||||
Point3DLike,
|
||||
Point3DLike_Array,
|
||||
Vector3D,
|
||||
Vector3DLike,
|
||||
)
|
||||
|
||||
from ..animation.animation import Animation
|
||||
|
|
@ -1204,7 +1204,7 @@ class Mobject:
|
|||
for mob in self.family_members_with_points():
|
||||
func(mob)
|
||||
|
||||
def shift(self, *vectors: Vector3D) -> Self:
|
||||
def shift(self, *vectors: Vector3DLike) -> Self:
|
||||
"""Shift by the given vectors.
|
||||
|
||||
Parameters
|
||||
|
|
@ -1275,14 +1275,14 @@ class Mobject:
|
|||
)
|
||||
return self
|
||||
|
||||
def rotate_about_origin(self, angle: float, axis: Vector3D = OUT, axes=[]) -> Self:
|
||||
def rotate_about_origin(self, angle: float, axis: Vector3DLike = OUT) -> Self:
|
||||
"""Rotates the :class:`~.Mobject` about the ORIGIN, which is at [0,0,0]."""
|
||||
return self.rotate(angle, axis, about_point=ORIGIN)
|
||||
|
||||
def rotate(
|
||||
self,
|
||||
angle: float,
|
||||
axis: Vector3D = OUT,
|
||||
axis: Vector3DLike = OUT,
|
||||
about_point: Point3DLike | None = None,
|
||||
**kwargs,
|
||||
) -> Self:
|
||||
|
|
@ -1350,7 +1350,7 @@ class Mobject:
|
|||
)
|
||||
return self
|
||||
|
||||
def flip(self, axis: Vector3D = UP, **kwargs) -> Self:
|
||||
def flip(self, axis: Vector3DLike = UP, **kwargs) -> Self:
|
||||
"""Flips/Mirrors an mobject about its center.
|
||||
|
||||
Examples
|
||||
|
|
@ -1470,7 +1470,7 @@ class Mobject:
|
|||
self,
|
||||
func: MultiMappingFunction,
|
||||
about_point: Point3DLike | None = None,
|
||||
about_edge: Vector3D | None = None,
|
||||
about_edge: Vector3DLike | None = None,
|
||||
) -> Self:
|
||||
if about_point is None:
|
||||
if about_edge is None:
|
||||
|
|
@ -1500,7 +1500,7 @@ class Mobject:
|
|||
return self
|
||||
|
||||
def align_on_border(
|
||||
self, direction: Vector3D, buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER
|
||||
self, direction: Vector3DLike, buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER
|
||||
) -> Self:
|
||||
"""Direction just needs to be a vector pointing towards side or
|
||||
corner in the 2d plane.
|
||||
|
|
@ -1517,7 +1517,7 @@ class Mobject:
|
|||
return self
|
||||
|
||||
def to_corner(
|
||||
self, corner: Vector3D = DL, buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER
|
||||
self, corner: Vector3DLike = DL, buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER
|
||||
) -> Self:
|
||||
"""Moves this :class:`~.Mobject` to the given corner of the screen.
|
||||
|
||||
|
|
@ -1545,7 +1545,7 @@ class Mobject:
|
|||
return self.align_on_border(corner, buff)
|
||||
|
||||
def to_edge(
|
||||
self, edge: Vector3D = LEFT, buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER
|
||||
self, edge: Vector3DLike = LEFT, buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER
|
||||
) -> Self:
|
||||
"""Moves this :class:`~.Mobject` to the given edge of the screen,
|
||||
without affecting its position in the other dimension.
|
||||
|
|
@ -1577,12 +1577,12 @@ class Mobject:
|
|||
def next_to(
|
||||
self,
|
||||
mobject_or_point: Mobject | Point3DLike,
|
||||
direction: Vector3D = RIGHT,
|
||||
direction: Vector3DLike = RIGHT,
|
||||
buff: float = DEFAULT_MOBJECT_TO_MOBJECT_BUFFER,
|
||||
aligned_edge: Vector3D = ORIGIN,
|
||||
aligned_edge: Vector3DLike = ORIGIN,
|
||||
submobject_to_align: Mobject | None = None,
|
||||
index_of_submobject_to_align: int | None = None,
|
||||
coor_mask: Vector3D = np.array([1, 1, 1]),
|
||||
coor_mask: Vector3DLike = np.array([1, 1, 1]),
|
||||
) -> Self:
|
||||
"""Move this :class:`~.Mobject` next to another's :class:`~.Mobject` or Point3D.
|
||||
|
||||
|
|
@ -1604,13 +1604,18 @@ class Mobject:
|
|||
self.add(d, c, s, t)
|
||||
|
||||
"""
|
||||
np_direction = np.asarray(direction)
|
||||
np_aligned_edge = np.asarray(aligned_edge)
|
||||
|
||||
if isinstance(mobject_or_point, Mobject):
|
||||
mob = mobject_or_point
|
||||
if index_of_submobject_to_align is not None:
|
||||
target_aligner = mob[index_of_submobject_to_align]
|
||||
else:
|
||||
target_aligner = mob
|
||||
target_point = target_aligner.get_critical_point(aligned_edge + direction)
|
||||
target_point = target_aligner.get_critical_point(
|
||||
np_aligned_edge + np_direction
|
||||
)
|
||||
else:
|
||||
target_point = mobject_or_point
|
||||
if submobject_to_align is not None:
|
||||
|
|
@ -1619,8 +1624,8 @@ class Mobject:
|
|||
aligner = self[index_of_submobject_to_align]
|
||||
else:
|
||||
aligner = self
|
||||
point_to_align = aligner.get_critical_point(aligned_edge - direction)
|
||||
self.shift((target_point - point_to_align + buff * direction) * coor_mask)
|
||||
point_to_align = aligner.get_critical_point(np_aligned_edge - np_direction)
|
||||
self.shift((target_point - point_to_align + buff * np_direction) * coor_mask)
|
||||
return self
|
||||
|
||||
def shift_onto_screen(self, **kwargs) -> Self:
|
||||
|
|
@ -1766,22 +1771,22 @@ class Mobject:
|
|||
"""Stretches the :class:`~.Mobject` to fit a depth, not keeping width/height proportional."""
|
||||
return self.rescale_to_fit(depth, 2, stretch=True, **kwargs)
|
||||
|
||||
def set_coord(self, value, dim: int, direction: Vector3D = ORIGIN) -> Self:
|
||||
def set_coord(self, value, dim: int, direction: Vector3DLike = ORIGIN) -> Self:
|
||||
curr = self.get_coord(dim, direction)
|
||||
shift_vect = np.zeros(self.dim)
|
||||
shift_vect[dim] = value - curr
|
||||
self.shift(shift_vect)
|
||||
return self
|
||||
|
||||
def set_x(self, x: float, direction: Vector3D = ORIGIN) -> Self:
|
||||
def set_x(self, x: float, direction: Vector3DLike = ORIGIN) -> Self:
|
||||
"""Set x value of the center of the :class:`~.Mobject` (``int`` or ``float``)"""
|
||||
return self.set_coord(x, 0, direction)
|
||||
|
||||
def set_y(self, y: float, direction: Vector3D = ORIGIN) -> Self:
|
||||
def set_y(self, y: float, direction: Vector3DLike = ORIGIN) -> Self:
|
||||
"""Set y value of the center of the :class:`~.Mobject` (``int`` or ``float``)"""
|
||||
return self.set_coord(y, 1, direction)
|
||||
|
||||
def set_z(self, z: float, direction: Vector3D = ORIGIN) -> Self:
|
||||
def set_z(self, z: float, direction: Vector3DLike = ORIGIN) -> Self:
|
||||
"""Set z value of the center of the :class:`~.Mobject` (``int`` or ``float``)"""
|
||||
return self.set_coord(z, 2, direction)
|
||||
|
||||
|
|
@ -1794,8 +1799,8 @@ class Mobject:
|
|||
def move_to(
|
||||
self,
|
||||
point_or_mobject: Point3DLike | Mobject,
|
||||
aligned_edge: Vector3D = ORIGIN,
|
||||
coor_mask: Vector3D = np.array([1, 1, 1]),
|
||||
aligned_edge: Vector3DLike = ORIGIN,
|
||||
coor_mask: Vector3DLike = np.array([1, 1, 1]),
|
||||
) -> Self:
|
||||
"""Move center of the :class:`~.Mobject` to certain Point3D."""
|
||||
if isinstance(point_or_mobject, Mobject):
|
||||
|
|
@ -2114,7 +2119,7 @@ class Mobject:
|
|||
else:
|
||||
return np.max(values)
|
||||
|
||||
def get_critical_point(self, direction: Vector3D) -> Point3D:
|
||||
def get_critical_point(self, direction: Vector3DLike) -> Point3D:
|
||||
"""Picture a box bounding the :class:`~.Mobject`. Such a box has
|
||||
9 'critical points': 4 corners, 4 edge center, the
|
||||
center. This returns one of them, along the given direction.
|
||||
|
|
@ -2143,11 +2148,11 @@ class Mobject:
|
|||
|
||||
# Pseudonyms for more general get_critical_point method
|
||||
|
||||
def get_edge_center(self, direction: Vector3D) -> Point3D:
|
||||
def get_edge_center(self, direction: Vector3DLike) -> Point3D:
|
||||
"""Get edge Point3Ds for certain direction."""
|
||||
return self.get_critical_point(direction)
|
||||
|
||||
def get_corner(self, direction: Vector3D) -> Point3D:
|
||||
def get_corner(self, direction: Vector3DLike) -> Point3D:
|
||||
"""Get corner Point3Ds for certain direction."""
|
||||
return self.get_critical_point(direction)
|
||||
|
||||
|
|
@ -2158,9 +2163,9 @@ class Mobject:
|
|||
def get_center_of_mass(self) -> Point3D:
|
||||
return np.apply_along_axis(np.mean, 0, self.get_all_points())
|
||||
|
||||
def get_boundary_point(self, direction: Vector3D) -> Point3D:
|
||||
def get_boundary_point(self, direction: Vector3DLike) -> Point3D:
|
||||
all_points = self.get_points_defining_boundary()
|
||||
index = np.argmax(np.dot(all_points, np.array(direction).T))
|
||||
index = np.argmax(np.dot(all_points, direction))
|
||||
return all_points[index]
|
||||
|
||||
def get_midpoint(self) -> Point3D:
|
||||
|
|
@ -2217,19 +2222,19 @@ class Mobject:
|
|||
dim,
|
||||
) - self.reduce_across_dimension(min, dim)
|
||||
|
||||
def get_coord(self, dim: int, direction: Vector3D = ORIGIN):
|
||||
def get_coord(self, dim: int, direction: Vector3DLike = ORIGIN) -> float:
|
||||
"""Meant to generalize ``get_x``, ``get_y`` and ``get_z``"""
|
||||
return self.get_extremum_along_dim(dim=dim, key=direction[dim])
|
||||
|
||||
def get_x(self, direction: Vector3D = ORIGIN) -> float:
|
||||
def get_x(self, direction: Vector3DLike = ORIGIN) -> float:
|
||||
"""Returns x Point3D of the center of the :class:`~.Mobject` as ``float``"""
|
||||
return self.get_coord(0, direction)
|
||||
|
||||
def get_y(self, direction: Vector3D = ORIGIN) -> float:
|
||||
def get_y(self, direction: Vector3DLike = ORIGIN) -> float:
|
||||
"""Returns y Point3D of the center of the :class:`~.Mobject` as ``float``"""
|
||||
return self.get_coord(1, direction)
|
||||
|
||||
def get_z(self, direction: Vector3D = ORIGIN) -> float:
|
||||
def get_z(self, direction: Vector3DLike = ORIGIN) -> float:
|
||||
"""Returns z Point3D of the center of the :class:`~.Mobject` as ``float``"""
|
||||
return self.get_coord(2, direction)
|
||||
|
||||
|
|
@ -2300,7 +2305,7 @@ class Mobject:
|
|||
return self.match_dim_size(mobject, 2, **kwargs)
|
||||
|
||||
def match_coord(
|
||||
self, mobject: Mobject, dim: int, direction: Vector3D = ORIGIN
|
||||
self, mobject: Mobject, dim: int, direction: Vector3DLike = ORIGIN
|
||||
) -> Self:
|
||||
"""Match the Point3Ds with the Point3Ds of another :class:`~.Mobject`."""
|
||||
return self.set_coord(
|
||||
|
|
@ -2324,7 +2329,7 @@ class Mobject:
|
|||
def align_to(
|
||||
self,
|
||||
mobject_or_point: Mobject | Point3DLike,
|
||||
direction: Vector3D = ORIGIN,
|
||||
direction: Vector3DLike = ORIGIN,
|
||||
) -> Self:
|
||||
"""Aligns mobject to another :class:`~.Mobject` in a certain direction.
|
||||
|
||||
|
|
@ -2431,7 +2436,7 @@ class Mobject:
|
|||
|
||||
def arrange(
|
||||
self,
|
||||
direction: Vector3D = RIGHT,
|
||||
direction: Vector3DLike = RIGHT,
|
||||
buff: float = DEFAULT_MOBJECT_TO_MOBJECT_BUFFER,
|
||||
center: bool = True,
|
||||
**kwargs,
|
||||
|
|
@ -2464,7 +2469,7 @@ class Mobject:
|
|||
rows: int | None = None,
|
||||
cols: int | None = None,
|
||||
buff: float | tuple[float, float] = MED_SMALL_BUFF,
|
||||
cell_alignment: Vector3D = ORIGIN,
|
||||
cell_alignment: Vector3DLike = ORIGIN,
|
||||
row_alignments: str | None = None, # "ucd"
|
||||
col_alignments: str | None = None, # "lcr"
|
||||
row_heights: Iterable[float | None] | None = None,
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ if TYPE_CHECKING:
|
|||
Point3DLike,
|
||||
Point3DLike_Array,
|
||||
Vector3D,
|
||||
Vector3DLike,
|
||||
)
|
||||
|
||||
TimeBasedUpdater: TypeAlias = Callable[["Mobject", float], object]
|
||||
|
|
@ -636,7 +637,7 @@ class OpenGLMobject:
|
|||
self,
|
||||
func: MultiMappingFunction,
|
||||
about_point: Point3DLike | None = None,
|
||||
about_edge: Vector3D | None = ORIGIN,
|
||||
about_edge: Vector3DLike | None = ORIGIN,
|
||||
works_on_bounding_box: bool = False,
|
||||
) -> Self:
|
||||
if about_point is None and about_edge is not None:
|
||||
|
|
@ -992,7 +993,7 @@ class OpenGLMobject:
|
|||
# Submobject organization
|
||||
|
||||
def arrange(
|
||||
self, direction: Vector3D = RIGHT, center: bool = True, **kwargs
|
||||
self, direction: Vector3DLike = RIGHT, center: bool = True, **kwargs
|
||||
) -> Self:
|
||||
"""Sorts :class:`~.OpenGLMobject` next to each other on screen.
|
||||
|
||||
|
|
@ -1022,7 +1023,7 @@ class OpenGLMobject:
|
|||
rows: int | None = None,
|
||||
cols: int | None = None,
|
||||
buff: float | tuple[float, float] = MED_SMALL_BUFF,
|
||||
cell_alignment: Vector3D = ORIGIN,
|
||||
cell_alignment: Vector3DLike = ORIGIN,
|
||||
row_alignments: str | None = None, # "ucd"
|
||||
col_alignments: str | None = None, # "lcr"
|
||||
row_heights: Sequence[float | None] | None = None,
|
||||
|
|
@ -1553,7 +1554,7 @@ class OpenGLMobject:
|
|||
|
||||
# Transforming operations
|
||||
|
||||
def shift(self, vector: Vector3D) -> Self:
|
||||
def shift(self, vector: Vector3DLike) -> Self:
|
||||
self.apply_points_function(
|
||||
lambda points: points + vector,
|
||||
about_edge=None,
|
||||
|
|
@ -1631,14 +1632,14 @@ class OpenGLMobject:
|
|||
self.apply_points_function(func, works_on_bounding_box=True, **kwargs)
|
||||
return self
|
||||
|
||||
def rotate_about_origin(self, angle: float, axis: Vector3D = OUT) -> Self:
|
||||
def rotate_about_origin(self, angle: float, axis: Vector3DLike = OUT) -> Self:
|
||||
return self.rotate(angle, axis, about_point=ORIGIN)
|
||||
|
||||
def rotate(
|
||||
self,
|
||||
angle: float,
|
||||
axis: Vector3D = OUT,
|
||||
about_point: Sequence[float] | None = None,
|
||||
axis: Vector3DLike = OUT,
|
||||
about_point: Point3DLike | None = None,
|
||||
**kwargs,
|
||||
) -> Self:
|
||||
"""Rotates the :class:`~.OpenGLMobject` about a certain point."""
|
||||
|
|
@ -1650,7 +1651,7 @@ class OpenGLMobject:
|
|||
)
|
||||
return self
|
||||
|
||||
def flip(self, axis: Vector3D = UP, **kwargs) -> Self:
|
||||
def flip(self, axis: Vector3DLike = UP, **kwargs) -> Self:
|
||||
"""Flips/Mirrors an mobject about its center.
|
||||
|
||||
Examples
|
||||
|
|
@ -1751,8 +1752,8 @@ class OpenGLMobject:
|
|||
|
||||
def wag(
|
||||
self,
|
||||
direction: Vector3D = RIGHT,
|
||||
axis: Vector3D = DOWN,
|
||||
direction: Vector3DLike = RIGHT,
|
||||
axis: Vector3DLike = DOWN,
|
||||
wag_factor: float = 1.0,
|
||||
) -> Self:
|
||||
for mob in self.family_members_with_points():
|
||||
|
|
@ -1778,7 +1779,7 @@ class OpenGLMobject:
|
|||
|
||||
def align_on_border(
|
||||
self,
|
||||
direction: Vector3D,
|
||||
direction: Vector3DLike,
|
||||
buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER,
|
||||
) -> Self:
|
||||
"""
|
||||
|
|
@ -1791,21 +1792,21 @@ class OpenGLMobject:
|
|||
0,
|
||||
)
|
||||
point_to_align = self.get_bounding_box_point(direction)
|
||||
shift_val = target_point - point_to_align - buff * np.array(direction)
|
||||
shift_val = target_point - point_to_align - buff * np.asarray(direction)
|
||||
shift_val = shift_val * abs(np.sign(direction))
|
||||
self.shift(shift_val)
|
||||
return self
|
||||
|
||||
def to_corner(
|
||||
self,
|
||||
corner: Vector3D = LEFT + DOWN,
|
||||
corner: Vector3DLike = LEFT + DOWN,
|
||||
buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER,
|
||||
) -> Self:
|
||||
return self.align_on_border(corner, buff)
|
||||
|
||||
def to_edge(
|
||||
self,
|
||||
edge: Vector3D = LEFT,
|
||||
edge: Vector3DLike = LEFT,
|
||||
buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER,
|
||||
) -> Self:
|
||||
return self.align_on_border(edge, buff)
|
||||
|
|
@ -1813,12 +1814,12 @@ class OpenGLMobject:
|
|||
def next_to(
|
||||
self,
|
||||
mobject_or_point: OpenGLMobject | Point3DLike,
|
||||
direction: Vector3D = RIGHT,
|
||||
direction: Vector3DLike = RIGHT,
|
||||
buff: float = DEFAULT_MOBJECT_TO_MOBJECT_BUFFER,
|
||||
aligned_edge: Vector3D = ORIGIN,
|
||||
aligned_edge: Vector3DLike = ORIGIN,
|
||||
submobject_to_align: OpenGLMobject | None = None,
|
||||
index_of_submobject_to_align: int | None = None,
|
||||
coor_mask: Point3DLike = np.array([1, 1, 1]),
|
||||
coor_mask: Vector3DLike = np.array([1, 1, 1]),
|
||||
) -> Self:
|
||||
"""Move this :class:`~.OpenGLMobject` next to another's :class:`~.OpenGLMobject` or coordinate.
|
||||
|
||||
|
|
@ -1840,6 +1841,9 @@ class OpenGLMobject:
|
|||
self.add(d, c, s, t)
|
||||
|
||||
"""
|
||||
np_direction = np.asarray(direction)
|
||||
np_aligned_edge = np.asarray(aligned_edge)
|
||||
|
||||
if isinstance(mobject_or_point, OpenGLMobject):
|
||||
mob = mobject_or_point
|
||||
if index_of_submobject_to_align is not None:
|
||||
|
|
@ -1847,7 +1851,7 @@ class OpenGLMobject:
|
|||
else:
|
||||
target_aligner = mob
|
||||
target_point = target_aligner.get_bounding_box_point(
|
||||
aligned_edge + direction,
|
||||
np_aligned_edge + np_direction,
|
||||
)
|
||||
else:
|
||||
target_point = mobject_or_point
|
||||
|
|
@ -1857,8 +1861,8 @@ class OpenGLMobject:
|
|||
aligner = self[index_of_submobject_to_align]
|
||||
else:
|
||||
aligner = self
|
||||
point_to_align = aligner.get_bounding_box_point(aligned_edge - direction)
|
||||
self.shift((target_point - point_to_align + buff * direction) * coor_mask)
|
||||
point_to_align = aligner.get_bounding_box_point(np_aligned_edge - np_direction)
|
||||
self.shift((target_point - point_to_align + buff * np_direction) * coor_mask)
|
||||
return self
|
||||
|
||||
def shift_onto_screen(self, **kwargs) -> Self:
|
||||
|
|
@ -1970,22 +1974,24 @@ class OpenGLMobject:
|
|||
|
||||
scale_to_fit_depth = set_depth
|
||||
|
||||
def set_coord(self, value: float, dim: int, direction: Vector3D = ORIGIN) -> Self:
|
||||
def set_coord(
|
||||
self, value: float, dim: int, direction: Vector3DLike = ORIGIN
|
||||
) -> Self:
|
||||
curr = self.get_coord(dim, direction)
|
||||
shift_vect = np.zeros(self.dim)
|
||||
shift_vect[dim] = value - curr
|
||||
self.shift(shift_vect)
|
||||
return self
|
||||
|
||||
def set_x(self, x: float, direction: Vector3D = ORIGIN) -> Self:
|
||||
def set_x(self, x: float, direction: Vector3DLike = ORIGIN) -> Self:
|
||||
"""Set x value of the center of the :class:`~.OpenGLMobject` (``int`` or ``float``)"""
|
||||
return self.set_coord(x, 0, direction)
|
||||
|
||||
def set_y(self, y: float, direction: Vector3D = ORIGIN) -> Self:
|
||||
def set_y(self, y: float, direction: Vector3DLike = ORIGIN) -> Self:
|
||||
"""Set y value of the center of the :class:`~.OpenGLMobject` (``int`` or ``float``)"""
|
||||
return self.set_coord(y, 1, direction)
|
||||
|
||||
def set_z(self, z: float, direction: Vector3D = ORIGIN) -> Self:
|
||||
def set_z(self, z: float, direction: Vector3DLike = ORIGIN) -> Self:
|
||||
"""Set z value of the center of the :class:`~.OpenGLMobject` (``int`` or ``float``)"""
|
||||
return self.set_coord(z, 2, direction)
|
||||
|
||||
|
|
@ -1998,8 +2004,8 @@ class OpenGLMobject:
|
|||
def move_to(
|
||||
self,
|
||||
point_or_mobject: Point3DLike | OpenGLMobject,
|
||||
aligned_edge: Vector3D = ORIGIN,
|
||||
coor_mask: Point3DLike = np.array([1, 1, 1]),
|
||||
aligned_edge: Vector3DLike = ORIGIN,
|
||||
coor_mask: Vector3DLike = np.array([1, 1, 1]),
|
||||
) -> Self:
|
||||
"""Move center of the :class:`~.OpenGLMobject` to certain coordinate."""
|
||||
if isinstance(point_or_mobject, OpenGLMobject):
|
||||
|
|
@ -2252,16 +2258,16 @@ class OpenGLMobject:
|
|||
|
||||
# Getters
|
||||
|
||||
def get_bounding_box_point(self, direction: Vector3D) -> Point3D:
|
||||
def get_bounding_box_point(self, direction: Vector3DLike) -> Point3D:
|
||||
bb = self.get_bounding_box()
|
||||
indices = (np.sign(direction) + 1).astype(int)
|
||||
return np.array([bb[indices[i]][i] for i in range(3)])
|
||||
|
||||
def get_edge_center(self, direction: Vector3D) -> Point3D:
|
||||
def get_edge_center(self, direction: Vector3DLike) -> Point3D:
|
||||
"""Get edge coordinates for certain direction."""
|
||||
return self.get_bounding_box_point(direction)
|
||||
|
||||
def get_corner(self, direction: Vector3D) -> Point3D:
|
||||
def get_corner(self, direction: Vector3DLike) -> Point3D:
|
||||
"""Get corner coordinates for certain direction."""
|
||||
return self.get_bounding_box_point(direction)
|
||||
|
||||
|
|
@ -2272,23 +2278,24 @@ class OpenGLMobject:
|
|||
def get_center_of_mass(self) -> Point3D:
|
||||
return self.get_all_points().mean(0)
|
||||
|
||||
def get_boundary_point(self, direction: Vector3D) -> Point3D:
|
||||
def get_boundary_point(self, direction: Vector3DLike) -> Point3D:
|
||||
all_points = self.get_all_points()
|
||||
boundary_directions = all_points - self.get_center()
|
||||
norms = np.linalg.norm(boundary_directions, axis=1)
|
||||
boundary_directions /= np.repeat(norms, 3).reshape((len(norms), 3))
|
||||
index = np.argmax(np.dot(boundary_directions, np.array(direction).T))
|
||||
index = np.argmax(np.dot(boundary_directions, direction))
|
||||
return all_points[index]
|
||||
|
||||
def get_continuous_bounding_box_point(self, direction: Vector3D) -> Point3D:
|
||||
def get_continuous_bounding_box_point(self, direction: Vector3DLike) -> Point3D:
|
||||
dl, center, ur = self.get_bounding_box()
|
||||
corner_vect = ur - center
|
||||
return center + direction / np.max(
|
||||
np_direction = np.asarray(direction)
|
||||
return center + np_direction / np.max(
|
||||
np.abs(
|
||||
np.true_divide(
|
||||
direction,
|
||||
np_direction,
|
||||
corner_vect,
|
||||
out=np.zeros(len(direction)),
|
||||
out=np.zeros(len(np_direction)),
|
||||
where=((corner_vect) != 0),
|
||||
),
|
||||
),
|
||||
|
|
@ -2334,19 +2341,19 @@ class OpenGLMobject:
|
|||
"""Returns the depth of the mobject."""
|
||||
return self.length_over_dim(2)
|
||||
|
||||
def get_coord(self, dim: int, direction: Vector3D = ORIGIN) -> ManimFloat:
|
||||
def get_coord(self, dim: int, direction: Vector3DLike = ORIGIN) -> ManimFloat:
|
||||
"""Meant to generalize ``get_x``, ``get_y`` and ``get_z``"""
|
||||
return self.get_bounding_box_point(direction)[dim]
|
||||
|
||||
def get_x(self, direction: Vector3D = ORIGIN) -> ManimFloat:
|
||||
def get_x(self, direction: Vector3DLike = ORIGIN) -> ManimFloat:
|
||||
"""Returns x coordinate of the center of the :class:`~.OpenGLMobject` as ``float``"""
|
||||
return self.get_coord(0, direction)
|
||||
|
||||
def get_y(self, direction: Vector3D = ORIGIN) -> ManimFloat:
|
||||
def get_y(self, direction: Vector3DLike = ORIGIN) -> ManimFloat:
|
||||
"""Returns y coordinate of the center of the :class:`~.OpenGLMobject` as ``float``"""
|
||||
return self.get_coord(1, direction)
|
||||
|
||||
def get_z(self, direction: Vector3D = ORIGIN) -> ManimFloat:
|
||||
def get_z(self, direction: Vector3DLike = ORIGIN) -> ManimFloat:
|
||||
"""Returns z coordinate of the center of the :class:`~.OpenGLMobject` as ``float``"""
|
||||
return self.get_coord(2, direction)
|
||||
|
||||
|
|
@ -2412,7 +2419,7 @@ class OpenGLMobject:
|
|||
return self.match_dim_size(mobject, 2, **kwargs)
|
||||
|
||||
def match_coord(
|
||||
self, mobject: OpenGLMobject, dim: int, direction: Vector3D = ORIGIN
|
||||
self, mobject: OpenGLMobject, dim: int, direction: Vector3DLike = ORIGIN
|
||||
) -> Self:
|
||||
"""Match the coordinates with the coordinates of another :class:`~.OpenGLMobject`."""
|
||||
return self.set_coord(
|
||||
|
|
@ -2421,22 +2428,22 @@ class OpenGLMobject:
|
|||
direction=direction,
|
||||
)
|
||||
|
||||
def match_x(self, mobject: OpenGLMobject, direction: Vector3D = ORIGIN) -> Self:
|
||||
def match_x(self, mobject: OpenGLMobject, direction: Vector3DLike = ORIGIN) -> Self:
|
||||
"""Match x coord. to the x coord. of another :class:`~.OpenGLMobject`."""
|
||||
return self.match_coord(mobject, 0, direction)
|
||||
|
||||
def match_y(self, mobject: OpenGLMobject, direction: Vector3D = ORIGIN) -> Self:
|
||||
def match_y(self, mobject: OpenGLMobject, direction: Vector3DLike = ORIGIN) -> Self:
|
||||
"""Match y coord. to the x coord. of another :class:`~.OpenGLMobject`."""
|
||||
return self.match_coord(mobject, 1, direction)
|
||||
|
||||
def match_z(self, mobject: OpenGLMobject, direction: Vector3D = ORIGIN) -> Self:
|
||||
def match_z(self, mobject: OpenGLMobject, direction: Vector3DLike = ORIGIN) -> Self:
|
||||
"""Match z coord. to the x coord. of another :class:`~.OpenGLMobject`."""
|
||||
return self.match_coord(mobject, 2, direction)
|
||||
|
||||
def align_to(
|
||||
self,
|
||||
mobject_or_point: OpenGLMobject | Point3DLike,
|
||||
direction: Vector3D = ORIGIN,
|
||||
direction: Vector3DLike = ORIGIN,
|
||||
) -> Self:
|
||||
"""
|
||||
Examples:
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ from ...utils.color import BLACK
|
|||
from ..svg.svg_mobject import VMobjectFromSVGPath
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from manim.typing import Point3D, Point3DLike, Vector3D
|
||||
from manim.typing import Point3D, Point3DLike, Vector3D, Vector3DLike
|
||||
from manim.utils.color.core import ParsableManimColor
|
||||
|
||||
|
||||
|
|
@ -70,7 +70,7 @@ class Brace(VMobjectFromSVGPath):
|
|||
def __init__(
|
||||
self,
|
||||
mobject: Mobject,
|
||||
direction: Point3DLike = DOWN,
|
||||
direction: Vector3DLike = DOWN,
|
||||
buff: float = 0.2,
|
||||
sharpness: float = 2,
|
||||
stroke_width: float = 0,
|
||||
|
|
@ -233,7 +233,7 @@ class BraceLabel(VMobject, metaclass=ConvertToOpenGL):
|
|||
self,
|
||||
obj: Mobject,
|
||||
text: str,
|
||||
brace_direction: Point3DLike = DOWN,
|
||||
brace_direction: Vector3DLike = DOWN,
|
||||
label_constructor: type[SingleStringMathTex | Text] = MathTex,
|
||||
font_size: float = DEFAULT_FONT_SIZE,
|
||||
buff: float = 0.2,
|
||||
|
|
@ -376,7 +376,7 @@ class BraceBetweenPoints(Brace):
|
|||
self,
|
||||
point_1: Point3DLike,
|
||||
point_2: Point3DLike,
|
||||
direction: Point3DLike = ORIGIN,
|
||||
direction: Vector3DLike = ORIGIN,
|
||||
**kwargs: Any,
|
||||
):
|
||||
if all(direction == ORIGIN):
|
||||
|
|
@ -443,7 +443,7 @@ class ArcBrace(Brace):
|
|||
def __init__(
|
||||
self,
|
||||
arc: Arc | None = None,
|
||||
direction: Point3DLike = RIGHT,
|
||||
direction: Vector3DLike = RIGHT,
|
||||
**kwargs: Any,
|
||||
):
|
||||
if arc is None:
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from manim.mobject.text.tex_mobject import MathTex, SingleStringMathTex, Tex
|
|||
from manim.mobject.text.text_mobject import Text
|
||||
from manim.mobject.types.vectorized_mobject import VMobject
|
||||
from manim.mobject.value_tracker import ValueTracker
|
||||
from manim.typing import Point3DLike
|
||||
from manim.typing import Vector3DLike
|
||||
|
||||
string_to_mob_map: dict[str, VMobject] = {}
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ class DecimalNumber(VMobject, metaclass=ConvertToOpenGL):
|
|||
unit: str | None = None, # Aligned to bottom unless it starts with "^"
|
||||
unit_buff_per_font_unit: float = 0,
|
||||
include_background_rectangle: bool = False,
|
||||
edge_to_fix: Point3DLike = LEFT,
|
||||
edge_to_fix: Vector3DLike = LEFT,
|
||||
font_size: float = DEFAULT_FONT_SIZE,
|
||||
stroke_width: float = 0,
|
||||
fill_opacity: float = 1.0,
|
||||
|
|
|
|||
|
|
@ -2,9 +2,6 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from manim.typing import Point3DLike, Vector3D
|
||||
from manim.utils.color import BLUE, BLUE_D, BLUE_E, LIGHT_GREY, WHITE, interpolate_color
|
||||
|
||||
__all__ = [
|
||||
"ThreeDVMobject",
|
||||
"Surface",
|
||||
|
|
@ -20,7 +17,7 @@ __all__ = [
|
|||
]
|
||||
|
||||
from collections.abc import Iterable, Sequence
|
||||
from typing import Any, Callable
|
||||
from typing import TYPE_CHECKING, Any, Callable
|
||||
|
||||
import numpy as np
|
||||
from typing_extensions import Self
|
||||
|
|
@ -34,12 +31,21 @@ from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
|
|||
from manim.mobject.opengl.opengl_mobject import OpenGLMobject
|
||||
from manim.mobject.types.vectorized_mobject import VectorizedPoint, VGroup, VMobject
|
||||
from manim.utils.color import (
|
||||
BLUE,
|
||||
BLUE_D,
|
||||
BLUE_E,
|
||||
LIGHT_GREY,
|
||||
WHITE,
|
||||
ManimColor,
|
||||
ParsableManimColor,
|
||||
interpolate_color,
|
||||
)
|
||||
from manim.utils.iterables import tuplify
|
||||
from manim.utils.space_ops import normalize, perpendicular_bisector, z_to_vector
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from manim.typing import Point3D, Point3DLike, Vector3DLike
|
||||
|
||||
|
||||
class ThreeDVMobject(VMobject, metaclass=ConvertToOpenGL):
|
||||
def __init__(self, shade_in_3d: bool = True, **kwargs):
|
||||
|
|
@ -970,8 +976,8 @@ class Line3D(Cylinder):
|
|||
def pointify(
|
||||
self,
|
||||
mob_or_point: Mobject | Point3DLike,
|
||||
direction: Vector3D = None,
|
||||
) -> np.ndarray:
|
||||
direction: Vector3DLike | None = None,
|
||||
) -> Point3D:
|
||||
"""Gets a point representing the center of the :class:`Mobjects <.Mobject>`.
|
||||
|
||||
Parameters
|
||||
|
|
@ -1018,7 +1024,7 @@ class Line3D(Cylinder):
|
|||
def parallel_to(
|
||||
cls,
|
||||
line: Line3D,
|
||||
point: Vector3D = ORIGIN,
|
||||
point: Point3DLike = ORIGIN,
|
||||
length: float = 5,
|
||||
**kwargs,
|
||||
) -> Line3D:
|
||||
|
|
@ -1054,11 +1060,11 @@ class Line3D(Cylinder):
|
|||
line2 = Line3D.parallel_to(line1, color=YELLOW)
|
||||
self.add(ax, line1, line2)
|
||||
"""
|
||||
point = np.array(point)
|
||||
np_point = np.asarray(point)
|
||||
vect = normalize(line.vect)
|
||||
return cls(
|
||||
point + vect * length / 2,
|
||||
point - vect * length / 2,
|
||||
np_point + vect * length / 2,
|
||||
np_point - vect * length / 2,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
|
@ -1066,7 +1072,7 @@ class Line3D(Cylinder):
|
|||
def perpendicular_to(
|
||||
cls,
|
||||
line: Line3D,
|
||||
point: Vector3D = ORIGIN,
|
||||
point: Vector3DLike = ORIGIN,
|
||||
length: float = 5,
|
||||
**kwargs,
|
||||
) -> Line3D:
|
||||
|
|
@ -1102,17 +1108,17 @@ class Line3D(Cylinder):
|
|||
line2 = Line3D.perpendicular_to(line1, color=BLUE)
|
||||
self.add(ax, line1, line2)
|
||||
"""
|
||||
point = np.array(point)
|
||||
np_point = np.asarray(point)
|
||||
|
||||
norm = np.cross(line.vect, point - line.start)
|
||||
norm = np.cross(line.vect, np_point - line.start)
|
||||
if all(np.linalg.norm(norm) == np.zeros(3)):
|
||||
raise ValueError("Could not find the perpendicular.")
|
||||
|
||||
start, end = perpendicular_bisector([line.start, line.end], norm)
|
||||
vect = normalize(end - start)
|
||||
return cls(
|
||||
point + vect * length / 2,
|
||||
point - vect * length / 2,
|
||||
np_point + vect * length / 2,
|
||||
np_point - vect * length / 2,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ if TYPE_CHECKING:
|
|||
import numpy.typing as npt
|
||||
from typing_extensions import Self
|
||||
|
||||
from manim.typing import ManimFloat, Point3DLike, Vector3D
|
||||
from manim.typing import ManimFloat, Point3DLike
|
||||
|
||||
|
||||
class PMobject(Mobject, metaclass=ConvertToOpenGL):
|
||||
|
|
@ -349,7 +349,7 @@ class PointCloudDot(Mobject1D):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
center: Vector3D = ORIGIN,
|
||||
center: Point3DLike = ORIGIN,
|
||||
radius: float = 2.0,
|
||||
stroke_width: int = 2,
|
||||
density: int = DEFAULT_POINT_DENSITY_1D,
|
||||
|
|
@ -406,7 +406,7 @@ class Point(PMobject):
|
|||
"""
|
||||
|
||||
def __init__(
|
||||
self, location: Vector3D = ORIGIN, color: ManimColor = BLACK, **kwargs: Any
|
||||
self, location: Point3DLike = ORIGIN, color: ManimColor = BLACK, **kwargs: Any
|
||||
) -> None:
|
||||
self.location = location
|
||||
super().__init__(color=color, **kwargs)
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ if TYPE_CHECKING:
|
|||
Point3DLike_Array,
|
||||
RGBA_Array_Float,
|
||||
Vector3D,
|
||||
Vector3DLike,
|
||||
Zeros,
|
||||
)
|
||||
|
||||
|
|
@ -116,7 +117,7 @@ class VMobject(Mobject):
|
|||
background_stroke_width: float = 0,
|
||||
sheen_factor: float = 0.0,
|
||||
joint_type: LineJointType | None = None,
|
||||
sheen_direction: Vector3D = UL,
|
||||
sheen_direction: Vector3DLike = UL,
|
||||
close_new_points: bool = False,
|
||||
pre_function_handle_to_anchor_scale_factor: float = 0.01,
|
||||
make_smooth_after_applying_functions: bool = False,
|
||||
|
|
@ -141,7 +142,7 @@ class VMobject(Mobject):
|
|||
self.joint_type: LineJointType = (
|
||||
LineJointType.AUTO if joint_type is None else joint_type
|
||||
)
|
||||
self.sheen_direction: Vector3D = sheen_direction
|
||||
self.sheen_direction = sheen_direction
|
||||
self.close_new_points: bool = close_new_points
|
||||
self.pre_function_handle_to_anchor_scale_factor: float = (
|
||||
pre_function_handle_to_anchor_scale_factor
|
||||
|
|
@ -394,7 +395,7 @@ class VMobject(Mobject):
|
|||
background_stroke_width: float | None = None,
|
||||
background_stroke_opacity: float | None = None,
|
||||
sheen_factor: float | None = None,
|
||||
sheen_direction: Vector3D | None = None,
|
||||
sheen_direction: Vector3DLike | None = None,
|
||||
background_image: Image | str | None = None,
|
||||
family: bool = True,
|
||||
) -> Self:
|
||||
|
|
@ -619,7 +620,7 @@ class VMobject(Mobject):
|
|||
|
||||
color = property(get_color, set_color)
|
||||
|
||||
def set_sheen_direction(self, direction: Vector3D, family: bool = True) -> Self:
|
||||
def set_sheen_direction(self, direction: Vector3DLike, family: bool = True) -> Self:
|
||||
"""Sets the direction of the applied sheen.
|
||||
|
||||
Parameters
|
||||
|
|
@ -638,16 +639,16 @@ class VMobject(Mobject):
|
|||
:meth:`~.VMobject.set_sheen`
|
||||
:meth:`~.VMobject.rotate_sheen_direction`
|
||||
"""
|
||||
direction = np.array(direction)
|
||||
direction_copy = np.array(direction)
|
||||
if family:
|
||||
for submob in self.get_family():
|
||||
submob.sheen_direction = direction
|
||||
submob.sheen_direction = direction_copy.copy()
|
||||
else:
|
||||
self.sheen_direction: Vector3D = direction
|
||||
self.sheen_direction = direction_copy
|
||||
return self
|
||||
|
||||
def rotate_sheen_direction(
|
||||
self, angle: float, axis: Vector3D = OUT, family: bool = True
|
||||
self, angle: float, axis: Vector3DLike = OUT, family: bool = True
|
||||
) -> Self:
|
||||
"""Rotates the direction of the applied sheen.
|
||||
|
||||
|
|
@ -680,7 +681,7 @@ class VMobject(Mobject):
|
|||
return self
|
||||
|
||||
def set_sheen(
|
||||
self, factor: float, direction: Vector3D | None = None, family: bool = True
|
||||
self, factor: float, direction: Vector3DLike | None = None, family: bool = True
|
||||
) -> Self:
|
||||
"""Applies a color gradient from a direction.
|
||||
|
||||
|
|
@ -1188,7 +1189,7 @@ class VMobject(Mobject):
|
|||
def rotate(
|
||||
self,
|
||||
angle: float,
|
||||
axis: Vector3D = OUT,
|
||||
axis: Vector3DLike = OUT,
|
||||
about_point: Point3DLike | None = None,
|
||||
**kwargs,
|
||||
) -> Self:
|
||||
|
|
|
|||
|
|
@ -49,7 +49,14 @@ if TYPE_CHECKING:
|
|||
|
||||
from typing_extensions import Self
|
||||
|
||||
from manim.typing import MappingFunction, Point2DLike, Point3D, Point3DLike
|
||||
from manim.typing import (
|
||||
MappingFunction,
|
||||
Point3D,
|
||||
Point3DLike,
|
||||
Vector2DLike,
|
||||
Vector3D,
|
||||
Vector3DLike,
|
||||
)
|
||||
|
||||
|
||||
X_COLOR = GREEN_C
|
||||
|
|
@ -139,7 +146,7 @@ class VectorScene(Scene):
|
|||
self.renderer.camera = Camera(self.renderer.get_frame())
|
||||
self.clear()
|
||||
|
||||
def get_vector(self, numerical_vector: Point3DLike, **kwargs: Any) -> Arrow:
|
||||
def get_vector(self, numerical_vector: Vector3DLike, **kwargs: Any) -> Arrow:
|
||||
"""
|
||||
Returns an arrow on the Plane given an input numerical vector.
|
||||
|
||||
|
|
@ -166,7 +173,7 @@ class VectorScene(Scene):
|
|||
|
||||
def add_vector(
|
||||
self,
|
||||
vector: Arrow | Point3DLike,
|
||||
vector: Arrow | Vector3DLike,
|
||||
color: ParsableManimColor | Iterable[ParsableManimColor] = YELLOW,
|
||||
animate: bool = True,
|
||||
**kwargs: Any,
|
||||
|
|
@ -346,10 +353,10 @@ class VectorScene(Scene):
|
|||
if not rotate:
|
||||
label.rotate(-angle, about_point=ORIGIN)
|
||||
if direction == "left":
|
||||
temp_shift_1: Point3D = np.asarray(label.get_bottom())
|
||||
temp_shift_1: Vector3D = np.asarray(label.get_bottom())
|
||||
label.shift(-temp_shift_1 + 0.1 * UP)
|
||||
else:
|
||||
temp_shift_2: Point3D = np.asarray(label.get_top())
|
||||
temp_shift_2: Vector3D = np.asarray(label.get_top())
|
||||
label.shift(-temp_shift_2 + 0.1 * DOWN)
|
||||
label.rotate(angle, about_point=ORIGIN)
|
||||
label.shift((vector.get_end() - vector.get_start()) / 2)
|
||||
|
|
@ -391,7 +398,7 @@ class VectorScene(Scene):
|
|||
self,
|
||||
x_coord: MathTex,
|
||||
x_line: Line,
|
||||
vector: Point3DLike,
|
||||
vector: Vector3DLike,
|
||||
) -> MathTex: # TODO Write DocStrings for this.
|
||||
x_coord.next_to(x_line, -np.sign(vector[1]) * UP)
|
||||
x_coord.set_color(X_COLOR)
|
||||
|
|
@ -401,7 +408,7 @@ class VectorScene(Scene):
|
|||
self,
|
||||
y_coord: MathTex,
|
||||
y_line: Line,
|
||||
vector: Point3DLike,
|
||||
vector: Vector3DLike,
|
||||
) -> MathTex: # TODO Write DocStrings for this.
|
||||
y_coord.next_to(y_line, np.sign(vector[0]) * RIGHT)
|
||||
y_coord.set_color(Y_COLOR)
|
||||
|
|
@ -409,7 +416,7 @@ class VectorScene(Scene):
|
|||
|
||||
def coords_to_vector(
|
||||
self,
|
||||
vector: Point2DLike,
|
||||
vector: Vector2DLike,
|
||||
coords_start: Point3DLike = 2 * RIGHT + 2 * UP,
|
||||
clean_up: bool = True,
|
||||
) -> None:
|
||||
|
|
@ -475,7 +482,7 @@ class VectorScene(Scene):
|
|||
|
||||
def vector_to_coords(
|
||||
self,
|
||||
vector: Point3DLike,
|
||||
vector: Vector3DLike,
|
||||
integer_labels: bool = True,
|
||||
clean_up: bool = True,
|
||||
) -> tuple[Matrix, Line, Line]:
|
||||
|
|
@ -536,7 +543,7 @@ class VectorScene(Scene):
|
|||
self.add(*starting_mobjects)
|
||||
return array, x_line, y_line
|
||||
|
||||
def show_ghost_movement(self, vector: Arrow | Point2DLike | Point3DLike) -> None:
|
||||
def show_ghost_movement(self, vector: Arrow | Vector2DLike | Vector3DLike) -> None:
|
||||
"""
|
||||
This method plays an animation that partially shows the entire plane moving
|
||||
in the direction of a particular vector. This is useful when you wish to
|
||||
|
|
@ -554,7 +561,7 @@ class VectorScene(Scene):
|
|||
vector = np.asarray(vector)
|
||||
if len(vector) == 2:
|
||||
vector = np.append(np.array(vector), 0.0)
|
||||
vector_cleaned: Point3D = vector
|
||||
vector_cleaned: Vector3D = vector
|
||||
|
||||
x_max = int(config["frame_x_radius"] + abs(vector_cleaned[0]))
|
||||
y_max = int(config["frame_y_radius"] + abs(vector_cleaned[1]))
|
||||
|
|
|
|||
170
manim/typing.py
170
manim/typing.py
|
|
@ -61,11 +61,17 @@ __all__ = [
|
|||
"PointND_Array",
|
||||
"PointNDLike_Array",
|
||||
"Vector2D",
|
||||
"Vector2DLike",
|
||||
"Vector2D_Array",
|
||||
"Vector2DLike_Array",
|
||||
"Vector3D",
|
||||
"Vector3DLike",
|
||||
"Vector3D_Array",
|
||||
"Vector3DLike_Array",
|
||||
"VectorND",
|
||||
"VectorNDLike",
|
||||
"VectorND_Array",
|
||||
"VectorNDLike_Array",
|
||||
"RowVector",
|
||||
"ColVector",
|
||||
"MatrixMN",
|
||||
|
|
@ -312,29 +318,23 @@ A 2-dimensional point: ``[float, float]``.
|
|||
|
||||
This represents anything which can be converted to a :class:`Point2D` NumPy
|
||||
array.
|
||||
|
||||
Normally, a function or method which expects a `Point2D` as a
|
||||
parameter can handle being passed a `Point3D` instead.
|
||||
"""
|
||||
|
||||
Point2D_Array: TypeAlias = npt.NDArray[PointDType]
|
||||
"""``shape: (M, 2)``
|
||||
|
||||
A NumPy array representing a sequence of `Point2D` objects:
|
||||
A NumPy array representing a sequence of :class:`Point2D` objects:
|
||||
``[[float, float], ...]``.
|
||||
"""
|
||||
|
||||
Point2DLike_Array: TypeAlias = Union[Point2D_Array, Sequence[Point2DLike]]
|
||||
"""``shape: (M, 2)``
|
||||
|
||||
An array of `Point2DLike` objects: ``[[float, float], ...]``.
|
||||
An array of :class:`Point2DLike` objects: ``[[float, float], ...]``.
|
||||
|
||||
This represents anything which can be converted to a :class:`Point2D_Array`
|
||||
NumPy array.
|
||||
|
||||
Normally, a function or method which expects a `Point2D_Array` as a
|
||||
parameter can handle being passed a `Point3D_Array` instead.
|
||||
|
||||
Please refer to the documentation of the function you are using for
|
||||
further type information.
|
||||
"""
|
||||
|
|
@ -357,14 +357,14 @@ array.
|
|||
Point3D_Array: TypeAlias = npt.NDArray[PointDType]
|
||||
"""``shape: (M, 3)``
|
||||
|
||||
A NumPy array representing a sequence of `Point3D` objects:
|
||||
A NumPy array representing a sequence of :class:`Point3D` objects:
|
||||
``[[float, float, float], ...]``.
|
||||
"""
|
||||
|
||||
Point3DLike_Array: TypeAlias = Union[Point3D_Array, Sequence[Point3DLike]]
|
||||
"""``shape: (M, 3)``
|
||||
|
||||
An array of `Point3D` objects: ``[[float, float, float], ...]``.
|
||||
An array of :class:`Point3DLike` objects: ``[[float, float, float], ...]``.
|
||||
|
||||
This represents anything which can be converted to a :class:`Point3D_Array`
|
||||
NumPy array.
|
||||
|
|
@ -391,14 +391,14 @@ array.
|
|||
PointND_Array: TypeAlias = npt.NDArray[PointDType]
|
||||
"""``shape: (M, N)``
|
||||
|
||||
A NumPy array representing a sequence of `PointND` objects:
|
||||
A NumPy array representing a sequence of :class:`PointND` objects:
|
||||
``[[float, ...], ...]``.
|
||||
"""
|
||||
|
||||
PointNDLike_Array: TypeAlias = Union[PointND_Array, Sequence[PointNDLike]]
|
||||
"""``shape: (M, N)``
|
||||
|
||||
An array of `PointND` objects: ``[[float, ...], ...]``.
|
||||
An array of :class:`PointNDLike` objects: ``[[float, ...], ...]``.
|
||||
|
||||
This represents anything which can be converted to a :class:`PointND_Array`
|
||||
NumPy array.
|
||||
|
|
@ -416,10 +416,20 @@ Vector types
|
|||
Vector2D: TypeAlias = npt.NDArray[PointDType]
|
||||
"""``shape: (2,)``
|
||||
|
||||
A NumPy array representing a 2-dimensional vector: ``[float, float]``.
|
||||
|
||||
.. caution::
|
||||
Do not confuse with the :class:`~.Vector` or :class:`~.Arrow`
|
||||
VMobjects!
|
||||
"""
|
||||
|
||||
Vector2DLike: TypeAlias = Union[npt.NDArray[PointDType], tuple[float, float]]
|
||||
"""``shape: (2,)``
|
||||
|
||||
A 2-dimensional vector: ``[float, float]``.
|
||||
|
||||
Normally, a function or method which expects a `Vector2D` as a
|
||||
parameter can handle being passed a `Vector3D` instead.
|
||||
This represents anything which can be converted to a :class:`Vector2D` NumPy
|
||||
array.
|
||||
|
||||
.. caution::
|
||||
Do not confuse with the :class:`~.Vector` or :class:`~.Arrow`
|
||||
|
|
@ -429,17 +439,37 @@ parameter can handle being passed a `Vector3D` instead.
|
|||
Vector2D_Array: TypeAlias = npt.NDArray[PointDType]
|
||||
"""``shape: (M, 2)``
|
||||
|
||||
An array of `Vector2D` objects: ``[[float, float], ...]``.
|
||||
A NumPy array representing a sequence of :class:`Vector2D` objects:
|
||||
``[[float, float], ...]``.
|
||||
"""
|
||||
|
||||
Normally, a function or method which expects a `Vector2D_Array` as a
|
||||
parameter can handle being passed a `Vector3D_Array` instead.
|
||||
Vector2DLike_Array: TypeAlias = Union[Vector2D_Array, Sequence[Vector2DLike]]
|
||||
"""``shape: (M, 2)``
|
||||
|
||||
An array of :class:`Vector2DLike` objects: ``[[float, float], ...]``.
|
||||
|
||||
This represents anything which can be converted to a :class:`Vector2D_Array`
|
||||
NumPy array.
|
||||
"""
|
||||
|
||||
Vector3D: TypeAlias = npt.NDArray[PointDType]
|
||||
"""``shape: (3,)``
|
||||
|
||||
A NumPy array representing a 3-dimensional vector: ``[float, float, float]``.
|
||||
|
||||
.. caution::
|
||||
Do not confuse with the :class:`~.Vector` or :class:`~.Arrow3D`
|
||||
VMobjects!
|
||||
"""
|
||||
|
||||
Vector3DLike: TypeAlias = Union[npt.NDArray[PointDType], tuple[float, float, float]]
|
||||
"""``shape: (3,)``
|
||||
|
||||
A 3-dimensional vector: ``[float, float, float]``.
|
||||
|
||||
This represents anything which can be converted to a :class:`Vector3D` NumPy
|
||||
array.
|
||||
|
||||
.. caution::
|
||||
Do not confuse with the :class:`~.Vector` or :class:`~.Arrow3D`
|
||||
VMobjects!
|
||||
|
|
@ -448,14 +478,38 @@ A 3-dimensional vector: ``[float, float, float]``.
|
|||
Vector3D_Array: TypeAlias = npt.NDArray[PointDType]
|
||||
"""``shape: (M, 3)``
|
||||
|
||||
An array of `Vector3D` objects: ``[[float, float, float], ...]``.
|
||||
An NumPy array representing a sequence of :class:`Vector3D` objects:
|
||||
``[[float, float, float], ...]``.
|
||||
"""
|
||||
|
||||
Vector3DLike_Array: TypeAlias = Union[npt.NDArray[PointDType], Sequence[Vector3DLike]]
|
||||
"""``shape: (M, 3)``
|
||||
|
||||
An array of :class:`Vector3DLike` objects: ``[[float, float, float], ...]``.
|
||||
|
||||
This represents anything which can be converted to a :class:`Vector3D_Array`
|
||||
NumPy array.
|
||||
"""
|
||||
|
||||
VectorND: TypeAlias = npt.NDArray[PointDType]
|
||||
"""``shape (N,)``
|
||||
|
||||
A NumPy array representing an :math:`N`-dimensional vector: ``[float, ...]``.
|
||||
|
||||
.. caution::
|
||||
Do not confuse with the :class:`~.Vector` VMobject! This type alias
|
||||
is named "VectorND" instead of "Vector" to avoid potential name
|
||||
collisions.
|
||||
"""
|
||||
|
||||
VectorNDLike: TypeAlias = Union[npt.NDArray[PointDType], Sequence[float]]
|
||||
"""``shape (N,)``
|
||||
|
||||
An :math:`N`-dimensional vector: ``[float, ...]``.
|
||||
|
||||
This represents anything which can be converted to a :class:`VectorND` NumPy
|
||||
array.
|
||||
|
||||
.. caution::
|
||||
Do not confuse with the :class:`~.Vector` VMobject! This type alias
|
||||
is named "VectorND" instead of "Vector" to avoid potential name
|
||||
|
|
@ -465,7 +519,17 @@ An :math:`N`-dimensional vector: ``[float, ...]``.
|
|||
VectorND_Array: TypeAlias = npt.NDArray[PointDType]
|
||||
"""``shape (M, N)``
|
||||
|
||||
An array of `VectorND` objects: ``[[float, ...], ...]``.
|
||||
A NumPy array representing a sequence of :class:`VectorND` objects:
|
||||
``[[float, ...], ...]``.
|
||||
"""
|
||||
|
||||
VectorNDLike_Array: TypeAlias = Union[npt.NDArray[PointDType], Sequence[VectorNDLike]]
|
||||
"""``shape (M, N)``
|
||||
|
||||
An array of :class:`VectorNDLike` objects: ``[[float, ...], ...]``.
|
||||
|
||||
This represents anything which can be converted to a :class:`VectorND_Array`
|
||||
NumPy array.
|
||||
"""
|
||||
|
||||
RowVector: TypeAlias = npt.NDArray[PointDType]
|
||||
|
|
@ -495,7 +559,7 @@ A matrix: ``[[float, ...], [float, ...], ...]``.
|
|||
Zeros: TypeAlias = MatrixMN
|
||||
"""``shape: (M, N)``
|
||||
|
||||
A `MatrixMN` filled with zeros, typically created with
|
||||
A :class:`MatrixMN` filled with zeros, typically created with
|
||||
``numpy.zeros((M, N))``.
|
||||
"""
|
||||
|
||||
|
|
@ -508,7 +572,7 @@ Bézier types
|
|||
QuadraticBezierPoints: TypeAlias = Point3D_Array
|
||||
"""``shape: (3, 3)``
|
||||
|
||||
A `Point3D_Array` of three 3D control points for a single quadratic Bézier
|
||||
A :class:`Point3D_Array` of three 3D control points for a single quadratic Bézier
|
||||
curve:
|
||||
``[[float, float, float], [float, float, float], [float, float, float]]``.
|
||||
"""
|
||||
|
|
@ -518,7 +582,7 @@ QuadraticBezierPointsLike: TypeAlias = Union[
|
|||
]
|
||||
"""``shape: (3, 3)``
|
||||
|
||||
A `Point3DLike_Array` of three 3D control points for a single quadratic Bézier
|
||||
A :class:`Point3DLike_Array` of three 3D control points for a single quadratic Bézier
|
||||
curve:
|
||||
``[[float, float, float], [float, float, float], [float, float, float]]``.
|
||||
|
||||
|
|
@ -529,7 +593,7 @@ This represents anything which can be converted to a
|
|||
QuadraticBezierPoints_Array: TypeAlias = npt.NDArray[PointDType]
|
||||
"""``shape: (N, 3, 3)``
|
||||
|
||||
A NumPy array containing :math:`N` `QuadraticBezierPoints` objects:
|
||||
A NumPy array containing :math:`N` :class:`QuadraticBezierPoints` objects:
|
||||
``[[[float, float, float], [float, float, float], [float, float, float]], ...]``.
|
||||
"""
|
||||
|
||||
|
|
@ -538,7 +602,7 @@ QuadraticBezierPointsLike_Array: TypeAlias = Union[
|
|||
]
|
||||
"""``shape: (N, 3, 3)``
|
||||
|
||||
A sequence of :math:`N` `QuadraticBezierPointsLike` objects:
|
||||
A sequence of :math:`N` :class:`QuadraticBezierPointsLike` objects:
|
||||
``[[[float, float, float], [float, float, float], [float, float, float]], ...]``.
|
||||
|
||||
This represents anything which can be converted to a
|
||||
|
|
@ -548,7 +612,7 @@ This represents anything which can be converted to a
|
|||
QuadraticBezierPath: TypeAlias = Point3D_Array
|
||||
"""``shape: (3*N, 3)``
|
||||
|
||||
A `Point3D_Array` of :math:`3N` points, where each one of the
|
||||
A :class:`Point3D_Array` of :math:`3N` points, where each one of the
|
||||
:math:`N` consecutive blocks of 3 points represents a quadratic
|
||||
Bézier curve:
|
||||
``[[float, float, float], ...], ...]``.
|
||||
|
|
@ -560,7 +624,7 @@ further type information.
|
|||
QuadraticBezierPathLike: TypeAlias = Point3DLike_Array
|
||||
"""``shape: (3*N, 3)``
|
||||
|
||||
A `Point3DLike_Array` of :math:`3N` points, where each one of the
|
||||
A :class:`Point3DLike_Array` of :math:`3N` points, where each one of the
|
||||
:math:`N` consecutive blocks of 3 points represents a quadratic
|
||||
Bézier curve:
|
||||
``[[float, float, float], ...], ...]``.
|
||||
|
|
@ -575,7 +639,7 @@ further type information.
|
|||
QuadraticSpline: TypeAlias = QuadraticBezierPath
|
||||
"""``shape: (3*N, 3)``
|
||||
|
||||
A special case of `QuadraticBezierPath` where all the :math:`N`
|
||||
A special case of :class:`QuadraticBezierPath` where all the :math:`N`
|
||||
quadratic Bézier curves are connected, forming a quadratic spline:
|
||||
``[[float, float, float], ...], ...]``.
|
||||
|
||||
|
|
@ -586,7 +650,7 @@ further type information.
|
|||
QuadraticSplineLike: TypeAlias = QuadraticBezierPathLike
|
||||
"""``shape: (3*N, 3)``
|
||||
|
||||
A special case of `QuadraticBezierPathLike` where all the :math:`N`
|
||||
A special case of :class:`QuadraticBezierPathLike` where all the :math:`N`
|
||||
quadratic Bézier curves are connected, forming a quadratic spline:
|
||||
``[[float, float, float], ...], ...]``.
|
||||
|
||||
|
|
@ -600,7 +664,7 @@ further type information.
|
|||
CubicBezierPoints: TypeAlias = Point3D_Array
|
||||
"""``shape: (4, 3)``
|
||||
|
||||
A `Point3D_Array` of four 3D control points for a single cubic Bézier curve:
|
||||
A :class:`Point3D_Array` of four 3D control points for a single cubic Bézier curve:
|
||||
``[[float, float, float], [float, float, float], [float, float, float], [float, float, float]]``.
|
||||
"""
|
||||
|
||||
|
|
@ -609,7 +673,7 @@ CubicBezierPointsLike: TypeAlias = Union[
|
|||
]
|
||||
"""``shape: (4, 3)``
|
||||
|
||||
A `Point3DLike_Array` of 4 control points for a single cubic Bézier curve:
|
||||
A :class:`Point3DLike_Array` of 4 control points for a single cubic Bézier curve:
|
||||
``[[float, float, float], [float, float, float], [float, float, float], [float, float, float]]``.
|
||||
|
||||
This represents anything which can be converted to a :class:`CubicBezierPoints`
|
||||
|
|
@ -619,7 +683,7 @@ NumPy array.
|
|||
CubicBezierPoints_Array: TypeAlias = npt.NDArray[PointDType]
|
||||
"""``shape: (N, 4, 3)``
|
||||
|
||||
A NumPy array containing :math:`N` `CubicBezierPoints` objects:
|
||||
A NumPy array containing :math:`N` :class:`CubicBezierPoints` objects:
|
||||
``[[[float, float, float], [float, float, float], [float, float, float], [float, float, float]], ...]``.
|
||||
"""
|
||||
|
||||
|
|
@ -628,7 +692,7 @@ CubicBezierPointsLike_Array: TypeAlias = Union[
|
|||
]
|
||||
"""``shape: (N, 4, 3)``
|
||||
|
||||
A sequence of :math:`N` `CubicBezierPointsLike` objects:
|
||||
A sequence of :math:`N` :class:`CubicBezierPointsLike` objects:
|
||||
``[[[float, float, float], [float, float, float], [float, float, float], [float, float, float]], ...]``.
|
||||
|
||||
This represents anything which can be converted to a
|
||||
|
|
@ -638,7 +702,7 @@ This represents anything which can be converted to a
|
|||
CubicBezierPath: TypeAlias = Point3D_Array
|
||||
"""``shape: (4*N, 3)``
|
||||
|
||||
A `Point3D_Array` of :math:`4N` points, where each one of the
|
||||
A :class:`Point3D_Array` of :math:`4N` points, where each one of the
|
||||
:math:`N` consecutive blocks of 4 points represents a cubic Bézier
|
||||
curve:
|
||||
``[[float, float, float], ...], ...]``.
|
||||
|
|
@ -650,7 +714,7 @@ further type information.
|
|||
CubicBezierPathLike: TypeAlias = Point3DLike_Array
|
||||
"""``shape: (4*N, 3)``
|
||||
|
||||
A `Point3DLike_Array` of :math:`4N` points, where each one of the
|
||||
A :class:`Point3DLike_Array` of :math:`4N` points, where each one of the
|
||||
:math:`N` consecutive blocks of 4 points represents a cubic Bézier
|
||||
curve:
|
||||
``[[float, float, float], ...], ...]``.
|
||||
|
|
@ -665,7 +729,7 @@ further type information.
|
|||
CubicSpline: TypeAlias = CubicBezierPath
|
||||
"""``shape: (4*N, 3)``
|
||||
|
||||
A special case of `CubicBezierPath` where all the :math:`N` cubic
|
||||
A special case of :class:`CubicBezierPath` where all the :math:`N` cubic
|
||||
Bézier curves are connected, forming a quadratic spline:
|
||||
``[[float, float, float], ...], ...]``.
|
||||
|
||||
|
|
@ -676,7 +740,7 @@ further type information.
|
|||
CubicSplineLike: TypeAlias = CubicBezierPathLike
|
||||
"""``shape: (4*N, 3)``
|
||||
|
||||
A special case of `CubicBezierPath` where all the :math:`N` cubic
|
||||
A special case of :class:`CubicBezierPath` where all the :math:`N` cubic
|
||||
Bézier curves are connected, forming a quadratic spline:
|
||||
``[[float, float, float], ...], ...]``.
|
||||
|
||||
|
|
@ -690,7 +754,7 @@ further type information.
|
|||
BezierPoints: TypeAlias = Point3D_Array
|
||||
r"""``shape: (PPC, 3)``
|
||||
|
||||
A `Point3D_Array` of :math:`\text{PPC}` control points
|
||||
A :class:`Point3D_Array` of :math:`\text{PPC}` control points
|
||||
(:math:`\text{PPC: Points Per Curve} = n + 1`) for a single
|
||||
:math:`n`-th degree Bézier curve:
|
||||
``[[float, float, float], ...]``.
|
||||
|
|
@ -702,7 +766,7 @@ further type information.
|
|||
BezierPointsLike: TypeAlias = Point3DLike_Array
|
||||
r"""``shape: (PPC, 3)``
|
||||
|
||||
A `Point3DLike_Array` of :math:`\text{PPC}` control points
|
||||
A :class:`Point3DLike_Array` of :math:`\text{PPC}` control points
|
||||
(:math:`\text{PPC: Points Per Curve} = n + 1`) for a single
|
||||
:math:`n`-th degree Bézier curve:
|
||||
``[[float, float, float], ...]``.
|
||||
|
|
@ -717,8 +781,8 @@ further type information.
|
|||
BezierPoints_Array: TypeAlias = npt.NDArray[PointDType]
|
||||
r"""``shape: (N, PPC, 3)``
|
||||
|
||||
A NumPy array of :math:`N` `BezierPoints` objects containing
|
||||
:math:`\text{PPC}` `Point3D` objects each
|
||||
A NumPy array of :math:`N` :class:`BezierPoints` objects containing
|
||||
:math:`\text{PPC}` :class:`Point3D` objects each
|
||||
(:math:`\text{PPC: Points Per Curve} = n + 1`):
|
||||
``[[[float, float, float], ...], ...]``.
|
||||
|
||||
|
|
@ -731,8 +795,8 @@ BezierPointsLike_Array: TypeAlias = Union[
|
|||
]
|
||||
r"""``shape: (N, PPC, 3)``
|
||||
|
||||
A sequence of :math:`N` `BezierPointsLike` objects containing
|
||||
:math:`\text{PPC}` `Point3DLike` objects each
|
||||
A sequence of :math:`N` :class:`BezierPointsLike` objects containing
|
||||
:math:`\text{PPC}` :class:`Point3DLike` objects each
|
||||
(:math:`\text{PPC: Points Per Curve} = n + 1`):
|
||||
``[[[float, float, float], ...], ...]``.
|
||||
|
||||
|
|
@ -746,7 +810,7 @@ further type information.
|
|||
BezierPath: TypeAlias = Point3D_Array
|
||||
r"""``shape: (PPC*N, 3)``
|
||||
|
||||
A `Point3D_Array` of :math:`\text{PPC} \cdot N` points, where each
|
||||
A :class:`Point3D_Array` of :math:`\text{PPC} \cdot N` points, where each
|
||||
one of the :math:`N` consecutive blocks of :math:`\text{PPC}` control
|
||||
points (:math:`\text{PPC: Points Per Curve} = n + 1`) represents a
|
||||
Bézier curve of :math:`n`-th degree:
|
||||
|
|
@ -759,7 +823,7 @@ further type information.
|
|||
BezierPathLike: TypeAlias = Point3DLike_Array
|
||||
r"""``shape: (PPC*N, 3)``
|
||||
|
||||
A `Point3DLike_Array` of :math:`\text{PPC} \cdot N` points, where each
|
||||
A :class:`Point3DLike_Array` of :math:`\text{PPC} \cdot N` points, where each
|
||||
one of the :math:`N` consecutive blocks of :math:`\text{PPC}` control
|
||||
points (:math:`\text{PPC: Points Per Curve} = n + 1`) represents a
|
||||
Bézier curve of :math:`n`-th degree:
|
||||
|
|
@ -775,8 +839,8 @@ further type information.
|
|||
Spline: TypeAlias = BezierPath
|
||||
r"""``shape: (PPC*N, 3)``
|
||||
|
||||
A special case of `BezierPath` where all the :math:`N` Bézier curves
|
||||
consisting of :math:`\text{PPC}` `Point3D` objects
|
||||
A special case of :class:`BezierPath` where all the :math:`N` Bézier curves
|
||||
consisting of :math:`\text{PPC}` :class:`Point3D` objects
|
||||
(:math:`\text{PPC: Points Per Curve} = n + 1`) are connected, forming
|
||||
an :math:`n`-th degree spline:
|
||||
``[[float, float, float], ...], ...]``.
|
||||
|
|
@ -788,8 +852,8 @@ further type information.
|
|||
SplineLike: TypeAlias = BezierPathLike
|
||||
r"""``shape: (PPC*N, 3)``
|
||||
|
||||
A special case of `BezierPathLike` where all the :math:`N` Bézier curves
|
||||
consisting of :math:`\text{PPC}` `Point3D` objects
|
||||
A special case of :class:`BezierPathLike` where all the :math:`N` Bézier curves
|
||||
consisting of :math:`\text{PPC}` :class:`Point3D` objects
|
||||
(:math:`\text{PPC: Points Per Curve} = n + 1`) are connected, forming
|
||||
an :math:`n`-th degree spline:
|
||||
``[[float, float, float], ...], ...]``.
|
||||
|
|
@ -851,29 +915,29 @@ A rasterized image with a height of ``height`` pixels and a width of
|
|||
Every value in the array is an integer from 0 to 255.
|
||||
|
||||
Every pixel is represented either by a single integer indicating its
|
||||
lightness (for greyscale images), an `RGB_Array_Int` or an
|
||||
lightness (for greyscale images), an :class:`RGB_Array_Int` or an
|
||||
`RGBA_Array_Int`.
|
||||
"""
|
||||
|
||||
GrayscalePixelArray: TypeAlias = PixelArray
|
||||
"""``shape: (height, width)``
|
||||
|
||||
A 100% opaque grayscale `PixelArray`, where every pixel value is a
|
||||
A 100% opaque grayscale :class:`PixelArray`, where every pixel value is a
|
||||
`ManimInt` indicating its lightness (black -> gray -> white).
|
||||
"""
|
||||
|
||||
RGBPixelArray: TypeAlias = PixelArray
|
||||
"""``shape: (height, width, 3)``
|
||||
|
||||
A 100% opaque `PixelArray` in color, where every pixel value is an
|
||||
A 100% opaque :class:`PixelArray` in color, where every pixel value is an
|
||||
`RGB_Array_Int` object.
|
||||
"""
|
||||
|
||||
RGBAPixelArray: TypeAlias = PixelArray
|
||||
"""``shape: (height, width, 4)``
|
||||
|
||||
A `PixelArray` in color where pixels can be transparent. Every pixel
|
||||
value is an `RGBA_Array_Int` object.
|
||||
A :class:`PixelArray` in color where pixels can be transparent. Every pixel
|
||||
value is an :class:`RGBA_Array_Int` object.
|
||||
"""
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,15 @@ import numpy as np
|
|||
|
||||
from ..constants import OUT
|
||||
from ..utils.bezier import interpolate
|
||||
from ..utils.space_ops import rotation_matrix
|
||||
from ..utils.space_ops import normalize, rotation_matrix
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from manim.typing import PathFuncType, Point3D_Array, Vector3D
|
||||
from manim.typing import (
|
||||
PathFuncType,
|
||||
Point3D_Array,
|
||||
Point3DLike_Array,
|
||||
Vector3DLike,
|
||||
)
|
||||
|
||||
|
||||
STRAIGHT_PATH_THRESHOLD = 0.01
|
||||
|
|
@ -72,7 +77,7 @@ def straight_path() -> PathFuncType:
|
|||
|
||||
|
||||
def path_along_circles(
|
||||
arc_angle: float, circles_centers: np.ndarray, axis: Vector3D = OUT
|
||||
arc_angle: float, circles_centers: Point3DLike_Array, axis: Vector3DLike = OUT
|
||||
) -> PathFuncType:
|
||||
"""This function transforms each point by moving it roughly along a circle, each with its own specified center.
|
||||
|
||||
|
|
@ -132,9 +137,7 @@ def path_along_circles(
|
|||
self.wait()
|
||||
|
||||
"""
|
||||
if np.linalg.norm(axis) == 0:
|
||||
axis = OUT
|
||||
unit_axis = axis / np.linalg.norm(axis)
|
||||
unit_axis = normalize(axis, fall_back=OUT)
|
||||
|
||||
def path(
|
||||
start_points: Point3D_Array, end_points: Point3D_Array, alpha: float
|
||||
|
|
@ -152,7 +155,7 @@ def path_along_circles(
|
|||
return path
|
||||
|
||||
|
||||
def path_along_arc(arc_angle: float, axis: Vector3D = OUT) -> PathFuncType:
|
||||
def path_along_arc(arc_angle: float, axis: Vector3DLike = OUT) -> PathFuncType:
|
||||
"""This function transforms each point by moving it along a circular arc.
|
||||
|
||||
Parameters
|
||||
|
|
@ -204,9 +207,7 @@ def path_along_arc(arc_angle: float, axis: Vector3D = OUT) -> PathFuncType:
|
|||
"""
|
||||
if abs(arc_angle) < STRAIGHT_PATH_THRESHOLD:
|
||||
return straight_path()
|
||||
if np.linalg.norm(axis) == 0:
|
||||
axis = OUT
|
||||
unit_axis = axis / np.linalg.norm(axis)
|
||||
unit_axis = normalize(axis, fall_back=OUT)
|
||||
|
||||
def path(
|
||||
start_points: Point3D_Array, end_points: Point3D_Array, alpha: float
|
||||
|
|
@ -313,7 +314,7 @@ def counterclockwise_path() -> PathFuncType:
|
|||
return path_along_arc(np.pi)
|
||||
|
||||
|
||||
def spiral_path(angle: float, axis: Vector3D = OUT) -> PathFuncType:
|
||||
def spiral_path(angle: float, axis: Vector3DLike = OUT) -> PathFuncType:
|
||||
"""This function transforms each point by moving along a spiral to its destination.
|
||||
|
||||
Parameters
|
||||
|
|
@ -365,9 +366,7 @@ def spiral_path(angle: float, axis: Vector3D = OUT) -> PathFuncType:
|
|||
"""
|
||||
if abs(angle) < STRAIGHT_PATH_THRESHOLD:
|
||||
return straight_path()
|
||||
if np.linalg.norm(axis) == 0:
|
||||
axis = OUT
|
||||
unit_axis = axis / np.linalg.norm(axis)
|
||||
unit_axis = normalize(axis, fall_back=OUT)
|
||||
|
||||
def path(
|
||||
start_points: Point3D_Array, end_points: Point3D_Array, alpha: float
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ if TYPE_CHECKING:
|
|||
Vector2D,
|
||||
Vector2D_Array,
|
||||
Vector3D,
|
||||
Vector3D_Array,
|
||||
Vector3DLike,
|
||||
Vector3DLike_Array,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
|
|
@ -70,7 +71,7 @@ def norm_squared(v: float) -> float:
|
|||
return val
|
||||
|
||||
|
||||
def cross(v1: Vector3D, v2: Vector3D) -> Vector3D:
|
||||
def cross(v1: Vector3DLike, v2: Vector3DLike) -> Vector3D:
|
||||
return np.array(
|
||||
[
|
||||
v1[1] * v2[2] - v1[2] * v2[1],
|
||||
|
|
@ -178,8 +179,8 @@ def quaternion_conjugate(quaternion: Sequence[float]) -> np.ndarray:
|
|||
|
||||
|
||||
def rotate_vector(
|
||||
vector: np.ndarray, angle: float, axis: np.ndarray = OUT
|
||||
) -> np.ndarray:
|
||||
vector: Vector3DLike, angle: float, axis: Vector3DLike = OUT
|
||||
) -> Vector3D:
|
||||
"""Function for rotating a vector.
|
||||
|
||||
Parameters
|
||||
|
|
@ -245,7 +246,7 @@ def rotation_matrix_from_quaternion(quat: np.ndarray) -> np.ndarray:
|
|||
return np.transpose(rotation_matrix_transpose_from_quaternion(quat))
|
||||
|
||||
|
||||
def rotation_matrix_transpose(angle: float, axis: np.ndarray) -> np.ndarray:
|
||||
def rotation_matrix_transpose(angle: float, axis: Vector3DLike) -> np.ndarray:
|
||||
if all(np.array(axis)[:2] == np.zeros(2)):
|
||||
return rotation_about_z(angle * np.sign(axis[2])).T
|
||||
return rotation_matrix(angle, axis).T
|
||||
|
|
@ -253,12 +254,12 @@ def rotation_matrix_transpose(angle: float, axis: np.ndarray) -> np.ndarray:
|
|||
|
||||
def rotation_matrix(
|
||||
angle: float,
|
||||
axis: np.ndarray,
|
||||
axis: Vector3DLike,
|
||||
homogeneous: bool = False,
|
||||
) -> np.ndarray:
|
||||
"""Rotation in R^3 about a specified axis of rotation."""
|
||||
inhomogeneous_rotation_matrix = Rotation.from_rotvec(
|
||||
angle * normalize(np.array(axis))
|
||||
angle * normalize(axis)
|
||||
).as_matrix()
|
||||
if not homogeneous:
|
||||
return inhomogeneous_rotation_matrix
|
||||
|
|
@ -388,7 +389,7 @@ def normalize_along_axis(array: np.ndarray, axis: np.ndarray) -> np.ndarray:
|
|||
return array
|
||||
|
||||
|
||||
def get_unit_normal(v1: Vector3D, v2: Vector3D, tol: float = 1e-6) -> Vector3D:
|
||||
def get_unit_normal(v1: Vector3DLike, v2: Vector3DLike, tol: float = 1e-6) -> Vector3D:
|
||||
"""Gets the unit normal of the vectors.
|
||||
|
||||
Parameters
|
||||
|
|
@ -405,18 +406,21 @@ def get_unit_normal(v1: Vector3D, v2: Vector3D, tol: float = 1e-6) -> Vector3D:
|
|||
np.ndarray
|
||||
The normal of the two vectors.
|
||||
"""
|
||||
np_v1 = np.asarray(v1)
|
||||
np_v2 = np.asarray(v2)
|
||||
|
||||
# Instead of normalizing v1 and v2, just divide by the greatest
|
||||
# of all their absolute components, which is just enough
|
||||
div1, div2 = max(np.abs(v1)), max(np.abs(v2))
|
||||
div1, div2 = max(np.abs(np_v1)), max(np.abs(np_v2))
|
||||
if div1 == 0.0:
|
||||
if div2 == 0.0:
|
||||
return DOWN
|
||||
u = v2 / div2
|
||||
u = np_v2 / div2
|
||||
elif div2 == 0.0:
|
||||
u = v1 / div1
|
||||
u = np_v1 / div1
|
||||
else:
|
||||
# Normal scenario: v1 and v2 are both non-null
|
||||
u1, u2 = v1 / div1, v2 / div2
|
||||
u1, u2 = np_v1 / div1, np_v2 / div2
|
||||
cp = cross(u1, u2)
|
||||
cp_norm = np.sqrt(norm_squared(cp))
|
||||
if cp_norm > tol:
|
||||
|
|
@ -590,9 +594,9 @@ def line_intersection(
|
|||
|
||||
def find_intersection(
|
||||
p0s: Point3DLike_Array,
|
||||
v0s: Vector3D_Array,
|
||||
v0s: Vector3DLike_Array,
|
||||
p1s: Point3DLike_Array,
|
||||
v1s: Vector3D_Array,
|
||||
v1s: Vector3DLike_Array,
|
||||
threshold: float = 1e-5,
|
||||
) -> list[Point3D]:
|
||||
"""
|
||||
|
|
@ -605,7 +609,7 @@ def find_intersection(
|
|||
# algorithm from https://en.wikipedia.org/wiki/Skew_lines#Nearest_points
|
||||
result = []
|
||||
|
||||
for p0, v0, p1, v1 in zip(*[p0s, v0s, p1s, v1s]):
|
||||
for p0, v0, p1, v1 in zip(p0s, v0s, p1s, v1s):
|
||||
normal = cross(v1, cross(v0, v1))
|
||||
denom = max(np.dot(v0, normal), threshold)
|
||||
result += [p0 + np.dot(p1 - p0, normal) / denom * v0]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue