首页 > 解决方案 > 如何在流体模拟中添加暂停和开始按钮和一些滑块以实时更新而不重置?

问题描述

我有一些创建流体模拟的代码,我对其进行了更改,以便它无限期地继续运行和推进系统,直到用户关闭窗口。接下来,我想添加一个暂停和开始按钮和一些用于更改某些参数(即粘度、流入速度等)的滑块,以使其更具交互性。每次用户移动其中一个滑块时,我希望动画继续运行但使用新参数而不是重新开始。我无法找到任何资源来回答这个更新实时动画的问题。我该怎么做呢?谢谢你。

这是我的代码,向您展示我现在拥有的东西。我正在尝试在纯 matplotlib 中执行此操作。此代码确实有效,但尚未添加滑块和按钮

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from fluid import Fluid

RESOLUTION = 85, 160
VISCOSITY = 1e-5
INFLOW_RADIUS = RESOLUTION[0]*0.12
INFLOW_VELOCITY = RESOLUTION[1]*0.14

directions = (np.array([-0.2960987711,0.9551573264]), np.array([0,0]), np.array([0.2960987711,-0.9551573264]))
points = (np.array([RESOLUTION[0]*(0.225), 0]), np.array([-100, 0]), np.array([RESOLUTION[0]*(0.775), RESOLUTION[1]]))

channels = 'r', 'g', 'b'
fluid = Fluid(RESOLUTION, VISCOSITY, channels)


inflow_dye_field = np.zeros((fluid.size, len(channels))) # creating the array to be iterated over. This is the environment that the fluid will exist in
inflow_velocity_field = np.zeros_like(fluid.velocity_field) # creating the array for representing the initial velocity field which will tell the fluid how it needs to advance through successive iterations

def setup_flow():
    for i, p in enumerate(points):
        distance = np.linalg.norm(fluid.indices - p, axis=1)
        mask = distance <= INFLOW_RADIUS

        for d in range(2):
            inflow_velocity_field[..., d][mask] = directions[i][d] * INFLOW_VELOCITY

        inflow_dye_field[..., i][mask] = 1

setup_flow()

fig, ax = plt.subplots(figsize=(12,9))
fig.canvas.set_window_title('Fluid Simulation')

def animate(args):
   
    fluid.advect_diffuse()

    fluid.velocity_field += inflow_velocity_field

    for i, k in enumerate(channels):
        fluid.quantities[k] += inflow_dye_field[..., i]

    fluid.project()

    rgb = np.dstack(tuple(fluid.quantities[c] for c in channels))

    rgb = rgb.reshape((*RESOLUTION, 3))
    rgb = (np.clip(rgb, 0, 1) * 255).astype('uint8')
    
    im.set_data(rgb)

rgb = np.dstack(tuple(fluid.quantities[c] for c in channels))

rgb = rgb.reshape((*RESOLUTION, 3))
rgb = (np.clip(rgb, 0, 1) * 255).astype('uint8')

ax.xaxis.set_visible(False); ax.yaxis.set_visible(False)
im = ax.imshow(rgb, animated=True)
ani = animation.FuncAnimation(fig, animate, interval=30)
plt.show()

编辑:我曾尝试使用 Tkinter 来执行此操作,虽然在 Tkinter 窗口中嵌入 matplotlib 动画并不难,但 Tkinter 中的按钮和滑块不适用于嵌入式绘图。此外,将我的其余代码更改为纯 Tkinter 将起作用,但这将是一场绝对的噩梦,鉴于我拥有的时间,我对该库还没有足够的信心能够做到这一点。

标签: pythonmatplotlibanimationdynamicinteractive

解决方案


推荐阅读