【manim】之圆规动画

1. 概要

Manim 是一个基于Python的动画库,主要用于创建数学和科学中难以用普通视频制作工具制作的图形和动画。

它提供了各种基础的动画对象,比如,点,线,面,三角形,矩形,立方体等等,

基于它们,可以组合定制出自己需要表达的动画效果。

本篇介绍如何基于Manim封装一个圆规动画。

2. 动画原理

对于单个的元素,manim本身就提供了非常多的动画函数。

比如:创建/消除的动画,移动元素的动画,旋转元素的动画等等,具体可以参考: Animations

但是,对于多个元素联动的动画,则需要编写各个元素之间的联动规则,来封装符合要求的动画。

圆规动画就是多个元素联动的动画,下面演示其如何封装。

圆规动画目的是画一个 圆弧 ,只是在绘制的圆弧的过程中还需要展示了圆弧的起点,终点,

以及绘制过程中动态更新起点终点之间的线。

首先,定义绘制函数:

python 复制代码
def ruler(sc: Scene, p1, p2, color=GREEN, angle=PI, axis=OUT):
    """
    圆规动画


    Parameters
    ---------
    sc
        绘制动画的场景
    p1
        代表圆规的针,绘制时不动的点
    p2
        代表圆规的笔芯,绘制圆弧的点
    color
        圆弧的颜色,默认绿色
    angle
        绘制圆弧的角度,默认PI,相当于绘制半个圆
    axis
        只有2个值 IN/OUT,分别表示顺时针还是逆时针作弧
    """
    # 省略。。。
    return arc

各个参数的含义参见注释。

实现动画的思路如下:

  1. 构建3个元素,即:
    1. d1(根据参数中p1坐标绘制的点)
    2. d2(根据参数中p2坐标绘制的点)
    3. dl(连接p1和p2的虚线)
  2. 设置dl的动画,随着 d1和d2变化不断重新绘制(这里 d1其实是不会变的)
  3. 再设置圆弧的动画,随着 d2的变动,不断绘制新的圆弧(圆弧就是起点到d2的弧)
  4. 通过 manim自带的动画函数让 d2先动,其他动画随之运动
  5. 最后删除不必要的元素,只保留圆弧在 场景(sc)中
python 复制代码
def ruler(sc: Scene, p1, p2, color=GREEN, angle=PI, axis=OUT):
    d1 = Dot(point=p1, color=RED)
    d2 = Dot(point=p2, color=color)
    dl = DashedLine(d1.get_center(), d2.get_center())

    r = np.linalg.norm(p2 - p1)
    arc = ArcBetweenPoints(p2, p2, stroke_width=2)

    dl.add_updater(lambda z: z.become(DashedLine(d1.get_center(), d2.get_center())))
    if np.array_equal(axis, OUT):
        arc.add_updater(
            lambda z: z.become(
                ArcBetweenPoints(
                    p2, d2.get_center(), radius=r, stroke_color=color, stroke_width=2
                )
            )
        )
    if np.array_equal(axis, IN):
        arc.add_updater(
            lambda z: z.become(
                ArcBetweenPoints(
                    d2.get_center(), p2, radius=r, stroke_color=color, stroke_width=2
                )
            )
        )

    sc.add(d1, d2, dl, arc)
    sc.play(
        Rotate(
            d2,
            about_point=d1.get_center(),
            axis=axis,
            angle=angle,
            rate_func=linear,
        )
    )

    arc.clear_updaters()
    dl.clear_updaters()
    sc.remove(d1, d2, dl)
    return arc

3. 动画效果

封装之后,看看使用的效果。

首先,试试按照逆时针(默认是逆时针)和顺时针方式绘制半圆。

python 复制代码
# -*- coding: utf-8 -*-
from manim import *
import numpy as np


class Sample(Scene):
    def construct(self):
        ruler(self, np.array([-1, 0, 0]), np.array([-1, 1, 0]))
        ruler(self, np.array([1, 0, 0]), np.array([1, 1, 0]), axis=IN)
        self.wait()

然后,试试绘制2个圆弧的交叉点。

python 复制代码
class Sample(Scene):
    def construct(self):
        ruler(self, np.array([-1, -1, 0]), np.array([1.1, -0.2222, 0]), angle=PI / 3)
        ruler(
            self,
            np.array([1, -1, 0]),
            np.array([-1.1, -0.2222, 0]),
            axis=IN,
            angle=PI / 3,
        )
        self.wait()

4. 总结

联动动画的实现其实也不难,关键在于先确认起始的动画是哪个元素开始的,

比如,上文中起始动画是由d2发起的。

确定了起始动画,其他元素的联动都要基于起始动画的元素,

比如,上文中的dl和arc元素。

这样,联动的效果就形成了。

我在视频号中基于此做了一个 高斯正17边形的尺规作图动画(weixin.qq.com/sph/AkfwsX)...%25E3%2580%2582 "https://weixin.qq.com/sph/AkfwsX)%E3%80%82")

注: 此链接是视频号中视频的链接,只能在微信中打开。

相关推荐
龙亘川16 小时前
数字化赋能基层协同治理:亘川智城一网统管平台落地实践思考
大数据·人工智能·智慧城市·开源软件·数据可视化
龙亘川21 小时前
智慧交通运输监管平台业务建模与架构解析
人工智能·架构·智慧城市·数据可视化·政务
龙亘川2 天前
政法工作系统数字化建设实践解读:以全周期闭环驱动政法工作现代化
大数据·人工智能·智慧城市·开源软件·数据可视化
杨超越luckly2 天前
上海社零数据:消费结构分化——1.66万亿盘子从+7.2%到-1.0%的十五年观察
html·agent·数据可视化·上海·社会消费品零售总额
灰山君2 天前
面向高校实训室的数字孪生可视化平台:支持校内部署与200个教学席位
大数据·人工智能·信息可视化·数据可视化·实时大数据
FIT2CLOUD飞致云3 天前
电子表格支持嵌入集成,支持GaussDB数据源与StarRocks计算引擎,DataEase开源BI工具v3.1.0版本发布
开源·数据可视化·dataease·数据表格·bi
松果集4 天前
(六)SPSS非参数检验
大数据·数据分析·数据可视化
SL_staff4 天前
从钉钉日报到动态数据看板:面向业务侧的低代码BI实践路径
java·数据分析·数据可视化
龙亘川4 天前
数智赋能民生保障:亘川智城智慧民政系统构建民政一体化业务闭环
大数据·人工智能·智慧城市·开源软件·数据可视化·政务
柳杉4 天前
用 GPT-6 Astra 和 Tripo3D 做智慧农业 3D 大屏:从调研到可巡检园区全流程实录
前端·ai编程·数据可视化