matplotlib 齐次坐标系 绘制 2D 闪烁斑点

news/2024/11/17 23:32:55/

绘制闪烁的斑点群,需要考虑几个群体属性:群体的生成位置 (xylim),斑点数量 (n),斑点的半径均值 (r),斑点的寿命均值 (delta)

而对于每一个斑点,又需要考虑斑点个体属性:出生时间 (start)、出生位置 (xy)、半径 (radius)、颜色 (color)、寿命 (deltas),以控制斑点的外形和闪烁速度

在 Spot 这个对象中,我定义了以下几个函数:

  • __init__:将形参写入闪烁斑点的群体属性,并调用 produce 生成指定数量的斑点
  • produce:筛除寿命耗尽的斑点,并生成新的斑点的个体属性
  • scatter:根据群体属性 xylim 在指定方框内生成斑点的中心点,可重写
  • __call__:根据闪烁斑点的生存时间,计算闪烁斑点的不透明度,并利用 CoordSys_2d 对斑点的位置进行仿射变换,再逐一绘制斑点
import timeimport matplotlib.patches as pch
import matplotlib.pyplot as plt
import numpy as np# coord.py 详见: https://blog.csdn.net/qq_55745968/article/details/129912954
from coord import CoordSys_2dred = 'orangered'
orange = 'orange'
yellow = 'yellow'
green = 'greenyellow'
cyan = 'aqua'
blue = 'deepskyblue'
purple = 'mediumpurple'
pink = 'violet'class Spot:''' 闪烁斑点对象xylim: xy 坐标区间, [[xmin, ymin], [xmax, ymax]]n: 闪烁斑点的数量r: 斑点的半径均值, 标准差为 r/2, 最小值为 r/4delta: 斑点生存时间的均值, 标准差为 delta, 最小值为 delta/10'''colors = [red, orange, yellow, green, cyan, blue, purple, pink]def __init__(self, xylim: np.ndarray, n: int,r: float = .2, delta: float = 1., alpha: float = .7):# <群体属性>self.xylim = xylimself.n, self.r = n, rself.delta = deltaself.alpha = alpha# <个体属性># 出生时间, 生存时间self.start = np.array([])self.deltas = np.array([])# 出生位置, 半径, 颜色self.xy = np.ones([0, 2])self.radius = np.array([])self.color = np.array([])# 生产斑点self.produce()def scatter(self, n):return self.xylim[0] + np.random.rand(n, 2) * (self.xylim[1] - self.xylim[0])def produce(self, filt=None):# 筛除生存时间耗尽的斑点if isinstance(filt, np.ndarray):for key in ('start', 'color', 'xy', 'radius', 'deltas'):setattr(self, key, getattr(self, key)[filt])# 补全缺失的斑点lack = self.n - self.xy.shape[0]if lack > 0:# 记录出生时间, 生存时间self.start = np.concatenate((self.start, np.full(lack, fill_value=time.time())))self.deltas = np.concatenate((self.deltas, np.maximum(np.random.normal(loc=self.delta, scale=self.delta, size=lack), self.delta / 10)))# 随机位置, 随机半径, 随机颜色self.xy = np.concatenate((self.xy, self.scatter(lack)), axis=0)self.radius = np.concatenate((self.radius, np.maximum(np.random.normal(loc=self.r, scale=self.r / 2, size=lack), self.r / 4)))self.color = np.concatenate((self.color, np.random.choice(self.colors, size=lack)))def __call__(self, fig, state: CoordSys_2d = None):''' 刷新斑点的透明度state: CoordSys_2d 对象'''x = time.time() - self.start# y = 4/d^2 x (d - x)alpha = self.alpha * np.maximum(4 / self.deltas ** 2 * x * (self.deltas - x), 0)# 向图像添加斑点for i, xy in enumerate(np.stack(state.apply(*self.xy.T), axis=-1) if state else self.xy):patch = pch.Circle(xy, self.radius[i], alpha=alpha[i], edgecolor=None, facecolor=self.color[i])fig.add_patch(patch)self.produce(alpha > 0)

而对于闪烁斑点的旋转、平移,主要使用了 https://hebitzj.blog.csdn.net/article/details/129912954 中所编写的类 CoordSys_2d,这个类有以下几个主要函数:

  • transform:给定 x,y 轴上的偏移量、旋转角,并执行相对变换 / 绝对变换
  • apply:给定描述 x,y 的点集,根据齐次坐标系矩阵对该点集进行平移和旋转

利用这个类,可以实现闪烁斑点的持续旋转

if __name__ == '__main__':plt.rcParams['figure.figsize'] = [6.4, 6.4]fig = plt.subplot()# 初始化齐次坐标系state = CoordSys_2d()# 初始化闪烁斑点spot = Spot(xylim=np.array([[-2, 2], [-1, 1]]).T, n=100, r=.2, delta=1)while True:fig.cla()plt.xlim([-2, 2])plt.ylim([-2, 2])# 使当前的齐次坐标系旋转 2°state = state.transform(theta=2)# 调用闪烁斑点的 __call__ 函数绘制spot(fig, state=state)plt.pause(0.01)

http://www.ppmy.cn/news/40988.html

相关文章

Makefile学习6 - 条件判断

一. 前言 条件判断语句可以根据一个变量的值来控制make执行或者忽略Makefile的特定部分。条件语句可以是两个不同变量或者变量与常量值的比较。条件语句只能用于控制make实际执行的Makefile文件部分&#xff0c;不能控制规则的shell的执行过程。Makefile使用条件控制可以做到处…

Java知识点学习(第5天)

重载和重写的区别 重载&#xff1a;发生在同一个类中&#xff0c;方法名必须相同&#xff0c;参数类型不同、个数不同、顺序不同、方法返回值和访问修饰符可以不同&#xff0c;发生在编译的时候。 重写&#xff1a;发生在父子类中&#xff0c;方法名、参数列表必须相同&#…

国货之光!打工人必装的8个软件,你都用过没?|办公|效率|创作

给大家分享8款非常强大&#xff0c;但知名度不高的国产软件&#xff0c;每一个都堪称精品&#xff0c;喜欢的话记得点赞和关注哦~ 第一款是 火绒安全软件 火绒安全软件没有任何&#xff0c;具有推广性质的弹窗、没有捆绑打扰用户的行为&#xff1b;占用资源极少&#xff0c;&a…

【Docker】Docker安装Hadoop分布式集群

Docker安装分布式Hadoop集群 一、准备环境 1. 查看docker的hadoop镜像 docker search hadoop2. 拉取stars最多的镜像 docker pull sequenceiq/hadoop-docker3. 拉取完成后查看镜像是否已到本地 docker images 4. 运行第一个容器hadoop102 docker run --name hadoop102 …

不可变数据类型

不可变对象 不可变(immutable)&#xff1a; 即对象一旦被创建初始化后&#xff0c;内存中该类型的值永远不会改变&#xff0c;之后的每次改变都会产生一个新对象。 作为不可变类型&#xff0c;最主要的特性表现是&#xff1a;一旦创建&#xff0c;只要修改&#xff0c;就会在托…

cv2(OpenCV)下载安装

cv2对应库是OpenCV&#xff0c;官网下载链接&#xff1a;https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv 最好下载对应python版本的&#xff0c;通过pip命令安装可能会出现版本过高或者过低的问题&#xff0c;导致import cv2没问题&#xff0c;但是内部函数无法调用。 …

CSS选择器基础1.1(查找标签)

1&#xff0c;标签选择器&#xff08;以标签名命名的选择器&#xff09; 结构&#xff1a; 标签名{CSS属性名:属性值;} 注&#xff1a;选中所有的这个标签都生效CSS。 2&#xff0c;类选择器 结构&#xff1a; .类名{CSS属性名&#xff1a;属性值;} 作用&#xff1a;通过类…

「MongoDB」时序数据库和MongoDB第二部分-模式设计最佳实践

在上一篇博客文章时间序列数据与MongoDB&#xff1a;第一部分-简介中&#xff0c;我们介绍了时间序列数据的概念&#xff0c;然后介绍了一些可以用于帮助收集时间序列应用程序需求的发现问题。对这些问题的回答有助于指导支持大容量生产应用程序部署所需的模式和MongoDB数据库配…