查看原文
其他

动态烟花效果的实现

武辛 地学分析与算法 2022-05-17




国庆发了一张庆祝新中国成立70周年的燃放烟花动态图,今天分享如何通过Python实现这个烟花效果。


01分析


烟花燃放有一个过程:上升阶段、爆炸阶段、收尾坠落阶段。在这里主要通过Python中tkinter包来实现整个燃放的过程。在上升阶段,我们随机生成多个粒子,设定一个上升阶段持续的时间,并按dt时间来更新粒子的位置
# 上升阶段,随机生成粒子for point in range(numb_explode): objects = [] x_cordi = randint(50, self.width - 50) y_cordi = randint(50, 150) speed = uniform(0.5, 1.5) size = uniform(0.5, 3) color = choice(colors) explosion_speed = uniform(5, 1) total_particles = randint(10, 50) # 上升的点 r = Particle(self.cv, idx = 0, total= total_particles, explosion_speed = explosion_speed, bottom = y_cordi, x = x_cordi, y = bottom, vx = speed, vy = speed, color = color, size = 3, lifespan = uniform(0.6, 1.75)) rise_points.append(r)
# 更新粒子上升阶段位置total_time = .0while total_time < 0.5: if self.show_rise == False: break sleep(0.01) tnew = time() t, dt = tnew, tnew - t for point in rise_points: point.rise(dt) self.cv.update() savename = 'images/im_{0:0>6}'.format(self.index) if self.index % 3 == 0: ImageGrab.grab((0,0,self.width, self.height)).save(savename + '.jpg') self.index += 1 total_time += dt


爆炸阶段,一个粒子就会变成很多个小粒子,并往外扩散,因此我们需要将一个粒子随机变成多个小粒子,并对这些小粒子并按圆圈的形式更新其位置,设定一个扩散的持续时间,当超过该持续时间,这些小粒子就按自由落体更新位置。

# 爆炸阶段,生成多个小粒子for point in rise_points: objects = [] x_cordi = point.x y_cordi = point.bottom explosion_speed = point.initial_speed speed = point.vx color = point.color total_particles = point.total

for i in range(1, total_particles): r = Particle(self.cv, idx = i, total= total_particles, explosion_speed = explosion_speed, bottom = bottom, x = x_cordi, y = y_cordi, vx = speed, vy = speed, color = color, size = size, lifespan = uniform(0.6, 1.75)) objects.append(r) explode_points.append(objects)


# 更新扩散阶段和收尾阶段粒子d额位置def update(self, dt): self.age += dt
# 爆炸阶段,扩散1.2s 粒子范围扩大 if self.alive() and self.expand(): move_x = cos(radians(self.id * 360 / self.total)) * self.initial_speed move_y = sin(radians(self.id * 360 / self.total)) * self.initial_speed self.cv.move(self.cid, move_x, move_y) self.vx = move_x / (float(dt) * 1000)
# 收尾阶段,持续时间不超过lifespan,以自由落体坠落 elif self.alive(): move_x = cos(radians(self.id * 360 / self.total)) self.cv.move(self.cid, self.vx + move_x, self.vy + GRAVITY * dt) self.vy += GRAVITY * dt
# 移除超过最高时长的粒子 elif self.cid is not None: self.cv.delete(self.cid) self.cid = None最后将其保存为GIF动图,将多幅静态过程合成动态形式。


02展示


无上升阶段效果图:


有上升阶段效果图:


双向Dijkstra算法

EndNote引文编排

利用GN算法进行社区发现

Python爬取高德地图--瓦片图

水位时态数据在地图上的动态展示

ArcPy批量定义投影和批量投影转换

机器人局部规划算法--DWA算法原理

ArcGIS时间滑块实现车辆轨迹动态展示

多时间序列数据MK突变检验突变点提取

GPS数据处理---在野外采样寻点中的应用

世界各国GDP排名变化--Matlab动图实现

世界各国GDP排名变化--Python动图实现

更多精彩推荐,敬请关注我们

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存