added cursor force and more other changes
This commit is contained in:
parent
77bc6c4c71
commit
d2fd778fbc
16
.vscode/launch.json
vendored
Normal file
16
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Python: main file",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "main.py",
|
||||
"console": "integratedTerminal",
|
||||
"justMyCode": true
|
||||
}
|
||||
]
|
||||
}
|
35
gas_sim.py
35
gas_sim.py
@ -2,22 +2,39 @@ from math import hypot
|
||||
|
||||
|
||||
class GasSim:
|
||||
def __init__(self, particle_radius, particle_compressibility, particle_friction, substeps):
|
||||
def __init__(self, particle_radius, particle_compressibility, particle_friction, substeps, window_aspect):
|
||||
self.particle_radius = particle_radius
|
||||
self.particle_compressibility = particle_compressibility
|
||||
self.particle_friction = particle_friction
|
||||
self.substeps = substeps
|
||||
|
||||
self.window_aspect = window_aspect
|
||||
|
||||
self.particles = []
|
||||
self.walls = []
|
||||
|
||||
def add_particle(self, pos, vel = (0, 0)):
|
||||
self.particles.append([pos, vel])
|
||||
def add_particle(self, pos, vel = [0, 0]):
|
||||
self.particles.append([list(pos).copy(), vel.copy()])
|
||||
|
||||
def cursor_particle_collide_test(self, cursor_pos, cursor_radius):
|
||||
def circle_particle_collide_test(self, pos, radius):
|
||||
for particle in self.particles:
|
||||
if hypot(particle[0][0] - cursor_pos[0], particle[0][1] - cursor_pos[1]) <= cursor_radius + self.particle_radius:
|
||||
if hypot(particle[0][0] - pos[0], particle[0][1] - pos[1]) <= radius + self.particle_radius:
|
||||
return True
|
||||
|
||||
def add_wall(self, start, end):
|
||||
self.walls.append((start, end))
|
||||
|
||||
def circle_force(self, pos, radius, vector, dt):
|
||||
for i, particle in enumerate(self.particles):
|
||||
if hypot(particle[0][0] - pos[0], particle[0][1] - pos[1]) <= radius + self.particle_radius:
|
||||
self.particles[i][1][0] += vector[0] * dt
|
||||
self.particles[i][1][1] += vector[1] * dt
|
||||
|
||||
def update(self, dt):
|
||||
# substeps
|
||||
for _ in range(self.substeps):
|
||||
# update particles
|
||||
for i, particle in enumerate(self.particles):
|
||||
|
||||
#
|
||||
|
||||
|
||||
# position
|
||||
self.particles[i][0][0] += particle[1][0] * dt / self.substeps
|
||||
self.particles[i][0][1] += particle[1][1] * dt / self.substeps
|
65
main.py
65
main.py
@ -2,6 +2,7 @@ import pygame
|
||||
import pygame.gfxdraw
|
||||
import gas_sim as gs
|
||||
import numpy as np
|
||||
import random
|
||||
|
||||
##### CONFIG #####
|
||||
window_size = (1280, 720)
|
||||
@ -32,21 +33,13 @@ clock = pygame.time.Clock()
|
||||
|
||||
|
||||
# gas sim init
|
||||
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))
|
||||
gas_sim = gs.GasSim(particle_radius_ws, particle_compressibility, particle_friction, substeps, window_aspect)
|
||||
|
||||
|
||||
not_loaded_particles = True
|
||||
dt = target_fps / 1000
|
||||
|
||||
|
||||
|
||||
# main loop
|
||||
while True:
|
||||
# events
|
||||
@ -55,8 +48,31 @@ while True:
|
||||
pygame.quit()
|
||||
quit()
|
||||
|
||||
elif event.type == pygame.KEYDOWN:
|
||||
# on s key press
|
||||
if event.key == pygame.K_s:
|
||||
# save particles to file
|
||||
particles = tuple(pos for pos, _ in gas_sim.particles)
|
||||
np.save("particles.npy", particles)
|
||||
|
||||
# on mouse down
|
||||
print("Saved particles to file")
|
||||
|
||||
# on l key press
|
||||
elif event.key == pygame.K_l:
|
||||
if not_loaded_particles:
|
||||
# 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
|
||||
else:
|
||||
print("Particles already loaded !!!")
|
||||
|
||||
|
||||
# on left mouse down
|
||||
if pygame.mouse.get_pressed()[0]:
|
||||
|
||||
mouse_pos_ss = pygame.mouse.get_pos()
|
||||
@ -64,33 +80,20 @@ 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, particle_radius_ws):
|
||||
if not gas_sim.circle_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
|
||||
# on right mouse down
|
||||
elif pygame.mouse.get_pressed()[2]:
|
||||
# apply wind force
|
||||
mouse_pos_ss = pygame.mouse.get_pos()
|
||||
mouse_pos_ws = (mouse_pos_ss[0] / window_size[1], mouse_pos_ss[1] / window_size[1])
|
||||
|
||||
gas_sim.circle_force(mouse_pos_ws, cursor_radius_ws, (0.2, random.uniform(-0.5, 0.5)), dt)
|
||||
|
||||
|
||||
# update particles
|
||||
#gas_sim.update(dt)
|
||||
|
||||
gas_sim.update(dt)
|
||||
|
||||
|
||||
|
||||
|
BIN
particles.npy
BIN
particles.npy
Binary file not shown.
Loading…
Reference in New Issue
Block a user