翼度科技»论坛 编程开发 python 查看内容

【manim】之圆规动画

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
概要

前端时间做尺规作图相关的动画的时候,封装了一个圆规的动画,顺便研究了下 manim 库的动画函数。
manim 本身就是做动画的库,所以,基于它封装自定义的动画非常方便。
动画原理

对于单个的元素,manim本身就提供了非常多的动画函数。
比如:创建/消除的动画,移动元素的动画,旋转元素的动画等等,具体可以参考: Animations
如果是做一些简单的演示视频的话,这些内置的动画函数满足要求绰绰有余。
但是,对于多个元素联动的动画,则需要编写各个元素之间的联动规则,来封装符合要求的动画。
下面以圆规动画为例,演示多元素动画如何封装。
圆规动画目的还是画出一个 圆弧,只是在绘制的圆弧的过程中展示了圆弧的起点,终点以及连接起点终点之间的线。
这样,实际使用圆规作图的时候,可以更好的理解 圆弧是如何画出来的。
函数的签名如下:
  1. def ruler(sc: Scene, p1, p2, angle=PI, axis=OUT):
  2.     """
  3.     圆规动画
  4.     Parameters
  5.     ---------
  6.     sc
  7.         绘制动画的场景
  8.     p1
  9.         代表圆规的针,绘制时不动的点
  10.     p2
  11.         代表圆规的笔芯,绘制圆弧的点
  12.     angle
  13.         绘制圆弧的角度,默认PI,相当于绘制半个圆
  14.     axis
  15.         只有2个值 IN/OUT,分别表示顺时针还是逆时针作弧
  16.     """
  17.     # 省略。。。
  18.     return arc
复制代码
各个参数的含义参见注释。
实现动画的思路如下:

  • 构建3个元素,也就是d1(根据参数中p1坐标绘制的点),d2(根据参数中p2坐标绘制的点)以及 dl(连接p1和p2的虚线)
  • 设置dl的动画,随着 d1和d2变化不断重新绘制(这里 d1其实是不会变的)
  • 再设置圆弧的动画,随着 d2的变动,不断绘制新的圆弧
  • 通过 manim自带的动画函数让 d2先动,其他动画则会随之一起
  • 最后删除不必要的元素,只保留圆弧在 场景(sc)中
  1. def ruler(sc: Scene, p1, p2, angle=PI, axis=OUT):
  2.     """
  3.     圆规动画
  4.     Parameters
  5.     ---------
  6.     sc
  7.         绘制动画的场景
  8.     p1
  9.         代表圆规的针,绘制时不动的点
  10.     p2
  11.         代表圆规的笔芯,绘制圆弧的点
  12.     angle
  13.         绘制圆弧的角度,默认PI,相当于绘制半个圆
  14.     axis
  15.         只有2个值 IN/OUT,分别表示顺时针还是逆时针作弧
  16.     """
  17.     d1 = Dot(point=p1, color=RED)
  18.     d2 = Dot(point=p2, color=GREEN)
  19.     dl = DashedLine(d1.get_center(), d2.get_center())
  20.     r = np.linalg.norm(p2 - p1)
  21.     arc = ArcBetweenPoints(p2, p2)
  22.     dl.add_updater(lambda z: z.become(DashedLine(d1.get_center(), d2.get_center())))
  23.     if np.array_equal(axis, OUT):
  24.         arc.add_updater(
  25.             lambda z: z.become(
  26.                 ArcBetweenPoints(p2, d2.get_center(), radius=r, stroke_color=GREEN)
  27.             )
  28.         )
  29.     if np.array_equal(axis, IN):
  30.         arc.add_updater(
  31.             lambda z: z.become(
  32.                 ArcBetweenPoints(d2.get_center(), p2, radius=r, stroke_color=GREEN)
  33.             )
  34.         )
  35.     sc.add(d1, d2, dl, arc)
  36.     sc.play(
  37.         Rotate(
  38.             d2,
  39.             about_point=d1.get_center(),
  40.             axis=axis,
  41.             angle=angle,
  42.             rate_func=linear,
  43.         )
  44.     )
  45.     arc.clear_updaters()
  46.     dl.clear_updaters()
  47.     sc.remove(d1, d2, dl)
  48.     return arc
复制代码
动画效果

封装之后,使用起来非常简单:
  1. # -*- coding: utf-8 -*-
  2. from manim import *
  3. import numpy as np
  4. class Sample(Scene):
  5.     def construct(self):
  6.         ruler(self, np.array([-1, 0, 0]), np.array([-1, 1, 0]))
  7.         ruler(self, np.array([1, 0, 0]), np.array([1, 1, 0]), axis=IN)
  8.         self.wait()
复制代码
上面演示了逆时针(默认是逆时针)和顺时针方式绘制半圆。

各个元素的颜色等相关属性,没有暴露到函数参数中,可以直接在代码中修改。
这里主要演示如何基于 manim制作多元素动画的。

来源:https://www.cnblogs.com/wang_yb/p/17079903.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具