这一切都可以在 https://docs.manim.community/en/stable/guides/deep_dive.html 中找到
首先,我们知道,manim 的主要组成部分为:mobject, animation 和 scene
其中,我们只要理解前两者就可以了,我们不关心 scene 是如何将动画呈现在画布上的
Mobject
Mobject 分为 ImageMobject, PMobject 和 VMobject,顾名思义,分别为 图像物件、点物件和矢量物件,其中最重要的是 VMobject
我们观察 Mobject 的初始化:
def __init__(self, color=WHITE, name=None, dim=3, target=None, z_index=0): self.name = self.__class__.__name__ if name is None else name self.dim = dim self.target = target self.z_index = z_index self.point_hash = None self.submobjects = [] self.updaters = [] self.updating_suspended = False self.color = Color(color) if color else None self.reset_points() self.generate_points() self.init_colors()
可以看到,所有基于 Mobject 的类都会自动 generate_points,这是因为 VMobject 是通过锚点和手柄来呈现的
例如,我们观察几何图形基类 Polygram:
class Polygram(VMobject, metaclass=ConvertToOpenGL): def __init__(self, *vertex_groups: Iterable[Sequence[float]], color=BLUE, **kwargs): super().__init__(color=color, **kwargs) for vertices in vertex_groups: first_vertex, *vertices = vertices first_vertex = np.array(first_vertex) self.start_new_path(first_vertex) self.add_points_as_corners( [*(np.array(vertex) for vertex in vertices), first_vertex], )
它使用了 VMobject 的 start_new_path 和 add_points_as_corners 方法来呈现
Animation
这个动画基类在渲染中这几个方法会被调用:
Animation.begin() Animation.finish() Animation.interpolate()
例如,我们观察 Transform 的方法:
def begin(self) -> None: # Use a copy of target_mobject for the align_data # call so that the actual target_mobject stays # preserved. self.target_mobject = self.create_target() self.target_copy = self.target_mobject.copy() # Note, this potentially changes the structure # of both mobject and target_mobject if config.renderer == RendererType.OPENGL: self.mobject.align_data_and_family(self.target_copy) else: self.mobject.align_data(self.target_copy) super().begin() def interpolate_submobject( self, submobject: Mobject, starting_submobject: Mobject, target_copy: Mobject, alpha: float, ) -> Transform: submobject.interpolate(starting_submobject, target_copy, alpha, self.path_func) return self
注意,Animation 的这两个方法几乎等同:
def interpolate(self, alpha: float) -> None: self.interpolate_mobject(alpha)
Scene
它有三个重要的方法:
Scene.setup() Scene.construct() Scene.tear_down()
实际上,我们对 Scene 的构造并不感兴趣,因为这部分是最复杂的,它牵涉到实现代码转 mp4 的过程,但是其中含有 Animation 的相关部分。我们注意到,Animation 的 interpolate() 的方法在初始化的时候并没有调用,那么什么时候它起作用了呢?实际上,在 Scene 部分中才真正调用了这个方法:
def update_to_time(self, t): dt = t - self.last_t self.last_t = t for animation in self.animations: animation.update_mobjects(dt) alpha = t / animation.run_time animation.interpolate(alpha) self.update_mobjects(dt) self.update_meshes(dt) self.update_self(dt)
这也就说明了,manim 的动画实现过程部分会杂糅在 Scene 的实现过程中。例如,我们知道,对 VMobject 传入 points 属性,可以实现可视化的贝塞尔曲线,可是我始终没有找到实现这部分原理的方法,可能就是杂糅在 Scene 部分中
标签:None,target,self,vertex,Scene,源码,manim,mobject,4.0 From: https://www.cnblogs.com/daxiangcai/p/17037253.html