Mobjectの変化に合わせて、別のMobjectも変化させられるぜーっていう話。
add_updaterの追加
こういうのが数学のアニメーション動画を、Manimで作成する、最大の利点かもしれない。
ManimではあらゆるMobjectに、随時新しいMobjectに更新されるよう関数を追加できる。
ある大学の入試問題を解く中で、「頭の中にあるアニメーションが現物として表現できたらなぁ」と思ったのが挑戦のきっかけ
ちなみに3次元空間の問題だったので、後述の例もThreeDScene
のつもりで書いてる。
他のMobjectの変化に合わせて、動かす
さっそく、作った具体例から。
from manim import * class AddUpdater(ThreeDScene): def construct(self): axes = ThreeDAxes( x_range=(-7,7), y_range=(-7,7), z_range=(0,3), z_length=3 ) path_line = Line(start=[0,0,2],end=[3.5,0,2]) P_dot = Dot3D(point=path_line.get_start(),radius=0.07,color=YELLOW) disc = Circle(radius=1,color=RED,fill_opacity=0.5).shift(OUT) cone = VMobject() self.add( P_dot, cone, disc, axes, path_line, ) cone.add_updater(lambda x:x.become( Surface( lambda u, v: np.array([ (1-u)*P_dot.get_x() + u * np.cos(v), (1-u)*P_dot.get_y() + u * np.sin(v), -u + 2 ]),v_range=[0,TAU],u_range=[0,2],checkerboard_colors=[YELLOW_A, YELLOW_B], fill_opacity=0.3, resolution=(10, 10) ) ) ) self.set_camera_orientation(theta=40*DEGREES,phi=75*DEGREES) self.play(MoveAlongPath(P_dot,path_line),run_time=5)
作った内容としては、点Pから円板( )から平面上に射影するってイメージのもの。
Line
上で点Pを動かして、射影がどう変わるかをアニメーションしたもの。
add_updater
を使って動かしているのはcone
。
最初は別に何もない空っぽの状態でも構わないので、13行目ではとりあえずVMobject
であることだけ宣言。
核心は21行目から。
add_updater
の引数として渡せるのは、あくまで関数であるので、ここでlambda
関数を利用。
で、become
メソッドを使って、その瞬間ごとに表示されるべきVMobject
をSurface
で作ってみた。
ちなみに、y座標の設定まで (1-u)*P_dot.get_y() がついているのは、これの続きで点Pを平面における円周を動かす予定だったから。
出来上がっている動画がコチラ↓