diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed8ebf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ \ No newline at end of file diff --git a/gas_sim.py b/gas_sim.py index 5cc53cf..5f1c567 100644 --- a/gas_sim.py +++ b/gas_sim.py @@ -1,30 +1,23 @@ from math import hypot -class Particle: - def __init__(self, pos, vel): - self.pos = pos - self.vel = vel - - def update(self, dt): - self.pos = (self.pos[0] + self.vel[0] * dt, self.pos[1] + self.vel[1] * dt) - - class GasSim: - def __init__(self, particle_radius, particle_compressibility, substeps): + def __init__(self, particle_radius, particle_compressibility, particle_friction, substeps): self.particle_radius = particle_radius self.particle_compressibility = particle_compressibility + self.particle_friction = particle_friction self.substeps = substeps self.particles = [] + self.walls = [] def add_particle(self, pos, vel = (0, 0)): - self.particles.append(Particle(pos, vel)) - - def return_particles_pos(self): - return tuple(particle.pos for particle in self.particles) + self.particles.append([pos, vel]) def cursor_particle_collide_test(self, cursor_pos, cursor_radius): for particle in self.particles: - if hypot(particle.pos[0] - cursor_pos[0], particle.pos[1] - cursor_pos[1]) <= cursor_radius + self.particle_radius: - return True \ No newline at end of file + if hypot(particle[0][0] - cursor_pos[0], particle[0][1] - cursor_pos[1]) <= cursor_radius + self.particle_radius: + return True + + def add_wall(self, start, end): + self.walls.append((start, end)) \ No newline at end of file diff --git a/main.py b/main.py index 4dbce2e..617eac1 100644 --- a/main.py +++ b/main.py @@ -1,15 +1,18 @@ import pygame import pygame.gfxdraw import gas_sim as gs +import numpy as np ##### CONFIG ##### window_size = (1280, 720) +target_fps = 60 + +particle_radius_ws = 0.025 +particle_compressibility = 0.1 +particle_friction = 0.1 -particle_radius_ws = 0.1 -particle_compressibility = 0.5 - -cursor_radius_ws = 0.1 +cursor_radius_ws = 0.15 substeps = 10 ################## @@ -19,6 +22,7 @@ substeps = 10 window_aspect = window_size[0] / window_size[1] cursor_radius_ss = cursor_radius_ws * window_size[1] +particle_radius_ss = particle_radius_ws * window_size[1] # pygame init @@ -27,9 +31,19 @@ window = pygame.display.set_mode(window_size) clock = pygame.time.Clock() - # gas sim init -gas_sim = gs.GasSim(particle_radius_ws, particle_compressibility, substeps) +gas_sim = gs.GasSim(particle_radius_ws, particle_compressibility, particle_friction, substeps) + + +# add walls +gas_sim.add_wall((0, 0), (window_aspect, 0)) +gas_sim.add_wall((0, 1), (window_aspect, 1)) +gas_sim.add_wall((0, 0), (0, 1)) +gas_sim.add_wall((1, 0), (1, 1)) + + +not_loaded_particles = True +dt = target_fps / 1000 @@ -50,9 +64,35 @@ while True: mouse_pos_ws = (mouse_pos_ss[0] / window_size[1], mouse_pos_ss[1] / window_size[1]) # if not colliding with any particles - if not gas_sim.cursor_particle_collide_test(mouse_pos_ws, cursor_radius_ws): + if not gas_sim.cursor_particle_collide_test(mouse_pos_ws, particle_radius_ws): gas_sim.add_particle(mouse_pos_ws) + # on s key press + if pygame.key.get_pressed()[pygame.K_s]: + # save particles to file + particles = tuple(pos for pos, _ in gas_sim.particles) + np.save("particles.npy", particles) + + print("Saved particles to file") + + # on l key press + if not_loaded_particles and pygame.key.get_pressed()[pygame.K_l]: + # load particles from file + particles = np.load("particles.npy") + for particle in particles: + gas_sim.add_particle(particle) + + print("Loaded particles from file") + + not_loaded_particles = False + + + + # update particles + #gas_sim.update(dt) + + + window.fill((0, 0, 0)) @@ -61,11 +101,11 @@ while True: pygame.gfxdraw.aacircle(window, cursor_pos[0], cursor_pos[1], int(cursor_radius_ss), (255, 255, 255)) # draw particles - for particle_pos in gas_sim.return_particles_pos(): + for particle_pos, _ in gas_sim.particles: particle_pos_ss = (int(particle_pos[0] * window_size[1]), int(particle_pos[1] * window_size[1])) - pygame.gfxdraw.aacircle(window, particle_pos_ss[0], particle_pos_ss[1], int(cursor_radius_ss), (255, 255, 255)) + pygame.gfxdraw.aacircle(window, particle_pos_ss[0], particle_pos_ss[1], int(particle_radius_ss), (255, 255, 255)) # update pygame.display.update() - clock.tick(60) \ No newline at end of file + dt = clock.tick(60) / 1000 \ No newline at end of file diff --git a/particles.npy b/particles.npy new file mode 100644 index 0000000..cf35a8f Binary files /dev/null and b/particles.npy differ