绘图系统六:动态三维展示

文章目录

    • 时间轴
    • 单帧跳转
    • 动图绘制函数
    • 接口优化

  • 📈一 三维绘图系统 📈二 多图绘制系统📈三 坐 标 轴 定 制
  • 📈四 定制绘图风格 📈五 数据生成导入
  • 源码地址 Python打造动态绘图系统

时间轴

三维并不是人类理解的极限,毕竟我们生活在思维时空中。所以接下来要做的,就是四维图形——加一个时间轴。

实际上,这个项目创建之初就已经考虑到动图绘制的问题,毕竟默认的绘图坐标是txyz。但是,如果想实现动图绘制,就必须要先设置一个额外的线程,用于动态更新图像,否则绘图循环压迫主进程,会导致界面变得奇卡无比。

接下来,就开始实现绘制动图的需求,第一步,绘制UI。先在setFrmCtrl中添加

# 动画控制
frm = ttk.Frame(frmCtrl, width=320)
frm.pack(side=tk.TOP, fill=tk.X)
self.setAnimateFrame(frm)

然后实现具体的self.setAnimateFrame

def setAnimateFrame(self, frm):pDct = dict(side=tk.LEFT, fill=tk.X, padx=2)self.aniDelay = tk.StringVar()self.aniDelay.set(100)ttk.Label(frm, text="延时/毫秒").pack(**pDct)ttk.Entry(frm, width=5, textvariable=self.aniDelay).pack(**pDct)self.aniFrameNum = tk.StringVar()self.aniFrameNum.set(100)ttk.Label(frm, text="帧数").pack(**pDct)ttk.Entry(frm, width=5, textvariable=self.aniFrameNum).pack(**pDct)self.tIndex = 0   # 当前帧数ttk.Button(frm, width=3, text=  "⇦", command=self.btnPreFrame).pack(**pDct)ttk.Button(frm, width=3, text="▶", command=self.btnAniStart).pack(**pDct)ttk.Button(frm, width=3, text="⇨", command=self.btnNextFrame).pack(**pDct)def btnAniStart(self): passdef btnPreFrame(self): passdef btnNextFrame(self): pass

在这里插入图片描述

延时表示当自动绘制动图时,两帧间隔时间;帧数表示总共绘制的时间个数。三个按钮,分别用于向前一帧、向后一帧以及动态播放。

单帧跳转

坐标t的工作原理和xyz并不相同,毕竟每次调用时间参数的时候,都只需要调用某一点的时间。所以,现有的设置坐标数据的方法就不适用了,需要更改readDatas函数

# 读取坐标轴al的数据
def readDatas(self, al):dct = {}data = {}for flag in self.drawTypeDim.getDim():data[flag] = al.setData(flag, **dct)if flag=='t': dct['t'] = data['t'][self.tIndex]else:dct[flag] = data[flag]return data

然后再更新一下绘图函数:其实只是取消t作为绘图坐标轴的地位

def btnDrawImg(self):self.fig.clf()self.axDct = {}for al in self.als:ax = self.setDrawAxis(al)data = self.readDatas(al)draw = self.drawDct[al.getDrawType()]style = al.getStyle()keys = al.getDrawDim().replace('t',"")draw(ax, data, keys, style)self.fig.subplots_adjust(left=0.1, right=0.95, top=0.95, bottom=0.08)self.canvas.draw()

最后,实现一下btnNextFrame

def btnNextFrame(self): num = int(self.aniFrameNum.get())self.tIndex = (self.tIndex + 1) % numself.btnDrawImg()

效果如下,至此,我们离自动化动态绘图,只剩下一个多线程了。

在这里插入图片描述

动图绘制函数

所谓动图绘制,其实只需要一个循环,并且每次绘图之前,要有一定的延时。启用多线程和延时,需要导入下面两个模块

from threading import Thread
import time

接下来,就是self.btnAniStart函数和具体的动图绘制函数了

def btnAniStart(self): Thread(target=self.btnDrawCycle, daemon=True).start()def btnDrawCycle(self):dt = self.aniDelay.get()/1000.0for i in range(self.aniFrameNum.get()):self.tIndex = iself.btnDrawImg()time.sleep(dt)

点击播放按钮后效果如下

在这里插入图片描述

但是从图像播放的角度来说,这个设计并不十分合理,因为点击播放的三角号之后,应该要给出一个停止播放的按钮,相应地DrawCycle函数也应该新增一个无尽循环模式。

为了实现播放控制,为播放按钮绑定一个可变字符串

self.btnStartText = tk.StringVar()
self.btnStartText.set("▶")
ttk.Button(frm, width=3, textvariable=self.btnStartText,command=self.btnAniStart).pack(**pDct)

然后修改btnAniStart,大致改成下面的形式,但这里只是添加了暂停的逻辑,但并没有真正实现暂停的功能

def btnAniStart(self):if self.btnStartText.get() == "▶":Thread(target=self.drawCycle, daemon=True).start()self.btnStartText.set("⏸")else:self.btnStartText.set("▶")

而真正实现暂停功能,就需要修改drawCycle函数了

def drawCycle(self):dt = self.aniDelay.get()/1000.0num = self.aniFrameNum.get()while self.btnStartText.get() == "⏸":self.tIndex = (self.tIndex + 1) % numself.btnDrawImg()time.sleep(dt)

在这里插入图片描述

接口优化

开发过程中会经常遇到新增的需求,这些需求的实现,会对原来的设计形成干扰,而且这些需求累加在一起,会导致代码变得十分畸形。比如一开始DrawType类只包含绘图类型和维度,所以在AxisList中做对象的时候,变量名取为drawTypeDim。但后来DrawType又加入了其他功能,使得drawTypeDim这个变量变得很蠢,所以接下来要重新命名。

主要变更如下

  • AxisList类

    • drawTypeDim 变为 drawType
  • DrawSystem类

    • drawTypeDim 变为 drawType
  • AxisList类中定义的函数,但DrawSystem中有调用

    • getDrawType -> getType
    • getDrawDim -> getDim

另外,由于t轴和xyz在绘图时的作用相去甚远,所以将getDim函数拆分成xyz和t两个函数。在AxisList中新增两个函数

def getXYZ(self):return self.getDim().replace("t", "")def hasTimeAxis(self):return "t" in self.getDim()

更改DrawSystem中的调用,btnDrawImgal.getDim().replace('t',"")改为al.getXYZ()readDatas改写如下

def readDatas(self, al):dct = {}data = {}if al.hasTimeAxis():data['t'] = al.setData('t')dct['t'] = data['t'][self.tIndex]for flag in al.getXYZ():data[flag] = al.setData(flag, **dct)dct[flag] = data[flag]return data

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/139760.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

精品Python数字藏品购物商城爬虫-可视化大屏

《[含文档PPT源码等]精品基于Python实现的数字藏品爬虫》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具: 开发语言:python 使用框架:Django 前端技术:JavaScript、VUE.js&a…

PHP-composer安装扩展安装,批量操作合并pdf

清除Composer缓存: 运行以下命令来清除Composer的缓存,并再次尝试安装包。 bash composer clear-cache 使用不同的镜像源: Composer使用的默认包源可能会受到限制或访问问题。你可以切换到使用其他镜像源,如阿里云、Composer中国…

Nginx之gzip模块解读

目录 gzip基本介绍 gzip工作原理 Nginx中的gzip 不建议开启Nginx中的gzip场景 gzip基本介绍 gzip是GNUzip的缩写,最早用于UNIX系统的文件压缩。HTTP协议上的gzip编码是一种用来改进web应用程序性能的技术,web服务器和客户端(浏览器&…

科目三基础四项(一)

​ 第一天,基础操作,仪表,方向,挡位 按照模块来 1、方向盘两手在两侧 ​ 编辑 转向时的角度,只用:向左540,向右180 向左打和向右打的角度要抵消,回正 掉头向左打满再回 注意…

【STM32】IAP升级 预备知识

IAP(In Application Programming)简介 Flash够大的情况下,上电后的程序通过修改 MSP 的方式,可以在一块Flash上存在多个功能差异的程序。 IAP是为了在执行正常功能前,为了升级功能,提前运行的一段程序。这…

微软在Windows 11推出Copilot,将DALL-E 3集成在Bing!

美东时间9月21日,微软在美国纽约曼哈顿举办产品发布会,生成式AI成为重要主题之一。 微软表示,Copilot将于9月26日在Windows 11中推出;Microsoft 365 Copilot 将于11 月1日向企业客户全面推出;将OpenAI最新的文本生成图…

C# OpenCvSharp 图片模糊检测(拉普拉斯算子)

效果 项目 代码 using OpenCvSharp; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Windows.Forms.VisualStyl…

二叉树层序遍历及判断完全二叉树

个人主页:Lei宝啊 愿所有美好如期而遇 目录 二叉树层序遍历: 判断完全二叉树: 二叉树层序遍历: 层序遍历就是一层一层,从上到下遍历,上图遍历结果为:4 2 7 1 3 6 9 思路: 通过队列来实现层序…

vue下载Excel文件

前端vue实现导出Excel文件 用到的是 上代码 var wb XLSX.utils.table_to_book(document.querySelector(#my-table));//关联dom节点 这个是表格绑定的id名称var wbout XLSX.write(wb, {bookType: xlsx,bookSST: true,type: array})try {FileSaver.saveAs(new Blob([wbout], {…

Win10专业版开启远程桌面

Win10专业版开启远程桌面 方法一: 一、按“Win R”键,然后输入“sysdm.cpl”并按下回车键打开系统属性。 二、选择“远程”选项卡,在远程桌面中勾选“允许远程连接到此计算机”就可以开启远程桌面; 方法二: 一、打…

Mybatis 映射器与XML配置职责分离

之前我们介绍了使用XML配置方式完成对数据的增删改查操作,使用此方式在实际调用时需要使用【命名空间.标签编号】的方式执行,此方式在编写SQL语句时很方便,而在执行SQL语句环节就显得不太优雅;另外我们也介绍了使用映射器完成对数…

杂记 | 使用gitlab-runner将python项目以docker镜像方式流水线部署到服务器(解决部署缓慢和时区不对的问题)

文章目录 01 需求背景1.1 需求1.2 步骤 02 编写BaseDockerfile2.1 编写2.2 说明2.3 执行 03 编写Dockerfile04 编写.gitlab-ci.yml05 项目结构 01 需求背景 1.1 需求 我有一个python项目,该项目可能是一个服务器监控程序,也可能是一个后端程序&#xf…

ChatGLM GPT原理介绍

图解GPT 除了BERT以外,另一个预训练模型GPT也给NLP领域带来了不少轰动,本节也对GPT做一个详细的讲解。 OpenAI提出的GPT-2模型(https://openai.com/blog/better-language-models/) 能够写出连贯并且高质量的文章,比之前语言模型效果好很多。GPT-2是基于Transformer搭建的,相…

使用 PyTorch 的计算机视觉简介 (1/6)

一、说明 Computer Vision(CV)是一个研究计算机如何从数字图像和/或视频中获得一定程度的理解的领域。理解这个定义具有相当广泛的含义 - 它可以从能够区分图片上的猫和狗,到更复杂的任务,例如用自然语言描述图像。 二、CV常见的问…

Python类练习

文章目录 题目要求步骤 题目要求 1)创建一个 Kid 类,包含姓名,性别,年龄属性和 play 方法 2) 创建一个 Stu 类,继承 Kid 类,同时包含成绩属性,获取成绩方法,努力学习方法,play方法&…

Java笔记:看清类加载过程

1 类加载的过程 1.1 加载 “加载”是“类加载”(Class Loading)过程的第一步。这个加载过程主要就是靠类器实现的,包括用户自定义类加载器。 加载的过程 在加载的过程中,JVM主要做3件事情 1)通过一个类的全限定名来获取定义此类的二进制字节…

Latex Overleaf 写作问题记录

Latex & Overleaf 写作问题记录 公式换行及排列整齐 \begin{equation} \begin{split}Y & a1\\&b2 \end{split} \end{equation}顶格 \noindent求和符号 求和符号(上下限上下排列) \sum\limlits求和符号(上下限右边排列&#…

一键集成prometheus监控微服务接口平均响应时长

一、效果展示 二、环境准备 prometheus + grafana环境 参考博文:https://blog.csdn.net/luckywuxn/article/details/129475991 三、导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter

《Playing repeated games with Large Language Models》全文翻译

《Playing repeated games with Large Language Models》- 使用大型语言模型玩重复游戏 论文信息摘要1. 介绍2. 相关工作3. 一般方法4. 分析不同游戏系列的行为5. 囚徒困境5.1 性别之战 6. 讨论 论文信息 题目&#xff1a;《Playing repeated games with Large Language Model…

QT:使用堆叠窗口、标签、下拉条

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QStackedWidget> //堆叠窗口 #include <QComboBox> //下拉条 #include <QLabel> //标签class Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *p…