python manim实现排序算法动画示例


Posted in Python onAugust 14, 2022

什么是 manim

Manim 是一个用于精确编程动画的引擎,专为创建解释性数学视频而设计。

注意,有两个主要版本的 manim。该存储库最初是 3Blue1Brown 的作者的个人项目,目的是为这些视频制作动画,此处提供了视频专用代码。2020 年,一群开发人员将其分叉成现在的社区版,目标是更稳定、更好地测试、更快地响应社区贡献,以及更友好地开始使用。

主要版本如下:

冒泡排序介绍

本文就使用 manim 来实现一个冒泡排序的动画,首先来了解下什么是冒泡排序

冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。

算法步骤

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  • 针对所有的元素重复以上的步骤,除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

初始化元素

比如我们需要排序数组为: [4,2,3,1,5]

首先,需要在 manim 场景上初始化我们的需要排序的所有元素,这里用矩形来表示。

在 manim 中,可以用 Rectangle 来初始化矩形,然后我们通过设置元素不同的高度来表示不同的元素大小。

  • main.py
from manimlib import *
class Test(Scene):
    def construct(self):
        COLOR = [BLUE, GREEN, RED, PINK, ORANGE, MAROON_B, TEAL, PURPLE_B, GREY_BROWN]
        arr = [4,2,3,1,5]
        g = VGroup()
        for i in range(len(arr)):
            r1=Rectangle(width=1,height=arr[i],fill_color=COLOR[i%len(COLOR)],fill_opacity=1)
            t1=Text(str(arr[i])).scale(0.5)
            rec = VGroup(r1,t1)
            g.add(rec)
        g.arrange(RIGHT,aligned_edge=DOWN)
        self.add(g)
        self.wait()

使用下面的命令运行上面的代码:

manimgl main.py BubbleSort

ManimGL v1.6.1
[11:27:18] INFO     Using the default configuration file, which you can modify in `/Users/zheng/anaconda3/envs/manim/lib/python3.10/site-packages/manimlib/default_config.yml`                                                                                         config.py:265
           INFO     If you want to create a local configuration file, you can create a file named `custom_config.yml`, or run `manimgl --config`                                                                                                                       config.py:266
[11:27:20] INFO     Tips: You are now in the interactive mode. Now you can use the keyboard and the mouse to interact with the scene. Just press `q` if you want to quit.

运行后,就会出现一个窗口显示如下画面。

python manim实现排序算法动画示例

代码说明

上面代码中,通过继承父类 Scene 然后重新父类的 construct 来构建一个场景。

然后在场景中添加了矩形(Rectangle)和文本(Text),并且将这两个元素添加到了 VGroup 类中。

再用一个 VGroup 来包含所有的 VGroup,通过调用 arrange 方法来排列这些元素。第一个 RIGHT 参数表示所有元素向右依次排列,aligned_edge 表示对齐的边,这里我们传入 DOWN 将底边对齐。

最后使用 self.add() 方法把 VGroup 添加到场景中。

Rectangle 类定义了矩形的创建,更多图形可以查看 docs.manim.org.cn/documentati…

元素交换动画

通过算法步骤的第一步:比较相邻的元素。如果第一个比第二个大,就交换他们两个。就涉及到了交换的动画。

一开始,我用 manim 提供的 CyclicReplace 方法来交换两个元素。效果如下:

self.play(CyclicReplace(g[0], g[1]))
self.wait()

python manim实现排序算法动画示例

交换是交换了,但是交换后对齐的边变成了顶部对齐了,不符合预期。于是继续查看文档,最终决定使用元素的 target 属性来进行交换动画的制作。

上面我们要交换 g(0)g(1) 两个元素,所以我们定义这两个交换元素的 target

g[0].generate_target()
g[0].target.next_to(g[1],ORIGIN,aligned_edge=DOWN)
g[1].generate_target()
g[1].target.next_to(g[0],ORIGIN,aligned_edge=DOWN)

generate_target() 表示生成元素的 target, next_to() 表示将元素移动到指定的位置。

比如 g[0],我们先生成元素的 target,然后操作 target 将元素通过 next_to 方法移动到 g[1] 的位置。其中 ORIGIN 表示 g[1] 的所在位置。 我们对 g[1] 的元素也做类似的操作。

然后使用 MoveToTarget 来将元素转换到定义的 target 上,通过调用 self.play() 方法来播放动画。

self.play(MoveToTarget(g[0]),MoveToTarget(g[1]))

python manim实现排序算法动画示例

嗯~完美符合预期。

实现代码

根据上面的知识点,接下来就可以编写一个冒泡排序的动画了。

这里在初始化场景元素时,额外添加了一个数组来存放所有场景元素,因为在交换元素位置后,也要交换对应索引下的元素,如果直接用 VGroup 来交换时,会出现问题。

self.g[j],self.g[j+1] = self.g[j+1],self.g[j]
TypeError: 'VGroup' object does not support item assignment

所以用额外的数组去接收。

还添加了一个 Indicate 方法,当涉及到对应交换的元素时,会做一个类似对焦的动作。

from manimlib import *
class BubbleSort(Scene):
    def construct(self):
        self.COLOR = [BLUE, GREEN, RED, PINK, ORANGE, MAROON_B, TEAL, PURPLE_B, GREY_BROWN]
        self.bubbleSort([4,2,3,1,5])
    def init_vmobj(self,arr):
        '''
            初始化场景元素
        '''
        self.vmArr = []
        g = VGroup()
        for i in range(len(arr)):
            r1=Rectangle(width=1,height=arr[i]/2,fill_color=self.COLOR[i%len(self.COLOR)],fill_opacity=1)
            t1=Text(str(arr[i])).scale(0.5)
            rec = VGroup(r1,t1)
            self.vmArr.append(rec)
            g.add(rec)
        g.arrange(RIGHT,aligned_edge=DOWN)
        self.add(g)
        self.wait()
    def bubbleSort(self,arr):
        '''
            冒泡排序
        '''
        self.init_vmobj(arr)
        for i in range(1, len(arr)):
            for j in range(0, len(arr)-i):
                self.play(Indicate(self.vmArr[j]))
                self.play(Indicate(self.vmArr[j+1],color=RED))
                if arr[j] > arr[j+1]:
                    arr[j], arr[j + 1] = arr[j + 1], arr[j]
                    self.cyc_move(self.vmArr[j],self.vmArr[j+1])
                    self.vmArr[j],self.vmArr[j+1] = self.vmArr[j+1],self.vmArr[j]
        return arr
    def cyc_move(self,vm1,vm2):
        '''
            交换两个元素位置
        '''
        vm1.generate_target()
        vm1.target.next_to(vm2,ORIGIN,aligned_edge=DOWN)
        vm2.generate_target()
        vm2.target.next_to(vm1,ORIGIN,aligned_edge=DOWN)
        self.play(MoveToTarget(vm1),MoveToTarget(vm2))
        self.wait()

python manim实现排序算法动画示例

以上就是python manim实现排序算法动画示例的详细内容

本文不介绍 manim 的安装教程,需要安装教程的请参考:docs.manim.org.cn/getting_sta

更多关于python manim排序算法动画的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python 专题四 文件基础知识
Mar 20 Python
Python实现一个转存纯真IP数据库的脚本分享
May 21 Python
Python数据操作方法封装类实例
Jun 23 Python
Python实现输出程序执行进度百分比的方法
Sep 16 Python
pandas 两列时间相减换算为秒的方法
Apr 20 Python
Tensorflow 实现修改张量特定元素的值方法
Jul 30 Python
Python3 安装PyQt5及exe打包图文教程
Jan 08 Python
Python帮你微信头像任意添加装饰别再@微信官方了
Sep 25 Python
Python实现查找数据库最接近的数据
Jun 08 Python
Python使用OpenPyXL处理Excel表格
Jul 02 Python
Django filter动态过滤与排序实现过程解析
Nov 26 Python
解决pytorch下出现multi-target not supported at的一种可能原因
Feb 06 Python
Python 操作pdf pdfplumber读取PDF写入Exce
Aug 14 #Python
Python使用plt.boxplot()函数绘制箱图、常用方法以及含义详解
Aug 14 #Python
基于Python实现nc批量转tif格式
Aug 14 #Python
LyScript实现绕过反调试保护的示例详解
Aug 14 #Python
LeetCode189轮转数组python示例
Aug 05 #Python
python语言中pandas字符串分割str.split()函数
Aug 05 #Python
python绘制云雨图raincloud plot
Aug 05 #Python
You might like
PHP XML和数组互相转换详解
2016/10/26 PHP
php微信公众号开发(3)php实现简单微信文本通讯
2016/12/15 PHP
Javascript 汉字字节判断
2009/08/01 Javascript
Javascript 二维数组
2009/11/26 Javascript
JavaScript 匿名函数(anonymous function)与闭包(closure)
2011/10/04 Javascript
jquery实现的导航固定效果
2014/04/28 Javascript
JQuery中使用.each()遍历元素学习笔记
2014/11/08 Javascript
javascript事件委托的方式绑定详解
2015/06/10 Javascript
基于MVC4+EasyUI的Web开发框架形成之旅之界面控件的使用
2015/12/16 Javascript
js计算系统当前日期是星期几的方法
2016/07/14 Javascript
Bootstrap Table 在指定列中添加下拉框控件并获取所选值
2017/07/31 Javascript
JS去掉字符串末尾的标点符号及删除最后一个字符的方法
2017/10/24 Javascript
Vue.js在数组中插入重复数据的实现代码
2017/11/17 Javascript
jQuery实现下拉菜单动态添加数据点击滑出收起其他功能
2018/06/14 jQuery
jQuery 选择方法及$(this)用法实例分析
2020/05/19 jQuery
Vue+Java+Base64实现条码解析的示例
2020/09/23 Javascript
arcgis.js控制地图地体的显示范围超出区域自动弹回(实现思路)
2021/01/28 Javascript
[47:04]EG vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
[07:01]DOTA2-DPC中国联赛正赛 Aster vs Magma 3月5日 赛后选手采访
2021/03/11 DOTA
Python 的 Socket 编程
2015/03/24 Python
读取json格式为DataFrame(可转为.csv)的实例讲解
2018/06/05 Python
Python实现拷贝/删除文件夹的方法详解
2018/08/29 Python
Python 带有参数的装饰器实例代码详解
2018/12/06 Python
Python-Tkinter Text输入内容在界面显示的实例
2019/07/12 Python
基于python实现MQTT发布订阅过程原理解析
2020/07/27 Python
前端面试必备之CSS3的新特性
2017/09/05 HTML / CSS
为你的html5网页添加音效示例
2014/04/03 HTML / CSS
Ben Sherman官方网站:英国男装品牌
2019/10/22 全球购物
什么是虚拟内存?虚拟内存有什么优势?
2016/02/09 面试题
介绍一下如何优化MySql
2016/12/20 面试题
广告学专业应届生求职信
2013/10/01 职场文书
生产车间班组长岗位职责
2014/01/06 职场文书
运动会广播稿200米
2014/01/27 职场文书
《长江之歌》教学反思
2014/04/17 职场文书
火烧圆明园的观后感
2015/06/03 职场文书
中学团支部工作总结
2015/08/13 职场文书