选择类型提示¶
为了提供最佳用户体验,正确选择类型提示至关重要。Manim 提供了大量不同类型的提示,选择合适的可能很困难。本指南旨在帮助您选择适用于特定场景的正确类型。
第一步是确定您的类型提示属于哪个类别。
坐标¶
坐标包含两个主要类别:点和向量。
点¶
点的用途非常直接:它们表示空间中的一个点。例如
def print_point2D(coord: Point2DLike) -> None:
x, y = coord
print(f"Point at {x=},{y=}")
def print_point3D(coord: Point3DLike) -> None:
x, y, z = coord
print(f"Point at {x=},{y=},{z=}")
def print_point_array(coords: Point2DLike_Array | Point3DLike_Array) -> None:
for coord in coords:
if len(coord) == 2:
# it's a Point2DLike
print_point2D(coord)
else:
# it's a Point3DLike
print_point3D(coord)
def shift_point_up(coord: Point3DLike) -> Point3D:
result = np.asarray(coord)
result += UP
print(f"New point: {result}")
return result
请注意,最后一个函数 shift_point_up()
接受 Point3DLike
作为参数,并返回 Point3D
。一个 Point3D
始终表示由 3 个浮点数组成的 NumPy 数组,而 Point3DLike
可以表示任何类似于 3D 点的东西:要么是一个 NumPy 数组,要么是一个包含 3 个浮点数的元组/列表,因此有了 Like
这个词。同样的情况也发生在 Point2D
、Point2D_Array
和 Point3D_Array
,以及它们对应的 Like
类型 Point2DLike
、Point2DLike_Array
和 Point3DLike_Array
上。
函数类型标注的规则是:参数类型应尽可能宽泛,返回类型应尽可能具体。 因此,对于旨在供用户调用的函数,如果可能,我们应始终接受 Like
类型作为参数,并返回 NumPy、非 Like
类型。 主要原因是,为了给那些可能更倾向于传递元组或列表作为参数而不是 NumPy 数组的用户提供更大的灵活性,因为这更方便。最后一个函数 shift_point_up()
就是一个例子。
不应由用户调用的内部函数,如果需要,可以接受非 Like
参数。
向量¶
向量与点有许多相似之处。然而,它们具有不同的含义。向量应该用来表示方向。例如,考虑这个稍微有点刻意的函数:
M = TypeVar("M", bound=Mobject) # allow any mobject
def shift_mobject(mob: M, direction: Vector3D, scale_factor: float = 1) -> M:
return mob.shift(direction * scale_factor)
这里我们看到了一个重要的区别示例。direction
不应该被标注为 Point3D
,因为它表示的是一个用来移动 Mobject
的方向,而不是空间中的一个位置。
一般来说,如果一个参数被称为 direction
或 axis
,它应该被类型提示为某种形式的 VectorND
。
警告
这并非总是如此。例如,从 Manim 0.18.0 版本开始,Vector
Mobject 的 `direction` 参数应为 Point2DLike | Point3DLike
,因为它也可以接受 tuple[float, float]
和 tuple[float, float, float]
。
颜色¶
Manim 提供的用于处理颜色的接口是 ManimColor
。Manim 支持的主要颜色类型是 RGB、RGBA 和 HSV。您需要根据函数使用的颜色类型添加类型提示。如果任何颜色都适用,您需要类似这样的标注:
if TYPE_CHECKING:
from manim.utils.color import ParsableManimColor
# type hint stuff with ParsableManimColor
贝塞尔曲线¶
Manim 内部使用点集合来表示 Mobject
。对于最常用的 Mobject
子类 VMobject
而言,这些点代表贝塞尔曲线,它是一种使用一系列点来表示曲线的方式。
注意
要了解更多关于贝塞尔曲线的信息,请查看 https://pomax.github.io/bezierinfo/
Manim 支持两种不同的渲染器,它们各自对贝塞尔曲线有不同的表示方式:Cairo 使用三次贝塞尔曲线,而 OpenGL 使用二次贝塞尔曲线。
类型提示如 BezierPoints
表示一条贝塞尔曲线,而 BezierPath
表示多条贝塞尔曲线。当 BezierPath
中的贝塞尔曲线形成一条单一的连续曲线时,它被称为 Spline
。Manim 还提供了更具体的类型别名,用于处理二次或三次曲线,它们以各自的类型作为前缀(例如,CubicBezierPoints
是一个由恰好 4 个点组成的 BezierPoints
,代表一条三次贝塞尔曲线)。
函数¶
在整个代码库中,使用了许多不同类型的函数。最明显的例子是速率函数,它接受一个浮点数并输出一个浮点数(Callable[[float], float]
)。另一个例子是用于覆盖动画。通常需要将一个 Mobject
映射到一个被覆盖的 Animation
,为此我们有 FunctionOverride
类型提示。
PathFuncType
和 MappingFunction
更具专业性,但与沿路径移动对象或应用函数有关。如果您需要使用它们,您就会明白。
图像¶
Manim 中有几种图像表示方式。最常见的是以表示图像像素的浮点数 NumPy 数组形式。这在 OpenGL 渲染器中尤为常见。
这是 PixelArray
类型提示的用例。有时,Manim 可能会使用 PIL.Image.Image
,它与 PixelArray
不同。在这种情况下,请使用 PIL.Image.Image
类型提示。当然,如果需要更具体的图像类型,也可以进行相应的标注。