让数学变得更生动manim库的使用(2)-动画绘制

0 概述

动画是让人们深刻理解数学原理的关键要素,在上一章中已经介绍manim库的基本使用以及静态元素的绘制。本章主要介绍在各种场景下动画的应用以及效果展示。

1、引导动画

%%manim PointMovingOnShapes  -ql -v WARNING
class PointMovingOnShapes(Scene):
    def construct(self):
        # 创建一个半径为1的圆
        circle = Circle(radius=1, color=BLUE)
        # 创建一个点
        dot = Dot()
        # 将第一个点复制并向右平移1个段位
        dot2 = dot.copy().shift(RIGHT)
        # 将第一个点加入到场景中
        self.add(dot)
        # 绘制一个线段
        line = Line([3, 0, 0], [5, 0, 0])
        # 将线段加入到场景中
        self.add(line)
        # 增加从重新变大的动画给圆
        self.play(GrowFromCenter(circle))
        # 增加一个变形动画给dot移动到dot2
        self.play(Transform(dot, dot2))
        # 增加一个路径引导动画给dot 路径为circle 时间为 2 秒 缓动函数为linear
        self.play(MoveAlongPath(dot, circle), run_time=2, rate_func=linear)
        # 增加一个旋转中华,旋转中心点为 about_point 持续时间为 1.5 s
        self.play(Rotating(dot, about_point=[2, 0, 0]), run_time=1.5)
        self.wait()

效果如下

让数学变得更生动manim库的使用(2)-动画绘制_第1张图片

2、变形动画 MovingAround 

%%manim MovingAround  -ql -v WARNING
class MovingAround(Scene):
    def construct(self):
        square = Square(color=BLUE, fill_opacity=1)

        self.play(square.animate.shift(LEFT))
        self.play(square.animate.set_fill(ORANGE))
        self.play(square.animate.scale(0.3))
        self.play(square.animate.rotate(0.4))
        self.wait()

效果如下

让数学变得更生动manim库的使用(2)-动画绘制_第2张图片

3、角度动画

%%manim MovingAngle  -ql -v WARNING
class MovingAngle(Scene):
    def construct(self):
        # 设定旋转中心为left点[-1,0,0]
        rotation_center = LEFT
        # 设置一个数值跟踪器 初始值为 110
        theta_tracker = ValueTracker(110)
        # 绘制一个线段[-1,0][1,0]
        line1 = Line(LEFT, RIGHT)
        # 绘制一个相同的线段
        line_moving = Line(LEFT, RIGHT)
        # 绘制参考线
        line_ref = line_moving.copy()
        # 设置旋转动画,旋转角度根据数值跟踪器进行设置,是角度到弧度的转化,所有旋转都是以弧度为单位的而非角度
        line_moving.rotate(
            theta_tracker.get_value() * DEGREES, about_point=rotation_center
        )
        # 绘制一个角度标记在line1与line_moving
        a = Angle(line1, line_moving, radius=0.5, other_angle=False)
        # 绘制theta的初始位置,此时绘制一个比角标略大的角(弧)通过point_from_proportion(0.5)设定该区域的中间点
        te = MathTex(r"\theta").move_to(
            Angle(
                line1, line_moving, radius=0.5 + 3 * SMALL_BUFF, other_angle=False
            ).point_from_proportion(0.5)
        )

        self.add(line1, line_moving, a, te)
        self.wait()

        line_moving.add_updater(
            lambda x: x.become(line_ref.copy()).rotate(
                theta_tracker.get_value() * DEGREES, about_point=rotation_center
            )
        )

        a.add_updater(
            lambda x: x.become(Angle(line1, line_moving, radius=0.5, other_angle=False))
        )
        te.add_updater(
            lambda x: x.move_to(
                Angle(
                    line1, line_moving, radius=0.5 + 3 * SMALL_BUFF, other_angle=False
                ).point_from_proportion(0.5)
            )
        )
        # 设置数值跟踪器的数值
        self.play(theta_tracker.animate.set_value(40))
        # 将数值增加140
        self.play(theta_tracker.animate.increment_value(140))
        self.play(te.animate.set_color(RED), run_time=0.5)
        # 设定数值
        self.play(theta_tracker.animate.set_value(350))
        self.wait()

 效果如下

让数学变得更生动manim库的使用(2)-动画绘制_第3张图片

4、组动画

%%manim MovingGroupToDestination  -ql -v WARNING
class MovingGroupToDestination(Scene):
    def construct(self):
        # 将4个点形成一个虚拟编组
        group = VGroup(Dot(LEFT), Dot(ORIGIN), Dot(RIGHT, color=RED), Dot(2 * RIGHT)).scale(1.4)
        # 绘制目标点
        dest = Dot([4, 3, 0], color=YELLOW)
        # 将编组与目标点添加到场景
        self.add(group, dest)
        # 编写位移动画,从编组的第二个点到目标点
        self.play(group.animate.shift(dest.get_center() - group[2].get_center()))
        self.wait()

效果如下

让数学变得更生动manim库的使用(2)-动画绘制_第4张图片

5、元素框动画

%%manim MovingFrameBox  -ql -v WARNING
class MovingFrameBox(Scene):
    def construct(self):
        # 分三部分绘制一个完整的公式
        text=MathTex(
            "\\frac{d}{dx}f(x)g(x)=","f(x)\\frac{d}{dx}g(x)","+",
            "g(x)\\frac{d}{dx}f(x)"
        )
        # 播放手写动画
        self.play(Write(text))
        # 绘制外框间距比为 0.1
        framebox1 = SurroundingRectangle(text[1], buff = .1)
        framebox2 = SurroundingRectangle(text[3], buff = .1)
        # 绘制外框显示动画
        self.play(
            Create(framebox1),
        )
        self.wait()
        # 绘制第一个框移动并替换第二个框的动画
        self.play(
            ReplacementTransform(framebox1,framebox2),
        )
        self.wait()

效果如下

让数学变得更生动manim库的使用(2)-动画绘制_第5张图片

6、旋转补间动画

%%manim RotationUpdater  -ql -v WARNING
class RotationUpdater(Scene):
    def construct(self):
        # 创建前向旋转函数,此函数会根据时间dt(deltatime)来决定动画的幅度而不是手工设定
        def updater_forth(mobj, dt):
            mobj.rotate_about_origin(dt)
        # 创建后向旋转函数
        def updater_back(mobj, dt):
            mobj.rotate_about_origin(-dt)
        # 创建旋转的参考线段
        line_reference = Line(ORIGIN, LEFT).set_color(WHITE)
        # 创建旋转线段
        line_moving = Line(ORIGIN, LEFT).set_color(YELLOW)
        # 将前向旋转函数加入到线段中
        line_moving.add_updater(updater_forth)
        # 将两个线段加入到场景中
        self.add(line_reference, line_moving)
        self.wait(2)
        # 移除前向旋转函数
        line_moving.remove_updater(updater_forth)
        # 将后向向旋转函数加入到线段中
        line_moving.add_updater(updater_back)
        self.wait(5)
        # 移除后向旋转函数
        line_moving.remove_updater(updater_back)
        self.wait(0.5)

效果如下

让数学变得更生动manim库的使用(2)-动画绘制_第6张图片

7、轨迹动画

%%manim PointWithTrace  -ql -v WARNING
class PointWithTrace(Scene):
    def construct(self):
        # 创建一个空物体
        path = VMobject()
        # 创建一个点
        dot = Dot()
        # 定义路径关键点
        path.set_points_as_corners([dot.get_center(), dot.get_center()])
        # 定义路径更新函数
        def update_path(path):
            # copy原路径
            previous_path = path.copy()
            # 增加新的点
            previous_path.add_points_as_corners([dot.get_center()])
            # 更新当前巨鲸
            path.become(previous_path)
        #将更新函数加入到路径中
        path.add_updater(update_path)
        #将路径与点加入到场景中
        self.add(path, dot)
        # 让dot做圆周运动
        self.play(Rotating(dot, radians=PI, about_point=RIGHT, run_time=2))
        self.wait()
        # 让dot 做线性运动
        self.play(dot.animate.shift(UP))
        self.play(dot.animate.shift(LEFT))
        self.wait()

效果如下

让数学变得更生动manim库的使用(2)-动画绘制_第7张图片

8、总结

本章主要讲解了maim库中动画的绘制,在下一章中主要介绍2维,3维坐标系、以及摄像机动画的使用

 

 

 

 

你可能感兴趣的:(数学可视化,人工智能,python,webgl,机器学习,数据可视化,manim)