ikuzakの備忘録

数学関連のツールTeX,Tikz,Manim,Geogebraなどの備忘録です。

【Manim】add_updaterの追加

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から円板(  x^2 + y^2 \leqq 1,  z=1 )から xy平面上に射影するってイメージのもの。 Line上で点Pを動かして、射影がどう変わるかをアニメーションしたもの。

add_updaterを使って動かしているのはcone
最初は別に何もない空っぽの状態でも構わないので、13行目ではとりあえずVMobjectであることだけ宣言。

核心は21行目から。
add_updaterの引数として渡せるのは、あくまで関数であるので、ここでlambda関数を利用。
で、becomeメソッドを使って、その瞬間ごとに表示されるべきVMobjectSurfaceで作ってみた。

ちなみに、y座標の設定まで (1-u)*P_dot.get_y() がついているのは、これの続きで点Pを平面z=2における円周を動かす予定だったから。

出来上がっている動画がコチラ↓

/* -----codeの行番号----- */