Rename np_vector type to Vect3 or Vect4 to make context clearer

This commit is contained in:
Grant Sanderson 2022-12-16 20:35:26 -08:00
parent 43fd5e1aea
commit dec11a4b17
20 changed files with 284 additions and 285 deletions

View file

@ -29,14 +29,14 @@ if TYPE_CHECKING:
from manimlib.typing import ManimColor
from typing import Sequence
np_vector = np.ndarray[int, np.dtype[np.float64]]
Vect3 = np.ndarray[int, np.dtype[np.float64]]
class CameraFrame(Mobject):
def __init__(
self,
frame_shape: tuple[float, float] = (FRAME_WIDTH, FRAME_HEIGHT),
center_point: np_vector = ORIGIN,
center_point: Vect3 = ORIGIN,
focal_dist_to_height: float = 2.0,
**kwargs,
):

View file

@ -4,7 +4,7 @@ import numpy as np
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import List
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
# Sizes relevant to default camera frame
@ -31,27 +31,27 @@ DEFAULT_MOBJECT_TO_MOBJECT_BUFFER: float = MED_SMALL_BUFF
DEFAULT_WAIT_TIME: float = 1.0
ORIGIN: np_vector = np.array([0., 0., 0.])
UP: np_vector = np.array([0., 1., 0.])
DOWN: np_vector = np.array([0., -1., 0.])
RIGHT: np_vector = np.array([1., 0., 0.])
LEFT: np_vector = np.array([-1., 0., 0.])
IN: np_vector = np.array([0., 0., -1.])
OUT: np_vector = np.array([0., 0., 1.])
X_AXIS: np_vector = np.array([1., 0., 0.])
Y_AXIS: np_vector = np.array([0., 1., 0.])
Z_AXIS: np_vector = np.array([0., 0., 1.])
ORIGIN: Vect3 = np.array([0., 0., 0.])
UP: Vect3 = np.array([0., 1., 0.])
DOWN: Vect3 = np.array([0., -1., 0.])
RIGHT: Vect3 = np.array([1., 0., 0.])
LEFT: Vect3 = np.array([-1., 0., 0.])
IN: Vect3 = np.array([0., 0., -1.])
OUT: Vect3 = np.array([0., 0., 1.])
X_AXIS: Vect3 = np.array([1., 0., 0.])
Y_AXIS: Vect3 = np.array([0., 1., 0.])
Z_AXIS: Vect3 = np.array([0., 0., 1.])
# Useful abbreviations for diagonals
UL: np_vector = UP + LEFT
UR: np_vector = UP + RIGHT
DL: np_vector = DOWN + LEFT
DR: np_vector = DOWN + RIGHT
UL: Vect3 = UP + LEFT
UR: Vect3 = UP + RIGHT
DL: Vect3 = DOWN + LEFT
DR: Vect3 = DOWN + RIGHT
TOP: np_vector = FRAME_Y_RADIUS * UP
BOTTOM: np_vector = FRAME_Y_RADIUS * DOWN
LEFT_SIDE: np_vector = FRAME_X_RADIUS * LEFT
RIGHT_SIDE: np_vector = FRAME_X_RADIUS * RIGHT
TOP: Vect3 = FRAME_Y_RADIUS * UP
BOTTOM: Vect3 = FRAME_Y_RADIUS * DOWN
LEFT_SIDE: Vect3 = FRAME_X_RADIUS * LEFT
RIGHT_SIDE: Vect3 = FRAME_X_RADIUS * RIGHT
PI: float = np.pi
TAU: float = 2 * PI

View file

@ -12,7 +12,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Callable, List, Iterable
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
class AnimatedBoundary(VGroup):
@ -97,7 +97,7 @@ class AnimatedBoundary(VGroup):
class TracedPath(VMobject):
def __init__(
self,
traced_point_func: Callable[[], np_vector],
traced_point_func: Callable[[], Vect3],
time_traced: float = np.inf,
time_per_anchor: float = 1.0 / 15,
stroke_width: float | Iterable[float] = 2.0,

View file

@ -34,7 +34,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Callable, Iterable, Sequence, Type, TypeVar
from manimlib.mobject.mobject import Mobject
from manimlib.typing import ManimColor, np_vector, RangeSpecifier
from manimlib.typing import ManimColor, Vect3, RangeSpecifier
T = TypeVar("T", bound=Mobject)
@ -61,22 +61,22 @@ class CoordinateSystem(ABC):
self.num_sampled_graph_points_per_tick = num_sampled_graph_points_per_tick
@abstractmethod
def coords_to_point(self, *coords: float) -> np_vector:
def coords_to_point(self, *coords: float) -> Vect3:
raise Exception("Not implemented")
@abstractmethod
def point_to_coords(self, point: np_vector) -> tuple[float, ...]:
def point_to_coords(self, point: Vect3) -> tuple[float, ...]:
raise Exception("Not implemented")
def c2p(self, *coords: float):
"""Abbreviation for coords_to_point"""
return self.coords_to_point(*coords)
def p2c(self, point: np_vector):
def p2c(self, point: Vect3):
"""Abbreviation for point_to_coords"""
return self.point_to_coords(point)
def get_origin(self) -> np_vector:
def get_origin(self) -> Vect3:
return self.c2p(*[0] * self.dimension)
@abstractmethod
@ -102,8 +102,8 @@ class CoordinateSystem(ABC):
def get_x_axis_label(
self,
label_tex: str,
edge: np_vector = RIGHT,
direction: np_vector = DL,
edge: Vect3 = RIGHT,
direction: Vect3 = DL,
**kwargs
) -> Tex:
return self.get_axis_label(
@ -114,8 +114,8 @@ class CoordinateSystem(ABC):
def get_y_axis_label(
self,
label_tex: str,
edge: np_vector = UP,
direction: np_vector = DR,
edge: Vect3 = UP,
direction: Vect3 = DR,
**kwargs
) -> Tex:
return self.get_axis_label(
@ -126,9 +126,9 @@ class CoordinateSystem(ABC):
def get_axis_label(
self,
label_tex: str,
axis: np_vector,
edge: np_vector,
direction: np_vector,
axis: Vect3,
edge: Vect3,
direction: Vect3,
buff: float = MED_SMALL_BUFF
) -> Tex:
label = Tex(label_tex)
@ -153,7 +153,7 @@ class CoordinateSystem(ABC):
def get_line_from_axis_to_point(
self,
index: int,
point: np_vector,
point: Vect3,
line_func: Type[T] = DashedLine,
color: ManimColor = GREY_A,
stroke_width: float = 2
@ -163,10 +163,10 @@ class CoordinateSystem(ABC):
line.set_stroke(color, stroke_width)
return line
def get_v_line(self, point: np_vector, **kwargs):
def get_v_line(self, point: Vect3, **kwargs):
return self.get_line_from_axis_to_point(0, point, **kwargs)
def get_h_line(self, point: np_vector, **kwargs):
def get_h_line(self, point: Vect3, **kwargs):
return self.get_line_from_axis_to_point(1, point, **kwargs)
# Useful for graphing
@ -184,7 +184,7 @@ class CoordinateSystem(ABC):
# sample frequency
t_range[2] /= self.num_sampled_graph_points_per_tick
def parametric_function(t: float) -> np_vector:
def parametric_function(t: float) -> Vect3:
return self.c2p(t, function(t))
graph = ParametricCurve(
@ -198,7 +198,7 @@ class CoordinateSystem(ABC):
def get_parametric_curve(
self,
function: Callable[[float], np_vector],
function: Callable[[float], Vect3],
**kwargs
) -> ParametricCurve:
dim = self.dimension
@ -213,7 +213,7 @@ class CoordinateSystem(ABC):
self,
x: float,
graph: ParametricCurve
) -> np_vector | None:
) -> Vect3 | None:
if hasattr(graph, "underlying_function"):
return self.coords_to_point(x, graph.underlying_function(x))
else:
@ -230,7 +230,7 @@ class CoordinateSystem(ABC):
else:
return None
def i2gp(self, x: float, graph: ParametricCurve) -> np_vector | None:
def i2gp(self, x: float, graph: ParametricCurve) -> Vect3 | None:
"""
Alias for input_to_graph_point
"""
@ -265,7 +265,7 @@ class CoordinateSystem(ABC):
graph: ParametricCurve,
label: str | Mobject = "f(x)",
x: float | None = None,
direction: np_vector = RIGHT,
direction: Vect3 = RIGHT,
buff: float = MED_SMALL_BUFF,
color: ManimColor | None = None
) -> Tex | Mobject:
@ -302,8 +302,8 @@ class CoordinateSystem(ABC):
return self.get_h_line(self.i2gp(x, graph), **kwargs)
def get_scatterplot(self,
x_values: np_vector,
y_values: np_vector,
x_values: Vect3,
y_values: Vect3,
**dot_config):
return DotCloud(self.c2p(x_values, y_values), **dot_config)
@ -449,14 +449,14 @@ class Axes(VGroup, CoordinateSystem):
axis.shift(-axis.n2p(0))
return axis
def coords_to_point(self, *coords: float) -> np_vector:
def coords_to_point(self, *coords: float) -> Vect3:
origin = self.x_axis.number_to_point(0)
return origin + sum(
axis.number_to_point(coord) - origin
for axis, coord in zip(self.get_axes(), coords)
)
def point_to_coords(self, point: np_vector) -> tuple[float, ...]:
def point_to_coords(self, point: Vect3) -> tuple[float, ...]:
return tuple([
axis.point_to_number(point)
for axis in self.get_axes()
@ -492,7 +492,7 @@ class ThreeDAxes(Axes):
y_range: RangeSpecifier = (-5.0, 5.0, 1.0),
z_range: RangeSpecifier = (-4.0, 4.0, 1.0),
z_axis_config: dict = dict(),
z_normal: np_vector = DOWN,
z_normal: Vect3 = DOWN,
depth: float = 6.0,
num_axis_pieces: int = 20,
gloss: float = 0.5,
@ -664,18 +664,18 @@ class NumberPlane(Axes):
class ComplexPlane(NumberPlane):
def number_to_point(self, number: complex | float) -> np_vector:
def number_to_point(self, number: complex | float) -> Vect3:
number = complex(number)
return self.coords_to_point(number.real, number.imag)
def n2p(self, number: complex | float) -> np_vector:
def n2p(self, number: complex | float) -> Vect3:
return self.number_to_point(number)
def point_to_number(self, point: np_vector) -> complex:
def point_to_number(self, point: Vect3) -> complex:
x, y = self.point_to_coords(point)
return complex(x, y)
def p2n(self, point: np_vector) -> complex:
def p2n(self, point: Vect3) -> complex:
return self.point_to_number(point)
def get_default_coordinate_values(

View file

@ -11,13 +11,13 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Callable, Sequence, Tuple
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
class ParametricCurve(VMobject):
def __init__(
self,
t_func: Callable[[float], Sequence[float] | np_vector],
t_func: Callable[[float], Sequence[float] | Vect3],
t_range: Tuple[float, float, float] = (0, 1, 0.1),
epsilon: float = 1e-8,
# TODO, automatically figure out discontinuities
@ -32,7 +32,7 @@ class ParametricCurve(VMobject):
self.use_smoothing = use_smoothing
super().__init__(**kwargs)
def get_point_from_function(self, t: float) -> np_vector:
def get_point_from_function(self, t: float) -> Vect3:
return np.array(self.t_func(t))
def init_points(self):

View file

@ -30,7 +30,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Iterable
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
DEFAULT_DOT_RADIUS = 0.08
@ -177,19 +177,19 @@ class TipableVMobject(VMobject):
def get_default_tip_length(self) -> float:
return self.tip_length
def get_first_handle(self) -> np_vector:
def get_first_handle(self) -> Vect3:
return self.get_points()[1]
def get_last_handle(self) -> np_vector:
def get_last_handle(self) -> Vect3:
return self.get_points()[-2]
def get_end(self) -> np_vector:
def get_end(self) -> Vect3:
if self.has_tip():
return self.tip.get_start()
else:
return VMobject.get_end(self)
def get_start(self) -> np_vector:
def get_start(self) -> Vect3:
if self.has_start_tip():
return self.start_tip.get_start()
else:
@ -207,7 +207,7 @@ class Arc(TipableVMobject):
angle: float = TAU / 4,
radius: float = 1.0,
n_components: int = 8,
arc_center: np_vector = ORIGIN,
arc_center: Vect3 = ORIGIN,
**kwargs
):
super().__init__(**kwargs)
@ -225,7 +225,7 @@ class Arc(TipableVMobject):
angle: float,
start_angle: float = 0,
n_components: int = 8
) -> np_vector:
) -> Vect3:
samples = np.array([
[np.cos(a), np.sin(a), 0]
for a in np.linspace(
@ -243,7 +243,7 @@ class Arc(TipableVMobject):
points[2::3] = samples[2::2]
return points
def get_arc_center(self) -> np_vector:
def get_arc_center(self) -> Vect3:
"""
Looks at the normals to the first two
anchors, and finds their intersection points
@ -266,7 +266,7 @@ class Arc(TipableVMobject):
angle = angle_of_vector(self.get_end() - self.get_arc_center())
return angle % TAU
def move_arc_center_to(self, point: np_vector):
def move_arc_center_to(self, point: Vect3):
self.shift(point - self.get_arc_center())
return self
@ -274,8 +274,8 @@ class Arc(TipableVMobject):
class ArcBetweenPoints(Arc):
def __init__(
self,
start: np_vector,
end: np_vector,
start: Vect3,
end: Vect3,
angle: float = TAU / 4,
**kwargs
):
@ -288,8 +288,8 @@ class ArcBetweenPoints(Arc):
class CurvedArrow(ArcBetweenPoints):
def __init__(
self,
start_point: np_vector,
end_point: np_vector,
start_point: Vect3,
end_point: Vect3,
**kwargs
):
super().__init__(start_point, end_point, **kwargs)
@ -299,8 +299,8 @@ class CurvedArrow(ArcBetweenPoints):
class CurvedDoubleArrow(CurvedArrow):
def __init__(
self,
start_point: np_vector,
end_point: np_vector,
start_point: Vect3,
end_point: Vect3,
**kwargs
):
super().__init__(start_point, end_point, **kwargs)
@ -334,7 +334,7 @@ class Circle(Arc):
self.stretch((self.get_height() + 2 * buff) / self.get_height(), 1)
return self
def point_at_angle(self, angle: float) -> np_vector:
def point_at_angle(self, angle: float) -> Vect3:
start_angle = self.get_start_angle()
return self.point_from_proportion(
((angle - start_angle) % TAU) / TAU
@ -347,7 +347,7 @@ class Circle(Arc):
class Dot(Circle):
def __init__(
self,
point: np_vector = ORIGIN,
point: Vect3 = ORIGIN,
radius: float = DEFAULT_DOT_RADIUS,
stroke_color: ManimColor = BLACK,
stroke_width: float = 0.0,
@ -369,7 +369,7 @@ class Dot(Circle):
class SmallDot(Dot):
def __init__(
self,
point: np_vector = ORIGIN,
point: Vect3 = ORIGIN,
radius: float = DEFAULT_SMALL_DOT_RADIUS,
**kwargs
):
@ -395,7 +395,7 @@ class AnnularSector(VMobject):
start_angle: float = 0.0,
inner_radius: float = 1.0,
outer_radius: float = 2.0,
arc_center: np_vector = ORIGIN,
arc_center: Vect3 = ORIGIN,
fill_color: ManimColor = GREY_A,
fill_opacity: float = 1.0,
stroke_width: float = 0.0,
@ -447,7 +447,7 @@ class Annulus(VMobject):
fill_opacity: float = 1.0,
stroke_width: float = 0.0,
fill_color: ManimColor = GREY_A,
center: np_vector = ORIGIN,
center: Vect3 = ORIGIN,
**kwargs,
):
super().__init__(
@ -468,8 +468,8 @@ class Annulus(VMobject):
class Line(TipableVMobject):
def __init__(
self,
start: np_vector | Mobject = LEFT,
end: np_vector | Mobject = RIGHT,
start: Vect3 | Mobject = LEFT,
end: Vect3 | Mobject = RIGHT,
buff: float = 0.0,
path_arc: float = 0.0,
**kwargs
@ -481,8 +481,8 @@ class Line(TipableVMobject):
def set_points_by_ends(
self,
start: np_vector,
end: np_vector,
start: Vect3,
end: Vect3,
buff: float = 0,
path_arc: float = 0
):
@ -518,7 +518,7 @@ class Line(TipableVMobject):
self.path_arc = new_value
self.init_points()
def set_start_and_end_attrs(self, start: np_vector | Mobject, end: np_vector | Mobject):
def set_start_and_end_attrs(self, start: Vect3 | Mobject, end: Vect3 | Mobject):
# If either start or end are Mobjects, this
# gives their centers
rough_start = self.pointify(start)
@ -532,9 +532,9 @@ class Line(TipableVMobject):
def pointify(
self,
mob_or_point: Mobject | np_vector,
direction: np_vector | None = None
) -> np_vector:
mob_or_point: Mobject | Vect3,
direction: Vect3 | None = None
) -> Vect3:
"""
Take an argument passed into Line (or subclass) and turn
it into a 3d point.
@ -551,7 +551,7 @@ class Line(TipableVMobject):
result[:len(point)] = point
return result
def put_start_and_end_on(self, start: np_vector, end: np_vector):
def put_start_and_end_on(self, start: Vect3, end: Vect3):
curr_start, curr_end = self.get_start_and_end()
if np.isclose(curr_start, curr_end).all():
# Handle null lines more gracefully
@ -559,16 +559,16 @@ class Line(TipableVMobject):
return self
return super().put_start_and_end_on(start, end)
def get_vector(self) -> np_vector:
def get_vector(self) -> Vect3:
return self.get_end() - self.get_start()
def get_unit_vector(self) -> np_vector:
def get_unit_vector(self) -> Vect3:
return normalize(self.get_vector())
def get_angle(self) -> float:
return angle_of_vector(self.get_vector())
def get_projection(self, point: np_vector) -> np_vector:
def get_projection(self, point: Vect3) -> Vect3:
"""
Return projection of a point onto the line
"""
@ -579,7 +579,7 @@ class Line(TipableVMobject):
def get_slope(self) -> float:
return np.tan(self.get_angle())
def set_angle(self, angle: float, about_point: np_vector | None = None):
def set_angle(self, angle: float, about_point: Vect3 | None = None):
if about_point is None:
about_point = self.get_start()
self.rotate(
@ -601,8 +601,8 @@ class Line(TipableVMobject):
class DashedLine(Line):
def __init__(
self,
start: np_vector = LEFT,
end: np_vector = RIGHT,
start: Vect3 = LEFT,
end: Vect3 = RIGHT,
dash_length: float = DEFAULT_DASH_LENGTH,
positive_space_ratio: float = 0.5,
**kwargs
@ -625,22 +625,22 @@ class DashedLine(Line):
except ZeroDivisionError:
return 1
def get_start(self) -> np_vector:
def get_start(self) -> Vect3:
if len(self.submobjects) > 0:
return self.submobjects[0].get_start()
else:
return Line.get_start(self)
def get_end(self) -> np_vector:
def get_end(self) -> Vect3:
if len(self.submobjects) > 0:
return self.submobjects[-1].get_end()
else:
return Line.get_end(self)
def get_first_handle(self) -> np_vector:
def get_first_handle(self) -> Vect3:
return self.submobjects[0].get_points()[1]
def get_last_handle(self) -> np_vector:
def get_last_handle(self) -> Vect3:
return self.submobjects[-1].get_points()[-2]
@ -675,8 +675,8 @@ class Elbow(VMobject):
class Arrow(Line):
def __init__(
self,
start: np_vector | Mobject,
end: np_vector | Mobject,
start: Vect3 | Mobject,
end: Vect3 | Mobject,
stroke_color: ManimColor = GREY_A,
stroke_width: float = 5,
buff: float = 0.25,
@ -701,8 +701,8 @@ class Arrow(Line):
def set_points_by_ends(
self,
start: np_vector,
end: np_vector,
start: Vect3,
end: Vect3,
buff: float = 0,
path_arc: float = 0
):
@ -766,8 +766,8 @@ class Arrow(Line):
class FillArrow(Line):
def __init__(
self,
start: np_vector | Mobject = LEFT,
end: np_vector | Mobject = LEFT,
start: Vect3 | Mobject = LEFT,
end: Vect3 | Mobject = LEFT,
fill_color: ManimColor = GREY_A,
fill_opacity: float = 1.0,
stroke_width: float = 0.0,
@ -795,8 +795,8 @@ class FillArrow(Line):
def set_points_by_ends(
self,
start: np_vector,
end: np_vector,
start: Vect3,
end: Vect3,
buff: float = 0,
path_arc: float = 0
) -> None:
@ -868,15 +868,15 @@ class FillArrow(Line):
)
return self
def get_start(self) -> np_vector:
def get_start(self) -> Vect3:
nppc = self.n_points_per_curve
points = self.get_points()
return (points[0] + points[-nppc]) / 2
def get_end(self) -> np_vector:
def get_end(self) -> Vect3:
return self.get_points()[self.tip_index]
def put_start_and_end_on(self, start: np_vector, end: np_vector):
def put_start_and_end_on(self, start: Vect3, end: Vect3):
self.set_points_by_ends(start, end, buff=0, path_arc=self.path_arc)
return self
@ -899,7 +899,7 @@ class FillArrow(Line):
class Vector(Arrow):
def __init__(
self,
direction: np_vector = RIGHT,
direction: Vect3 = RIGHT,
buff: float = 0.0,
**kwargs
):
@ -911,10 +911,10 @@ class Vector(Arrow):
class CubicBezier(VMobject):
def __init__(
self,
a0: np_vector,
h0: np_vector,
h1: np_vector,
a1: np_vector,
a0: Vect3,
h0: Vect3,
h1: Vect3,
a1: Vect3,
**kwargs
):
super().__init__(**kwargs)
@ -922,11 +922,11 @@ class CubicBezier(VMobject):
class Polygon(VMobject):
def __init__(self, *vertices: np_vector, **kwargs):
def __init__(self, *vertices: Vect3, **kwargs):
super().__init__(**kwargs)
self.set_points_as_corners([*vertices, vertices[0]])
def get_vertices(self) -> list[np_vector]:
def get_vertices(self) -> list[Vect3]:
return self.get_start_anchors()
def round_corners(self, radius: float | None = None):
@ -976,7 +976,7 @@ class Polygon(VMobject):
class Polyline(VMobject):
def __init__(self, *vertices: np_vector, **kwargs):
def __init__(self, *vertices: Vect3, **kwargs):
super().__init__(**kwargs)
self.set_points_as_corners(vertices)
@ -1031,13 +1031,13 @@ class ArrowTip(Triangle):
self.data["points"] = Dot().set_width(h).get_points()
self.rotate(angle)
def get_base(self) -> np_vector:
def get_base(self) -> Vect3:
return self.point_from_proportion(0.5)
def get_tip_point(self) -> np_vector:
def get_tip_point(self) -> Vect3:
return self.get_points()[0]
def get_vector(self) -> np_vector:
def get_vector(self) -> Vect3:
return self.get_tip_point() - self.get_base()
def get_angle(self) -> float:

View file

@ -21,7 +21,7 @@ if TYPE_CHECKING:
from typing import Sequence
import numpy.typing as npt
from manimlib.mobject.mobject import Mobject
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
VECTOR_LABEL_SCALE_FACTOR = 0.8
@ -82,7 +82,7 @@ class Matrix(VMobject):
add_background_rectangles_to_entries: bool = False,
include_background_rectangle: bool = False,
element_config: dict = dict(),
element_alignment_corner: np_vector = DOWN,
element_alignment_corner: Vect3 = DOWN,
**kwargs
):
"""
@ -123,7 +123,7 @@ class Matrix(VMobject):
matrix: list[list[Mobject]],
v_buff: float,
h_buff: float,
aligned_corner: np_vector,
aligned_corner: Vect3,
):
for i, row in enumerate(matrix):
for j, elem in enumerate(row):
@ -193,7 +193,7 @@ class IntegerMatrix(Matrix):
def __init__(
self,
matrix: npt.ArrayLike,
element_alignment_corner: np_vector = UP,
element_alignment_corner: Vect3 = UP,
**kwargs
):
super().__init__(matrix, element_alignment_corner=element_alignment_corner, **kwargs)

View file

@ -48,7 +48,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Callable, Iterable, Sequence, Union, Tuple
import numpy.typing as npt
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3, Vect4
TimeBasedUpdater = Callable[["Mobject", float], None]
NonTimeUpdater = Callable[["Mobject"], None]
@ -200,8 +200,8 @@ class Mobject(object):
def apply_points_function(
self,
func: Callable[[np.ndarray], np.ndarray],
about_point: np_vector = None,
about_edge: np_vector = ORIGIN,
about_point: Vect3 = None,
about_edge: Vect3 = ORIGIN,
works_on_bounding_box: bool = False
):
if about_point is None and about_edge is not None:
@ -233,7 +233,7 @@ class Mobject(object):
self.set_points(mobject.get_points())
return self
def get_points(self) -> np_vector:
def get_points(self) -> Vect3:
return self.data["points"]
def clear_points(self) -> None:
@ -242,7 +242,7 @@ class Mobject(object):
def get_num_points(self) -> int:
return len(self.data["points"])
def get_all_points(self) -> np_vector:
def get_all_points(self) -> Vect3:
if self.submobjects:
return np.vstack([sm.get_points() for sm in self.get_family()])
else:
@ -251,13 +251,13 @@ class Mobject(object):
def has_points(self) -> bool:
return self.get_num_points() > 0
def get_bounding_box(self) -> np_vector:
def get_bounding_box(self) -> Vect3:
if self.needs_new_bounding_box:
self.data["bounding_box"] = self.compute_bounding_box()
self.needs_new_bounding_box = False
return self.data["bounding_box"]
def compute_bounding_box(self) -> np_vector:
def compute_bounding_box(self) -> Vect3:
all_points = np.vstack([
self.get_points(),
*(
@ -289,7 +289,7 @@ class Mobject(object):
def are_points_touching(
self,
points: np_vector,
points: Vect3,
buff: float = 0
) -> bool:
bb = self.get_bounding_box()
@ -299,7 +299,7 @@ class Mobject(object):
def is_point_touching(
self,
point: np_vector,
point: Vect3,
buff: float = 0
) -> bool:
return self.are_points_touching(np.array(point, ndmin=2), buff)[0]
@ -424,7 +424,7 @@ class Mobject(object):
def arrange(
self,
direction: np_vector = RIGHT,
direction: Vect3 = RIGHT,
center: bool = True,
**kwargs
):
@ -444,7 +444,7 @@ class Mobject(object):
buff_ratio: float | None = None,
h_buff_ratio: float = 0.5,
v_buff_ratio: float = 0.5,
aligned_edge: np_vector = ORIGIN,
aligned_edge: Vect3 = ORIGIN,
fill_rows_first: bool = True
):
submobs = self.submobjects
@ -827,7 +827,7 @@ class Mobject(object):
# Transforming operations
def shift(self, vector: np_vector):
def shift(self, vector: Vect3):
self.apply_points_function(
lambda points: points + vector,
about_edge=None,
@ -839,8 +839,8 @@ class Mobject(object):
self,
scale_factor: float | npt.ArrayLike,
min_scale_factor: float = 1e-8,
about_point: np_vector | None = None,
about_edge: np_vector = ORIGIN
about_point: Vect3 | None = None,
about_edge: Vect3 = ORIGIN
):
"""
Default behavior is to scale about the center of the mobject.
@ -877,14 +877,14 @@ class Mobject(object):
self.apply_points_function(func, works_on_bounding_box=True, **kwargs)
return self
def rotate_about_origin(self, angle: float, axis: np_vector = OUT):
def rotate_about_origin(self, angle: float, axis: Vect3 = OUT):
return self.rotate(angle, axis, about_point=ORIGIN)
def rotate(
self,
angle: float,
axis: np_vector = OUT,
about_point: np_vector | None = None,
axis: Vect3 = OUT,
about_point: Vect3 | None = None,
**kwargs
):
rot_matrix_T = rotation_matrix_transpose(angle, axis)
@ -895,7 +895,7 @@ class Mobject(object):
)
return self
def flip(self, axis: np_vector = UP, **kwargs):
def flip(self, axis: Vect3 = UP, **kwargs):
return self.rotate(TAU / 2, axis, **kwargs)
def apply_function(self, function: Callable[[np.ndarray], np.ndarray], **kwargs):
@ -946,8 +946,8 @@ class Mobject(object):
def wag(
self,
direction: np_vector = RIGHT,
axis: np_vector = DOWN,
direction: Vect3 = RIGHT,
axis: Vect3 = DOWN,
wag_factor: float = 1.0
):
for mob in self.family_members_with_points():
@ -969,7 +969,7 @@ class Mobject(object):
def align_on_border(
self,
direction: np_vector,
direction: Vect3,
buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER
):
"""
@ -985,27 +985,27 @@ class Mobject(object):
def to_corner(
self,
corner: np_vector = LEFT + DOWN,
corner: Vect3 = LEFT + DOWN,
buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER
):
return self.align_on_border(corner, buff)
def to_edge(
self,
edge: np_vector = LEFT,
edge: Vect3 = LEFT,
buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER
):
return self.align_on_border(edge, buff)
def next_to(
self,
mobject_or_point: Mobject | np_vector,
direction: np_vector = RIGHT,
mobject_or_point: Mobject | Vect3,
direction: Vect3 = RIGHT,
buff: float = DEFAULT_MOBJECT_TO_MOBJECT_BUFFER,
aligned_edge: np_vector = ORIGIN,
aligned_edge: Vect3 = ORIGIN,
submobject_to_align: Mobject | None = None,
index_of_submobject_to_align: int | slice | None = None,
coor_mask: np_vector = np.array([1, 1, 1]),
coor_mask: Vect3 = np.array([1, 1, 1]),
):
if isinstance(mobject_or_point, Mobject):
mob = mobject_or_point
@ -1050,7 +1050,7 @@ class Mobject(object):
return True
return False
def stretch_about_point(self, factor: float, dim: int, point: np_vector):
def stretch_about_point(self, factor: float, dim: int, point: Vect3):
return self.stretch(factor, dim, about_point=point)
def stretch_in_place(self, factor: float, dim: int):
@ -1115,20 +1115,20 @@ class Mobject(object):
self.set_depth(min_depth, **kwargs)
return self
def set_coord(self, value: float, dim: int, direction: np_vector = ORIGIN):
def set_coord(self, value: float, dim: int, direction: Vect3 = ORIGIN):
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: np_vector = ORIGIN):
def set_x(self, x: float, direction: Vect3 = ORIGIN):
return self.set_coord(x, 0, direction)
def set_y(self, y: float, direction: np_vector = ORIGIN):
def set_y(self, y: float, direction: Vect3 = ORIGIN):
return self.set_coord(y, 1, direction)
def set_z(self, z: float, direction: np_vector = ORIGIN):
def set_z(self, z: float, direction: Vect3 = ORIGIN):
return self.set_coord(z, 2, direction)
def space_out_submobjects(self, factor: float = 1.5, **kwargs):
@ -1139,9 +1139,9 @@ class Mobject(object):
def move_to(
self,
point_or_mobject: Mobject | np_vector,
aligned_edge: np_vector = ORIGIN,
coor_mask: np_vector = np.array([1, 1, 1])
point_or_mobject: Mobject | Vect3,
aligned_edge: Vect3 = ORIGIN,
coor_mask: Vect3 = np.array([1, 1, 1])
):
if isinstance(point_or_mobject, Mobject):
target = point_or_mobject.get_bounding_box_point(aligned_edge)
@ -1179,7 +1179,7 @@ class Mobject(object):
self.scale((length + buff) / length)
return self
def put_start_and_end_on(self, start: np_vector, end: np_vector):
def put_start_and_end_on(self, start: Vect3, end: Vect3):
curr_start, curr_end = self.get_start_and_end()
curr_vect = curr_end - curr_start
if np.all(curr_vect == 0):
@ -1213,7 +1213,7 @@ class Mobject(object):
def set_color_by_rgba_func(
self,
func: Callable[[np.ndarray], Sequence[float]],
func: Callable[[Vect3], Vect4],
recurse: bool = True
):
"""
@ -1226,7 +1226,7 @@ class Mobject(object):
def set_color_by_rgb_func(
self,
func: Callable[[np.ndarray], Sequence[float]],
func: Callable[[Vect3], Vect3],
opacity: float = 1,
recurse: bool = True
):
@ -1373,7 +1373,7 @@ class Mobject(object):
# Getters
def get_bounding_box_point(self, direction: np_vector) -> np_vector:
def get_bounding_box_point(self, direction: Vect3) -> Vect3:
bb = self.get_bounding_box()
indices = (np.sign(direction) + 1).astype(int)
return np.array([
@ -1381,10 +1381,10 @@ class Mobject(object):
for i in range(3)
])
def get_edge_center(self, direction: np_vector) -> np_vector:
def get_edge_center(self, direction: Vect3) -> Vect3:
return self.get_bounding_box_point(direction)
def get_corner(self, direction: np_vector) -> np_vector:
def get_corner(self, direction: Vect3) -> Vect3:
return self.get_bounding_box_point(direction)
def get_all_corners(self):
@ -1394,13 +1394,13 @@ class Mobject(object):
for indices in it.product([0, 2], repeat=3)
])
def get_center(self) -> np_vector:
def get_center(self) -> Vect3:
return self.get_bounding_box()[1]
def get_center_of_mass(self) -> np_vector:
def get_center_of_mass(self) -> Vect3:
return self.get_all_points().mean(0)
def get_boundary_point(self, direction: np_vector) -> np_vector:
def get_boundary_point(self, direction: Vect3) -> Vect3:
all_points = self.get_all_points()
boundary_directions = all_points - self.get_center()
norms = np.linalg.norm(boundary_directions, axis=1)
@ -1408,7 +1408,7 @@ class Mobject(object):
index = np.argmax(np.dot(boundary_directions, np.array(direction).T))
return all_points[index]
def get_continuous_bounding_box_point(self, direction: np_vector) -> np_vector:
def get_continuous_bounding_box_point(self, direction: Vect3) -> Vect3:
dl, center, ur = self.get_bounding_box()
corner_vect = (ur - center)
return center + direction / np.max(np.abs(np.true_divide(
@ -1417,22 +1417,22 @@ class Mobject(object):
where=((corner_vect) != 0)
)))
def get_top(self) -> np_vector:
def get_top(self) -> Vect3:
return self.get_edge_center(UP)
def get_bottom(self) -> np_vector:
def get_bottom(self) -> Vect3:
return self.get_edge_center(DOWN)
def get_right(self) -> np_vector:
def get_right(self) -> Vect3:
return self.get_edge_center(RIGHT)
def get_left(self) -> np_vector:
def get_left(self) -> Vect3:
return self.get_edge_center(LEFT)
def get_zenith(self) -> np_vector:
def get_zenith(self) -> Vect3:
return self.get_edge_center(OUT)
def get_nadir(self) -> np_vector:
def get_nadir(self) -> Vect3:
return self.get_edge_center(IN)
def length_over_dim(self, dim: int) -> float:
@ -1448,7 +1448,7 @@ class Mobject(object):
def get_depth(self) -> float:
return self.length_over_dim(2)
def get_coord(self, dim: int, direction: np_vector = ORIGIN) -> float:
def get_coord(self, dim: int, direction: Vect3 = ORIGIN) -> float:
"""
Meant to generalize get_x, get_y, get_z
"""
@ -1463,20 +1463,20 @@ class Mobject(object):
def get_z(self, direction=ORIGIN) -> float:
return self.get_coord(2, direction)
def get_start(self) -> np_vector:
def get_start(self) -> Vect3:
self.throw_error_if_no_points()
return self.get_points()[0].copy()
def get_end(self) -> np_vector:
def get_end(self) -> Vect3:
self.throw_error_if_no_points()
return self.get_points()[-1].copy()
def get_start_and_end(self) -> tuple[np_vector, np_vector]:
def get_start_and_end(self) -> tuple[Vect3, Vect3]:
self.throw_error_if_no_points()
points = self.get_points()
return (points[0].copy(), points[-1].copy())
def point_from_proportion(self, alpha: float) -> np_vector:
def point_from_proportion(self, alpha: float) -> Vect3:
points = self.get_points()
i, subalpha = integer_interpolate(0, len(points) - 1, alpha)
return interpolate(points[i], points[i + 1], subalpha)
@ -1523,9 +1523,9 @@ class Mobject(object):
def match_coord(
self,
mobject_or_point: Mobject | np_vector,
mobject_or_point: Mobject | Vect3,
dim: int,
direction: np_vector = ORIGIN
direction: Vect3 = ORIGIN
):
if isinstance(mobject_or_point, Mobject):
coord = mobject_or_point.get_coord(dim, direction)
@ -1535,29 +1535,29 @@ class Mobject(object):
def match_x(
self,
mobject_or_point: Mobject | np_vector,
direction: np_vector = ORIGIN
mobject_or_point: Mobject | Vect3,
direction: Vect3 = ORIGIN
):
return self.match_coord(mobject_or_point, 0, direction)
def match_y(
self,
mobject_or_point: Mobject | np_vector,
direction: np_vector = ORIGIN
mobject_or_point: Mobject | Vect3,
direction: Vect3 = ORIGIN
):
return self.match_coord(mobject_or_point, 1, direction)
def match_z(
self,
mobject_or_point: Mobject | np_vector,
direction: np_vector = ORIGIN
mobject_or_point: Mobject | Vect3,
direction: Vect3 = ORIGIN
):
return self.match_coord(mobject_or_point, 2, direction)
def align_to(
self,
mobject_or_point: Mobject | np_vector,
direction: np_vector = ORIGIN
mobject_or_point: Mobject | Vect3,
direction: Vect3 = ORIGIN
):
"""
Examples:
@ -1871,7 +1871,7 @@ class Mobject(object):
)
return self
def get_resized_shader_data_array(self, length: int) -> np_vector:
def get_resized_shader_data_array(self, length: int) -> Vect3:
# If possible, try to populate an existing array, rather
# than recreating it each frame
if len(self.shader_data) != length:
@ -1880,7 +1880,7 @@ class Mobject(object):
def read_data_to_shader(
self,
shader_data: np_vector,
shader_data: Vect3,
shader_data_key: str,
data_key: str
):
@ -2024,7 +2024,7 @@ class Group(Mobject):
class Point(Mobject):
def __init__(
self,
location: np_vector = ORIGIN,
location: Vect3 = ORIGIN,
artificial_width: float = 1e-6,
artificial_height: float = 1e-6,
**kwargs
@ -2040,10 +2040,10 @@ class Point(Mobject):
def get_height(self) -> float:
return self.artificial_height
def get_location(self) -> np_vector:
def get_location(self) -> Vect3:
return self.get_points()[0].copy()
def get_bounding_box_point(self, *args, **kwargs) -> np_vector:
def get_bounding_box_point(self, *args, **kwargs) -> Vect3:
return self.get_location()
def set_location(self, new_loc: npt.ArrayLike):

View file

@ -17,7 +17,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Iterable
from manimlib.typing import ManimColor, np_vector, RangeSpecifier
from manimlib.typing import ManimColor, Vect3, RangeSpecifier
class NumberLine(Line):
@ -36,7 +36,7 @@ class NumberLine(Line):
# Change name
numbers_with_elongated_ticks: list[float] = [],
include_numbers: bool = False,
line_to_number_direction: np_vector = DOWN,
line_to_number_direction: Vect3 = DOWN,
line_to_number_buff: float = MED_SMALL_BUFF,
include_tip: bool = False,
tip_config: dict = dict(
@ -118,11 +118,11 @@ class NumberLine(Line):
def get_tick_marks(self) -> VGroup:
return self.ticks
def number_to_point(self, number: float | np.ndarray) -> np_vector:
def number_to_point(self, number: float | np.ndarray) -> Vect3:
alpha = (number - self.x_min) / (self.x_max - self.x_min)
return outer_interpolate(self.get_start(), self.get_end(), alpha)
def point_to_number(self, point: np_vector) -> float:
def point_to_number(self, point: Vect3) -> float:
points = self.get_points()
start = points[0]
end = points[-1]
@ -133,11 +133,11 @@ class NumberLine(Line):
)
return interpolate(self.x_min, self.x_max, proportion)
def n2p(self, number: float) -> np_vector:
def n2p(self, number: float) -> Vect3:
"""Abbreviation for number_to_point"""
return self.number_to_point(number)
def p2n(self, point: np_vector) -> float:
def p2n(self, point: Vect3) -> float:
"""Abbreviation for point_to_number"""
return self.point_to_number(point)
@ -147,7 +147,7 @@ class NumberLine(Line):
def get_number_mobject(
self,
x: float,
direction: np_vector | None = None,
direction: Vect3 | None = None,
buff: float | None = None,
unit: float = 1.0,
unit_tex: str = "",

View file

@ -12,7 +12,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import TypeVar
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
T = TypeVar("T", bound=VMobject)
@ -31,7 +31,7 @@ class DecimalNumber(VMobject):
show_ellipsis: bool = False,
unit: str | None = None, # Aligned to bottom unless it starts with "^"
include_background_rectangle: bool = False,
edge_to_fix: np_vector = LEFT,
edge_to_fix: Vect3 = LEFT,
font_size: int = 48,
text_config: dict = dict(), # Do not pass in font_size here
**kwargs

View file

@ -27,14 +27,14 @@ if TYPE_CHECKING:
from manimlib.animation.animation import Animation
from manimlib.mobject.mobject import Mobject
from manimlib.typing import np_vector
from manimlib.typing import Vect3
class Brace(SingleStringTex):
def __init__(
self,
mobject: Mobject,
direction: np_vector = DOWN,
direction: Vect3 = DOWN,
buff: float = 0.2,
tex_string: str = R"\underbrace{\qquad}",
**kwargs

View file

@ -60,7 +60,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Tuple, Sequence, Callable
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
class Checkmark(TexTextFromPresetString):
@ -342,8 +342,8 @@ class Bubble(SVGMobject):
def __init__(
self,
direction: np_vector = LEFT,
center_point: np_vector = ORIGIN,
direction: Vect3 = LEFT,
center_point: Vect3 = ORIGIN,
content_scale_factor: float = 0.7,
height: float = 4.0,
width: float = 8.0,

View file

@ -23,7 +23,7 @@ from manimlib.utils.space_ops import z_to_vector
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Tuple, TypeVar
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
T = TypeVar("T", bound=Mobject)
@ -145,7 +145,7 @@ class Cylinder(Surface):
resolution: Tuple[int, int] = (101, 11),
height: float = 2,
radius: float = 1,
axis: np_vector = OUT,
axis: Vect3 = OUT,
**kwargs,
):
self.height = height
@ -173,8 +173,8 @@ class Cylinder(Surface):
class Line3D(Cylinder):
def __init__(
self,
start: np_vector,
end: np_vector,
start: Vect3,
end: Vect3,
width: float = 0.05,
resolution: Tuple[int, int] = (21, 25),
**kwargs

View file

@ -13,7 +13,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
import numpy.typing as npt
from typing import Sequence, Tuple
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
DEFAULT_DOT_RADIUS = 0.05
@ -32,7 +32,7 @@ class DotCloud(PMobject):
def __init__(
self,
points: Sequence[np_vector] | None = None,
points: Sequence[Vect3] | None = None,
color: ManimColor = GREY_C,
opacity: float = 1.0,
radius: float = DEFAULT_DOT_RADIUS,
@ -160,7 +160,7 @@ class TrueDot(DotCloud):
class GlowDots(DotCloud):
def __init__(
self,
points: Sequence[np_vector] | None = None,
points: Sequence[Vect3] | None = None,
color: ManimColor = YELLOW,
radius: float = DEFAULT_GLOW_DOT_RADIUS,
glow_factor: float = 2.0,

View file

@ -13,7 +13,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Sequence, Tuple
from manimlib.typing import np_vector
from manimlib.typing import Vect3
class ImageMobject(Mobject):
@ -55,7 +55,7 @@ class ImageMobject(Mobject):
def set_color(self, color, opacity=None, recurse=None):
return self
def point_to_rgb(self, point: np_vector) -> np_vector:
def point_to_rgb(self, point: Vect3) -> Vect3:
x0, y0 = self.get_corner(UL)[:2]
x1, y1 = self.get_corner(DR)[:2]
x_alpha = inverse_interpolate(x0, x1, point[0])

View file

@ -15,7 +15,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Callable, Sequence
import numpy.typing as npt
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
class PMobject(Mobject):
@ -32,7 +32,7 @@ class PMobject(Mobject):
self.data[key] = resize_func(self.data[key], size)
return self
def set_points(self, points: np_vector):
def set_points(self, points: Vect3):
if len(points) == 0:
points = np.zeros((0, 3))
super().set_points(points)
@ -41,8 +41,8 @@ class PMobject(Mobject):
def add_points(
self,
points: Sequence[np_vector],
rgbas: np_vector | None = None,
points: Sequence[Vect3],
rgbas: Vect3 | None = None,
color: ManimColor | None = None,
opacity: float | None = None
):
@ -63,7 +63,7 @@ class PMobject(Mobject):
self.data["rgbas"][-len(rgbas):] = rgbas
return self
def add_point(self, point: np_vector, rgba=None, color=None, opacity=None):
def add_point(self, point: Vect3, rgba=None, color=None, opacity=None):
rgbas = None if rgba is None else [rgba]
self.add_points([point], rgbas, color, opacity)
return self
@ -90,7 +90,7 @@ class PMobject(Mobject):
mob.data[key] = mob.data[key][to_keep]
return self
def sort_points(self, function: Callable[[np_vector], None] = lambda p: p[0]):
def sort_points(self, function: Callable[[Vect3], None] = lambda p: p[0]):
"""
function is any map from R^3 to R
"""

View file

@ -18,7 +18,7 @@ if TYPE_CHECKING:
from typing import Callable, Iterable, Sequence, Tuple
from manimlib.camera.camera import Camera
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
class Surface(Mobject):
@ -114,12 +114,12 @@ class Surface(Mobject):
def get_surface_points_and_nudged_points(
self
) -> tuple[np_vector, np_vector, np_vector]:
) -> tuple[Vect3, Vect3, Vect3]:
points = self.get_points()
k = len(points) // 3
return points[:k], points[k:2 * k], points[2 * k:]
def get_unit_normals(self) -> np_vector:
def get_unit_normals(self) -> Vect3:
s_points, du_points, dv_points = self.get_surface_points_and_nudged_points()
normals = np.cross(
(du_points - s_points) / self.epsilon,
@ -150,12 +150,12 @@ class Surface(Mobject):
def get_partial_points_array(
self,
points: np_vector,
points: Vect3,
a: float,
b: float,
resolution: Sequence[int],
axis: int
) -> np_vector:
) -> Vect3:
if len(points) == 0:
return points
nu, nv = resolution[:2]
@ -188,7 +188,7 @@ class Surface(Mobject):
).reshape(shape)
return points.reshape((nu * nv, *resolution[2:]))
def sort_faces_back_to_front(self, vect: np_vector = OUT):
def sort_faces_back_to_front(self, vect: Vect3 = OUT):
tri_is = self.triangle_indices
indices = list(range(len(tri_is) // 3))
points = self.get_points()

View file

@ -42,7 +42,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Callable, Iterable, Sequence, Tuple
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3, Vect4
DEFAULT_STROKE_COLOR = GREY_A
DEFAULT_FILL_COLOR = GREY_C
@ -149,7 +149,7 @@ class VMobject(Mobject):
def set_rgba_array(
self,
rgba_array: np_vector,
rgba_array: Vect3,
name: str | None = None,
recurse: bool = False
):
@ -213,10 +213,10 @@ class VMobject(Mobject):
self,
fill_color: ManimColor | Iterable[ManimColor] | None = None,
fill_opacity: float | Iterable[float] | None = None,
fill_rgba: np_vector | None = None,
fill_rgba: Vect4 | None = None,
stroke_color: ManimColor | Iterable[ManimColor] | None = None,
stroke_opacity: float | Iterable[float] | None = None,
stroke_rgba: np_vector | None = None,
stroke_rgba: Vect4 | None = None,
stroke_width: float | Iterable[float] | None = None,
stroke_background: bool = True,
reflectiveness: float | None = None,
@ -322,7 +322,7 @@ class VMobject(Mobject):
for rgba in self.data['fill_rgba']
]
def get_fill_opacities(self) -> np_vector:
def get_fill_opacities(self) -> np.ndarray:
return self.data['fill_rgba'][:, 3]
def get_stroke_colors(self) -> list[str]:
@ -331,10 +331,10 @@ class VMobject(Mobject):
for rgba in self.data['stroke_rgba']
]
def get_stroke_opacities(self) -> np_vector:
def get_stroke_opacities(self) -> np.ndarray:
return self.data['stroke_rgba'][:, 3]
def get_stroke_widths(self) -> np_vector:
def get_stroke_widths(self) -> np.ndarray:
return self.data['stroke_width'][:, 0]
# TODO, it's weird for these to return the first of various lists
@ -356,7 +356,7 @@ class VMobject(Mobject):
def get_stroke_color(self) -> str:
return self.get_stroke_colors()[0]
def get_stroke_width(self) -> float | np_vector:
def get_stroke_width(self) -> float | np.ndarray:
return self.get_stroke_widths()[0]
def get_stroke_opacity(self) -> float:
@ -397,9 +397,9 @@ class VMobject(Mobject):
# Points
def set_anchors_and_handles(
self,
anchors1: np_vector,
handles: np_vector,
anchors2: np_vector
anchors1: Vect3,
handles: Vect3,
anchors2: Vect3
):
assert(len(anchors1) == len(handles) == len(anchors2))
nppc = self.n_points_per_curve
@ -410,26 +410,26 @@ class VMobject(Mobject):
self.set_points(new_points)
return self
def start_new_path(self, point: np_vector):
def start_new_path(self, point: Vect3):
assert(self.get_num_points() % self.n_points_per_curve == 0)
self.append_points([point])
return self
def add_cubic_bezier_curve(
self,
anchor1: np_vector,
handle1: np_vector,
handle2: np_vector,
anchor2: np_vector
anchor1: Vect3,
handle1: Vect3,
handle2: Vect3,
anchor2: Vect3
):
new_points = get_quadratic_approximation_of_cubic(anchor1, handle1, handle2, anchor2)
self.append_points(new_points)
def add_cubic_bezier_curve_to(
self,
handle1: np_vector,
handle2: np_vector,
anchor: np_vector
handle1: Vect3,
handle2: Vect3,
anchor: Vect3
):
"""
Add cubic bezier curve to the path.
@ -443,14 +443,14 @@ class VMobject(Mobject):
else:
self.append_points(quadratic_approx)
def add_quadratic_bezier_curve_to(self, handle: np_vector, anchor: np_vector):
def add_quadratic_bezier_curve_to(self, handle: Vect3, anchor: Vect3):
self.throw_error_if_no_points()
if self.has_new_path_started():
self.append_points([handle, anchor])
else:
self.append_points([self.get_last_point(), handle, anchor])
def add_line_to(self, point: np_vector):
def add_line_to(self, point: Vect3):
end = self.get_points()[-1]
alphas = np.linspace(0, 1, self.n_points_per_curve)
if self.long_lines:
@ -472,7 +472,7 @@ class VMobject(Mobject):
self.append_points(points)
return self
def add_smooth_curve_to(self, point: np_vector):
def add_smooth_curve_to(self, point: Vect3):
if self.has_new_path_started():
self.add_line_to(point)
else:
@ -481,7 +481,7 @@ class VMobject(Mobject):
self.add_quadratic_bezier_curve_to(new_handle, point)
return self
def add_smooth_cubic_curve_to(self, handle: np_vector, point: np_vector):
def add_smooth_cubic_curve_to(self, handle: Vect3, point: Vect3):
self.throw_error_if_no_points()
if self.get_num_points() == 1:
new_handle = self.get_points()[-1]
@ -492,10 +492,10 @@ class VMobject(Mobject):
def has_new_path_started(self) -> bool:
return self.get_num_points() % self.n_points_per_curve == 1
def get_last_point(self) -> np_vector:
def get_last_point(self) -> Vect3:
return self.get_points()[-1]
def get_reflection_of_last_handle(self) -> np_vector:
def get_reflection_of_last_handle(self) -> Vect3:
points = self.get_points()
return 2 * points[-1] - points[-2]
@ -530,12 +530,12 @@ class VMobject(Mobject):
vmob.set_points(np.vstack(new_points))
return self
def add_points_as_corners(self, points: Iterable[np_vector]):
def add_points_as_corners(self, points: Iterable[Vect3]):
for point in points:
self.add_line_to(point)
return points
def set_points_as_corners(self, points: Iterable[np_vector]):
def set_points_as_corners(self, points: Iterable[Vect3]):
nppc = self.n_points_per_curve
points = np.array(points)
self.set_anchors_and_handles(*[
@ -546,7 +546,7 @@ class VMobject(Mobject):
def set_points_smoothly(
self,
points: Iterable[np_vector],
points: Iterable[Vect3],
true_smooth: bool = False
):
self.set_points_as_corners(points)
@ -601,7 +601,7 @@ class VMobject(Mobject):
self.change_anchor_mode("jagged")
return self
def add_subpath(self, points: Sequence[np_vector]):
def add_subpath(self, points: Sequence[Vect3]):
assert(len(points) % self.n_points_per_curve == 0)
self.append_points(points)
return self
@ -617,11 +617,11 @@ class VMobject(Mobject):
return self
#
def consider_points_equals(self, p0: np_vector, p1: np_vector) -> bool:
def consider_points_equals(self, p0: Vect3, p1: Vect3) -> bool:
return get_norm(p1 - p0) < self.tolerance_for_point_equality
# Information about the curve
def get_bezier_tuples_from_points(self, points: Sequence[np_vector]):
def get_bezier_tuples_from_points(self, points: Sequence[Vect3]):
nppc = self.n_points_per_curve
remainder = len(points) % nppc
points = points[:len(points) - remainder]
@ -635,8 +635,8 @@ class VMobject(Mobject):
def get_subpaths_from_points(
self,
points: Sequence[np_vector]
) -> list[Sequence[np_vector]]:
points: Sequence[Vect3]
) -> list[Sequence[Vect3]]:
nppc = self.n_points_per_curve
diffs = points[nppc - 1:-1:nppc] - points[nppc::nppc]
splits = (diffs * diffs).sum(1) > self.tolerance_for_point_equality
@ -653,28 +653,28 @@ class VMobject(Mobject):
if (i2 - i1) >= nppc
]
def get_subpaths(self) -> list[Sequence[np_vector]]:
def get_subpaths(self) -> list[Sequence[Vect3]]:
return self.get_subpaths_from_points(self.get_points())
def get_nth_curve_points(self, n: int) -> np_vector:
def get_nth_curve_points(self, n: int) -> Vect3:
assert(n < self.get_num_curves())
nppc = self.n_points_per_curve
return self.get_points()[nppc * n:nppc * (n + 1)]
def get_nth_curve_function(self, n: int) -> Callable[[float], np_vector]:
def get_nth_curve_function(self, n: int) -> Callable[[float], Vect3]:
return bezier(self.get_nth_curve_points(n))
def get_num_curves(self) -> int:
return self.get_num_points() // self.n_points_per_curve
def quick_point_from_proportion(self, alpha: float) -> np_vector:
def quick_point_from_proportion(self, alpha: float) -> Vect3:
# Assumes all curves have the same length, so is inaccurate
num_curves = self.get_num_curves()
n, residue = integer_interpolate(0, num_curves, alpha)
curve_func = self.get_nth_curve_function(n)
return curve_func(residue)
def point_from_proportion(self, alpha: float) -> np_vector:
def point_from_proportion(self, alpha: float) -> Vect3:
if alpha <= 0:
return self.get_start()
elif alpha >= 1:
@ -696,7 +696,7 @@ class VMobject(Mobject):
residue = inverse_interpolate(partials[i - 1] / full, partials[i] / full, alpha)
return self.get_nth_curve_function(i - 1)(residue)
def get_anchors_and_handles(self) -> list[np_vector]:
def get_anchors_and_handles(self) -> list[Vect3]:
"""
returns anchors1, handles, anchors2,
where (anchors1[i], handles[i], anchors2[i])
@ -710,14 +710,14 @@ class VMobject(Mobject):
for i in range(nppc)
]
def get_start_anchors(self) -> list[np_vector]:
def get_start_anchors(self) -> list[Vect3]:
return self.get_points()[0::self.n_points_per_curve]
def get_end_anchors(self) -> np_vector:
def get_end_anchors(self) -> Vect3:
nppc = self.n_points_per_curve
return self.get_points()[nppc - 1::nppc]
def get_anchors(self) -> np_vector:
def get_anchors(self) -> Vect3:
points = self.get_points()
if len(points) == 1:
return points
@ -726,7 +726,7 @@ class VMobject(Mobject):
self.get_end_anchors(),
))))
def get_points_without_null_curves(self, atol: float = 1e-9) -> np_vector:
def get_points_without_null_curves(self, atol: float = 1e-9) -> Vect3:
nppc = self.n_points_per_curve
points = self.get_points()
distinct_curves = reduce(op.or_, [
@ -746,7 +746,7 @@ class VMobject(Mobject):
norms = np.array([get_norm(d) for d in diffs])
return norms.sum()
def get_area_vector(self) -> np_vector:
def get_area_vector(self) -> Vect3:
# Returns a vector whose length is the area bound by
# the polygon formed by the anchor points, pointing
# in a direction perpendicular to the polygon according
@ -766,7 +766,7 @@ class VMobject(Mobject):
sum((p0[:, 0] + p1[:, 0]) * (p1[:, 1] - p0[:, 1])), # Add up (x1 + x2)*(y2 - y1)
])
def get_unit_normal(self, recompute: bool = False) -> np_vector:
def get_unit_normal(self, recompute: bool = False) -> Vect3:
if not recompute:
return self.data["unit_normal"][0]
@ -851,7 +851,7 @@ class VMobject(Mobject):
mob.set_points(new_points)
return self
def insert_n_curves_to_point_list(self, n: int, points: np_vector):
def insert_n_curves_to_point_list(self, n: int, points: Vect3):
nppc = self.n_points_per_curve
if len(points) == 1:
return np.repeat(points, nppc * n, 0)
@ -953,7 +953,7 @@ class VMobject(Mobject):
mob.needs_new_triangulation = True
return self
def get_triangulation(self, normal_vector: np_vector | None = None):
def get_triangulation(self, normal_vector: Vect3 | None = None):
# Figure out how to triangulate the interior to know
# how to send the points as to the vertex shader.
# First triangles come directly from the points
@ -1022,7 +1022,7 @@ class VMobject(Mobject):
return wrapper
@triggers_refreshed_triangulation
def set_points(self, points: np_vector):
def set_points(self, points: Vect3):
super().set_points(points)
return self
@ -1035,7 +1035,7 @@ class VMobject(Mobject):
@triggers_refreshed_triangulation
def apply_function(
self,
function: Callable[[np_vector], np_vector],
function: Callable[[Vect3], Vect3],
make_smooth: bool = False,
**kwargs
):
@ -1044,7 +1044,7 @@ class VMobject(Mobject):
self.make_approximately_smooth()
return self
def flip(self, axis: np_vector = UP, **kwargs):
def flip(self, axis: Vect3 = UP, **kwargs):
super().flip(axis, **kwargs)
self.refresh_unit_normal()
self.refresh_triangulation()

View file

@ -23,7 +23,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Callable, Iterable, Sequence, TypeVar, Tuple
import numpy.typing as npt
from manimlib.typing import ManimColor, np_vector
from manimlib.typing import ManimColor, Vect3
from manimlib.mobject.coordinate_systems import CoordinateSystem
from manimlib.mobject.mobject import Mobject
@ -35,7 +35,7 @@ def get_vectorized_rgb_gradient_function(
min_value: T,
max_value: T,
color_map: str
) -> Callable[[npt.ArrayLike], np_vector]:
) -> Callable[[npt.ArrayLike], Vect3]:
rgbs = np.array(get_colormap_list(color_map))
def func(values):
@ -57,14 +57,14 @@ def get_rgb_gradient_function(
min_value: T,
max_value: T,
color_map: str
) -> Callable[[T], np_vector]:
) -> Callable[[T], Vect3]:
vectorized_func = get_vectorized_rgb_gradient_function(min_value, max_value, color_map)
return lambda value: vectorized_func([value])[0]
def move_along_vector_field(
mobject: Mobject,
func: Callable[[np_vector], np_vector]
func: Callable[[Vect3], Vect3]
) -> Mobject:
mobject.add_updater(
lambda m, dt: m.shift(
@ -76,7 +76,7 @@ def move_along_vector_field(
def move_submobjects_along_vector_field(
mobject: Mobject,
func: Callable[[np_vector], np_vector]
func: Callable[[Vect3], Vect3]
) -> Mobject:
def apply_nudge(mob, dt):
for submob in mob:
@ -107,7 +107,7 @@ def move_points_along_vector_field(
def get_sample_points_from_coordinate_system(
coordinate_system: CoordinateSystem,
step_multiple: float
) -> it.product[tuple[np_vector, ...]]:
) -> it.product[tuple[Vect3, ...]]:
ranges = []
for range_args in coordinate_system.get_all_ranges():
_min, _max, step = range_args
@ -224,7 +224,7 @@ class StreamLines(VGroup):
self.draw_lines()
self.init_style()
def point_func(self, point: np_vector) -> np_vector:
def point_func(self, point: Vect3) -> Vect3:
in_coords = self.coordinate_system.p2c(point)
out_coords = self.func(*in_coords)
return self.coordinate_system.c2p(*out_coords)
@ -254,7 +254,7 @@ class StreamLines(VGroup):
lines.append(line)
self.set_submobjects(lines)
def get_start_points(self) -> np_vector:
def get_start_points(self) -> Vect3:
cs = self.coordinate_system
sample_coords = get_sample_points_from_coordinate_system(
cs, self.step_multiple,

View file

@ -11,7 +11,6 @@ if TYPE_CHECKING:
# TODO, Nothing about these actually specifies length,
# they are so far just about code readability
np_vector = np.ndarray[int, np.dtype[np.float64]]
Vect2 = np.ndarray[int, np.dtype[np.float64]] # TODO, specify length of 2
Vect3 = np.ndarray[int, np.dtype[np.float64]] # TODO, specify length of 3
Vect4 = np.ndarray[int, np.dtype[np.float64]] # TODO, specify length of 4