Mobject

MK做了一个关于常用 Mobject 的方法的视频: 〔manim教程〕第一讲 物体的位置与坐标变换

虽然 manimgl 对一部分物件进行了更新,但大体还能用,有变化的可以看源码进行修改。

Mobject

class manimlib.mobject.mobject.Mobject(**kwargs)

数学物品(屏幕上的所有物体的超类)

add(*mobjects: manimlib.mobject.mobject.Mobject)

mobjects 添加到子物体中

add_background_rectangle(color: ManimColor | None = None, opacity: float = 0.75, **kwargs)

添加背景矩形

add_background_rectangle_to_submobjects(**kwargs)

给子物件添加背景矩形

add_event_listner(event_type: EventType, event_callback: Callable[[Mobject, dict[str]]])

添加事件侦听

add_to_back(*mobjects: manimlib.mobject.mobject.Mobject)

mobjects 添加到子物体前面(覆盖关系在下)

add_updater(update_function: Updater, index: int | None = None, call_updater: bool = True)

添加 updater 函数

align_on_border(direction: numpy.ndarray, buff: float = 0.5)

direction 这个边界对齐

align_to(mobject_or_point: manimlib.mobject.mobject.Mobject | numpy.ndarray, direction: numpy.ndarray = array([0., 0., 0.]))

对齐

例子: mob1.align_to(mob2, UP) 会将 mob1 垂直移动,顶部与 mob2 的上边缘对齐

append_points(new_points: npt.ArrayLike)

添加锚点

apply_complex_function(function: Callable[[complex], complex], **kwargs)

施加一个复变函数

apply_function(function: Callable[[np.ndarray], np.ndarray], **kwargs)

function 作用到所有锚点上

apply_function_to_position(function: Callable[[np.ndarray], np.ndarray])

给物体所在的位置执行 function

apply_function_to_submobject_positions(function: Callable[[np.ndarray], np.ndarray])

给所有子物体所在的位置执行 function

apply_matrix(matrix: npt.ArrayLike, **kwargs)

matrix 矩阵作用到所有点上

apply_points_function(func: Callable[[np.ndarray], np.ndarray], about_point: np.ndarray = None, about_edge: np.ndarray = array([0., 0., 0.]), works_on_bounding_box: bool = False)

about_point 为不变基准点,或以 about_edge 为不变基准边,对所有点执行 func

are_points_touching(points: numpy.ndarray, buff: float = 0.25) → bool

判断某一点是否在本物件的包围框范围内

arrange(direction: numpy.ndarray = array([1., 0., 0.]), center: bool = True, **kwargs)

将子物件按照 direction 方向排列

arrange_in_grid(n_rows: Optional[int, None] = None, n_cols: Optional[int, None] = None, buff: Optional[float, None] = None, h_buff: Optional[float, None] = None, v_buff: Optional[float, None] = None, buff_ratio: Optional[float, None] = None, h_buff_ratio: float = 0.5, v_buff_ratio: float = 0.5, aligned_edge: numpy.ndarray = array([0., 0., 0.]), fill_rows_first: bool = True)

将子物件按表格方式排列

  • n_rows, n_cols : 行数、列数

  • v_buff, h_buff : 行距、列距

  • aligned_edge : 对齐边缘

become(mobject: manimlib.mobject.mobject.Mobject)

重构物件数据并将它变成传入的 mobject

center()

放到画面中心

clear_event_listners(recurse: bool = True)

清空事件侦听

clear_points() → None

清空物件锚点

clear_updaters(recurse: bool = True)

清空所有的 updater 函数

compute_bounding_box() → numpy.ndarray

计算包围框

digest_mobject_attrs()

确保所有对象属性都包含在子对象列表中

fade(darkness: float = 0.5, recurse: bool = True)

变暗

fix_in_frame()

将物件锁定在屏幕上,常用于 3D 场景需要旋转镜头的情况

flip(axis: numpy.ndarray = array([0., 1., 0.]), **kwargs)

axis 轴翻转

generate_target(use_deepcopy: bool = False)

通过复制自身作为自己的 target, 生成一个 target 属性

get_all_points() → numpy.ndarray

获取物件所有锚点

get_ancestors(extended: bool = False) → list

Returns parents, grandparents, etc. Order of result should be from higher members of the hierarchy down.

If extended is set to true, it includes the ancestors of all family members, e.g. any other parents of a submobject

get_bottom() → numpy.ndarray

获取下边缘中心

get_bounding_box() → numpy.ndarray

获取物件的矩形包围框(碰撞箱)

包含三个元素,分别为左下,中心,右上

get_center() → numpy.ndarray

获取物件中心坐标

get_center_of_mass() → numpy.ndarray

获取重心

get_color() → str

获取颜色

get_coord(dim: int, direction: numpy.ndarray = array([0., 0., 0.])) → float

获取物件在 dim 维度上的坐标

get_corner(direction: numpy.ndarray) → numpy.ndarray

获取某一个角落

get_depth() → float

获取物件深度(即 z 轴方向的宽度)

get_edge_center(direction: numpy.ndarray) → numpy.ndarray

获取某一边缘的中心

get_end() → numpy.ndarray

获取终止点

get_event_listners()

获取事件侦听

get_grid(n_rows: int, n_cols: int, height: Optional[float, None] = None, **kwargs)manimlib.mobject.mobject.Group

Returns a new mobject containing multiple copies of this one arranged in a grid

get_height() → float

获取物件高度

get_left() → numpy.ndarray

获取左边缘中心

get_nadir() → numpy.ndarray

获取内边缘中心(这里的内,指垂直于屏幕向内的平面)

get_num_points() → int

获取锚点数量

get_opacity() → float

获取透明度

get_pieces(n_pieces: int)manimlib.mobject.mobject.Group

将物体拆成 n_pieces 个部分,便于部分解决 3D 中透视问题

get_points() → numpy.ndarray

获取物件锚点

get_reflectiveness() → float

获取反光度

get_right() → numpy.ndarray

获取右边缘中心

get_shader_data()

获取 shader 数据

get_shader_wrapper()

获取 shader 包装

get_shader_wrapper_list() → list

获取 shader 包装列表

get_shadow() → float

获取阴影

get_start() → numpy.ndarray

获取起始点

get_start_and_end()

获取起始点和终止点

get_top() → numpy.ndarray

获取上边缘中心

get_width() → float

获取物件宽度

get_x(direction=array([0., 0., 0.])) → float

获取 x 坐标

get_y(direction=array([0., 0., 0.])) → float

获取 y 坐标

get_z(direction=array([0., 0., 0.])) → float

获取 z 坐标

get_zenith() → numpy.ndarray

获取外边缘中心(这里的外,指垂直于屏幕向外的平面)

has_points() → bool

判断是否有锚点

is_off_screen()

判断是否在画面外

length_over_dim(dim: int) → float

dim 维度的长度

lock_data(keys: Iterable[str])

为了加速一些动画,尤其是 Transform,它可以很方便地确认哪些数据片段不会在动画期间改变, 以便调用插值可以跳过这一点,这样它就不会被不必要地读入 shader_wrapper 对象

match_color(mobject: manimlib.mobject.mobject.Mobject)

将自己的颜色与 mobject 匹配

match_depth(mobject: manimlib.mobject.mobject.Mobject, **kwargs)

将自己的深度与 mobject 匹配(这里的深度指 z 轴方向的宽度)

match_height(mobject: manimlib.mobject.mobject.Mobject, **kwargs)

将自己的高度与 mobject 匹配

match_points(mobject: manimlib.mobject.mobject.Mobject)

将自身锚点与 mobject 的锚点匹配

match_updaters(mobject: manimlib.mobject.mobject.Mobject)

将自己的 updater 函数与 mobject 匹配

match_width(mobject: manimlib.mobject.mobject.Mobject, **kwargs)

将自己的宽度与 mobject 匹配

match_x(mobject_or_point: manimlib.mobject.mobject.Mobject | numpy.ndarray, direction: numpy.ndarray = array([0., 0., 0.]))

移动到与 mobject 相同的 x 轴坐标

match_y(mobject_or_point: manimlib.mobject.mobject.Mobject | numpy.ndarray, direction: numpy.ndarray = array([0., 0., 0.]))

移动到与 mobject 相同的 y 轴坐标

match_z(mobject_or_point: manimlib.mobject.mobject.Mobject | numpy.ndarray, direction: numpy.ndarray = array([0., 0., 0.]))

移动到与 mobject 相同的 z 轴坐标

move_to(point_or_mobject: manimlib.mobject.mobject.Mobject | numpy.ndarray, aligned_edge: numpy.ndarray = array([0., 0., 0.]), coor_mask: numpy.ndarray = array([1, 1, 1]))

移动到 point_or_mobject 的位置

next_to(mobject_or_point: manimlib.mobject.mobject.Mobject | numpy.ndarray, direction: numpy.ndarray = array([1., 0., 0.]), buff: float = 0.25, aligned_edge: numpy.ndarray = array([0., 0., 0.]), submobject_to_align: Optional[manimlib.mobject.mobject.Mobject, None] = None, index_of_submobject_to_align: Optional[Union[int, slice]] = None, coor_mask: numpy.ndarray = array([1, 1, 1]))

放到 mobject_or_point 旁边

pfp(alpha)

point_from_proportion 的简写

point_from_proportion(alpha: float) → numpy.ndarray

在整条路径上占比为 alpha 处的点

pointwise_become_partial(mobject, a, b)

生成一个路径百分比从 a 到 b 的物件

put_start_and_end_on(start: numpy.ndarray, end: numpy.ndarray)

把物体的起点和终点通过旋转缩放放在 startend

refresh_bounding_box(recurse_down: bool = False, recurse_up: bool = True)

更新包围框

remove(*mobjects: manimlib.mobject.mobject.Mobject, reassemble: bool = True)

mobjects 从子物体中移除

remove_event_listner(event_type: EventType, event_callback: Callable[[Mobject, dict[str]]])

移除事件侦听

remove_updater(update_function: Updater)

移除指定的 updater 函数

replace(mobject: manimlib.mobject.mobject.Mobject, dim_to_match: int = 0, stretch: bool = False)

放到和 mobject 的位置,并且大小相同

replace_submobject(index: int, new_submob: manimlib.mobject.mobject.Mobject)

用新的子物件代替指定索引处的旧子物件

resize_points(new_length: int, resize_func: Callable[[np.ndarray, int], np.ndarray] = <function resize_array>)

重置锚点数组大小

restore()

恢复为 saved_state 的状态

resume_updating(recurse: bool = True, call_updater: bool = True)

恢复物件更新

reverse_points()

反转锚点

rotate(angle: float, axis: numpy.ndarray = array([0., 0., 1.]), about_point: Optional[numpy.ndarray, None] = None, **kwargs)

axis 为方向,angle 为角度旋转,kwargs 中可传入 about_point

rotate_about_origin(angle: float, axis: numpy.ndarray = array([0., 0., 1.]))

绕原点旋转 angle 弧度

save_state(use_deepcopy: bool = False)

保留状态,即复制一份作为 saved_state 属性

scale(scale_factor: float | npt.ArrayLike, min_scale_factor: float = 1e-08, about_point: np.ndarray | None = None, about_edge: np.ndarray = array([0., 0., 0.]))

放大 (缩小) 到原来的 scale_factor 倍,可以传入 about_point/about_edge

set_color(color: ManimColor | Iterable[ManimColor] | None, opacity: float | Iterable[float] | None = None, recurse: bool = True)

设置颜色

set_color_by_code(glsl_code: str)

传入一段 glsl 代码,用这段代码来给物件上色

代码中包含以下变量:

  • vec4 color

  • vec3 point

  • vec3 unit_normal

  • vec3 light_coords

  • float gloss

  • float shadow

如果想要学习如何用 glsl 上色,推荐去 https://thebookofshaders/https://shadertoy.com/ 学习一番`

set_color_by_gradient(*colors: ManimColor)

渐变染色

set_color_by_rgb_func(func: Callable[[np.ndarray], Sequence[float]], opacity: float = 1, recurse: bool = True)

传入一个函数,这个函数接受一个三维坐标,将物件按照这个函数的方法设置颜色

set_color_by_rgba_func(func: Callable[[np.ndarray], Sequence[float]], recurse: bool = True)

传入一个函数,这个函数接受一个三维坐标,将物件按照这个函数的方法设置颜色,包含透明度

set_color_by_xyz_func(glsl_snippet: str, min_value: float = - 5.0, max_value: float = 5.0, colormap: str = 'viridis')

传入一个关于 x, y, z 的字符串表达式,这个表达式应当返回一个 float 值

这个方法不是非常智能,因为会把所有匹配到的 x, y, z 都认为是变量, 所以如果有特殊必要的话请查看该方法的源码,进行一些更改,取消字符串的匹配和替换

set_coord(value: float, dim: int, direction: numpy.ndarray = array([0., 0., 0.]))

移动到 dim 维度的 value 位置

set_data(data: dict)

设置成员数据,以字典形式传入

set_depth(depth: float, stretch: bool = False, **kwargs)

保持原比例设置深度

set_height(height: float, stretch: bool = False, **kwargs)

保持原比例设置高度

set_max_depth(max_depth: float, **kwargs)

设置最大深度

set_max_height(max_height: float, **kwargs)

设置最大高度

set_max_width(max_width: float, **kwargs)

设置最大宽度

set_opacity(opacity: float | Iterable[float] | None, recurse: bool = True)

设置透明度

set_points(points: npt.ArrayLike)

设置锚点

set_reflectiveness(reflectiveness: float, recurse: bool = True)

设置反光度

set_rgba_array(rgba_array: npt.ArrayLike, name: str = 'rgbas', recurse: bool = False)

将 rgbas 成员变量设置为指定的值

set_rgba_array_by_color(color: ManimColor | Iterable[ManimColor] | None = None, opacity: float | Iterable[float] | None = None, name: str = 'rgbas', recurse: bool = True)

通过颜色设置 rgba_array 成员以染色

set_shadow(shadow: float, recurse: bool = True)

设置阴影

set_submobjects(submobject_list: list)

重新设置子物件

set_uniforms(uniforms: dict)

设置 uniform 变量,以字典形式传入

set_width(width: float, stretch: bool = False, **kwargs)

保持原比例设置宽度

set_x(x: float, direction: numpy.ndarray = array([0., 0., 0.]))

将 x 轴坐标设置为 x

set_y(y: float, direction: numpy.ndarray = array([0., 0., 0.]))

将 y 轴坐标设置为 y

set_z(z: float, direction: numpy.ndarray = array([0., 0., 0.]))

将 z 轴坐标设置为 z

shift(vector: numpy.ndarray)

相对移动 vector 向量

shift_onto_screen(**kwargs)

确保在画面中

shuffle(recurse: bool = False)

随机打乱子物件的顺序

sort(point_to_num_func: Callable[[np.ndarray], float] = <function Mobject.<lambda>>, submob_func: Callable[[Mobject]] | None = None)

对子物件进行排序

space_out_submobjects(factor: float = 1.5, **kwargs)

调整子物件的间距为 factor

stretch(factor: float, dim: int, **kwargs)

dim 维度伸缩到原来的 factor

stretch_to_fit_depth(depth: float, **kwargs)

拉伸以适应深度

stretch_to_fit_height(height: float, **kwargs)

拉伸以适应高度

stretch_to_fit_width(width: float, **kwargs)

拉伸以适应宽度

surround(mobject: manimlib.mobject.mobject.Mobject, dim_to_match: int = 0, stretch: bool = False, buff: float = 0.25)

环绕着 mobject

suspend_updating(recurse: bool = True)

停止物件更新

to_corner(corner: numpy.ndarray = array([- 1., - 1., 0.]), buff: float = 0.5)

corner 这个角落对齐

to_edge(edge: numpy.ndarray = array([- 1., 0., 0.]), buff: float = 0.5)

edge 这个边对齐

unfix_from_frame()

将锁定在屏幕上的物件解锁

update(dt: float = 0, recurse: bool = True)

更新物件状态,为 动画 (Animation)更新 (updater) 调用

wag(direction: numpy.ndarray = array([1., 0., 0.]), axis: numpy.ndarray = array([0., - 1., 0.]), wag_factor: float = 1.0)

沿 axisdirection 方向摇摆 wag_factor

Group

class manimlib.mobject.mobject.Group(*mobjects: manimlib.mobject.mobject.Mobject, **kwargs)

数学物件组合

传入一系列 mobjects 作为子物件,可以用 [] 索引

和Mobject相同,用于存放一些子物体

Point

class manimlib.mobject.mobject.Point(location: npt.ArrayLike = array([0., 0., 0.]), **kwargs)

似乎仅用于表示坐标

get_height() → float

获取物件高度

get_location() → numpy.ndarray

获取坐标位置

get_width() → float

获取物件宽度

set_location(new_loc: npt.ArrayLike)

设置坐标位置

_AnimationBuilder

class manimlib.mobject.mobject._AnimationBuilder(mobject: manimlib.mobject.mobject.Mobject)

动画编译器

用于场景类 Sceneplay 中,用法如下:

self.play(mob.animate.shift(UP).scale(2).rotate(PI))

该示例中,会使 mob 生成一个 向上移动 2 个单位,放大至 2 倍,旋转 180 度 的目标,并使用 MoveToTarget 进行转变

这个方法可以采用 链式操作,即像样例中给的那样连续施加 3 个方法。这得益于 Mobject 的这些方法都返回自身, 也就是 return self,有兴趣的读者可以仔细研究一下源码

build()

在动画播放之前,prepare_animation() 会先自动调用 build() 方法,将方法编译为 动画实例

将一系列在 .animate 之后的方法合并为一个 MoveToTarget,并返回这个 MoveToTraget 的动画实例。也就是说,可以用下面的代码来播放动画,也可以将动画转变为更新

# 直接用 play 方法播放
self.play(mob.animate.shift(UP).scale(2).rotate(PI/2))

# 播放动画
anim = mob.animate.shift(UP).scale(2).rotate(PI/2).build() # 此处有无 .build() 均可
self.play(anim)

# 将动画实例用一个变量保存,并将动画转变为更新
anim = mob.animate.shift(UP).scale(2).rotate(PI/2).build()
turn_animation_into_updater(anim)
self.add(mob)
self.wait(2)