made small updates to the spatial grid
rearranged some of the code for better readability
This commit is contained in:
parent
a03ba2b950
commit
05e37a0bd5
Binary file not shown.
Binary file not shown.
@ -69,7 +69,7 @@ class Rendering:
|
|||||||
|
|
||||||
base_color = particle_colors.get(particle.particle_type, (255, 255, 255))
|
base_color = particle_colors.get(particle.particle_type, (255, 255, 255))
|
||||||
color = list(base_color)
|
color = list(base_color)
|
||||||
|
|
||||||
if particle.is_gas:
|
if particle.is_gas:
|
||||||
# Enhanced gas visibility
|
# Enhanced gas visibility
|
||||||
alpha = random.randint(128, 200)
|
alpha = random.randint(128, 200)
|
||||||
|
|||||||
2
setup.py
2
setup.py
@ -4,5 +4,5 @@ from setuptools import setup
|
|||||||
from Cython.Build import cythonize
|
from Cython.Build import cythonize
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
ext_modules=cythonize("sandpypi/simulation_core.pyx"),
|
ext_modules=cythonize("simulation_core.pyx"),
|
||||||
)
|
)
|
||||||
|
|||||||
132
sim.py
132
sim.py
@ -76,6 +76,36 @@ class Simulation:
|
|||||||
self.wind = [0.0, 0.0] # Global wind vector (x, y)
|
self.wind = [0.0, 0.0] # Global wind vector (x, y)
|
||||||
|
|
||||||
|
|
||||||
|
def get_cell_key(self, x, y): # this is where we get the cell key.
|
||||||
|
# Convert coordinates to grid cell
|
||||||
|
cell_x = x // self.cell_size
|
||||||
|
cell_y = y // self.cell_size
|
||||||
|
return (cell_x, cell_y)
|
||||||
|
|
||||||
|
|
||||||
|
def add_to_spatial_grid(self, particle, x, y): # this is where we add to the spatial grid.
|
||||||
|
cell_key = self.get_cell_key(x, y)
|
||||||
|
if cell_key not in self.spatial_grid:
|
||||||
|
self.spatial_grid[cell_key] = set()
|
||||||
|
self.spatial_grid[cell_key].add((x, y))
|
||||||
|
return cell_key
|
||||||
|
|
||||||
|
|
||||||
|
def remove_from_spatial_grid(self, x, y): # this is where we remove from the spatial grid.
|
||||||
|
cell_key = self.get_cell_key(x, y)
|
||||||
|
if cell_key in self.spatial_grid:
|
||||||
|
self.spatial_grid[cell_key].discard((x, y))
|
||||||
|
return cell_key
|
||||||
|
|
||||||
|
|
||||||
|
def update_spatial_grid(self): # this is where we update the spatial grid.
|
||||||
|
"""Update spatial grid for optimized collision detection"""
|
||||||
|
self.spatial_grid.clear()
|
||||||
|
for x, y in self.active_particles:
|
||||||
|
self.add_to_spatial_grid(self.particles[x][y], x, y)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def handle_phase_transitions(self, particle, x, y): # this is where we handle all the phase transitions.
|
def handle_phase_transitions(self, particle, x, y): # this is where we handle all the phase transitions.
|
||||||
"""Handle all phase transitions for a particle"""
|
"""Handle all phase transitions for a particle"""
|
||||||
# Check evaporation
|
# Check evaporation
|
||||||
@ -101,6 +131,7 @@ class Simulation:
|
|||||||
|
|
||||||
def handle_particle_interactions(self, dt): # this is where we handle all the particle interactions.
|
def handle_particle_interactions(self, dt): # this is where we handle all the particle interactions.
|
||||||
"""Handle interactions between different particle types"""
|
"""Handle interactions between different particle types"""
|
||||||
|
self.update_spatial_grid()
|
||||||
for x, y in list(self.active_particles):
|
for x, y in list(self.active_particles):
|
||||||
particle = self.particles[x][y]
|
particle = self.particles[x][y]
|
||||||
if not particle:
|
if not particle:
|
||||||
@ -253,6 +284,33 @@ class Simulation:
|
|||||||
self.ignite_particle(neighbor)
|
self.ignite_particle(neighbor)
|
||||||
|
|
||||||
|
|
||||||
|
def handle_special_particles(self, particle, x, y): # this is where we handle special particles.
|
||||||
|
"""Handle special particle behaviors"""
|
||||||
|
if particle.particle_type in ['fire', 'flame', 'smoke']:
|
||||||
|
if random.random() < 0.6: # % chance
|
||||||
|
self.particles[x][y] = None
|
||||||
|
self.active_particles.discard((x, y))
|
||||||
|
|
||||||
|
if particle.particle_type in ['fire', 'flame', 'lava']:
|
||||||
|
# Create smoke above with proper physics
|
||||||
|
if random.random() < 0.65 and y > 0: # % chance for smoke
|
||||||
|
properties = self.particle_properties['smoke']
|
||||||
|
new_smoke = Particle.from_type((x, y-1), 'smoke', properties)
|
||||||
|
if self.particles[x][y-1] is None:
|
||||||
|
self.particles[x][y-1] = new_smoke
|
||||||
|
self.active_particles.add((x, y-1))
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Handle collision with water
|
||||||
|
if particle.particle_type == 'water':
|
||||||
|
self.particles[x][y-1] = None
|
||||||
|
self.active_particles.discard((x, y-1))
|
||||||
|
self.particles[x][y] = None
|
||||||
|
self.active_particles.discard((x, y))
|
||||||
|
self.particles[x][y] = Particle.from_type((x, y), 'water', self.particle_properties['water'])
|
||||||
|
self.active_particles.add((x, y))
|
||||||
|
|
||||||
|
|
||||||
def handle_temperature(self, dt): # this is where we handle the temperature.
|
def handle_temperature(self, dt): # this is where we handle the temperature.
|
||||||
"""Handle temperature changes and state transitions"""
|
"""Handle temperature changes and state transitions"""
|
||||||
for x, y in list(self.active_particles):
|
for x, y in list(self.active_particles):
|
||||||
@ -298,36 +356,7 @@ class Simulation:
|
|||||||
if particle.temperature > 1000:
|
if particle.temperature > 1000:
|
||||||
self.particles[x][y] = None
|
self.particles[x][y] = None
|
||||||
self.active_particles.remove((x, y))
|
self.active_particles.remove((x, y))
|
||||||
self.spatial_grid.pop((x, y), None)
|
self.spatial_grid.pop((x, y), None)
|
||||||
|
|
||||||
|
|
||||||
def get_cell_key(self, x, y): # this is where we get the cell key.
|
|
||||||
# Convert coordinates to grid cell
|
|
||||||
cell_x = x // self.cell_size
|
|
||||||
cell_y = y // self.cell_size
|
|
||||||
return (cell_x, cell_y)
|
|
||||||
|
|
||||||
|
|
||||||
def add_to_spatial_grid(self, particle, x, y): # this is where we add to the spatial grid.
|
|
||||||
cell_key = self.get_cell_key(x, y)
|
|
||||||
if cell_key not in self.spatial_grid:
|
|
||||||
self.spatial_grid[cell_key] = set()
|
|
||||||
self.spatial_grid[cell_key].add((x, y))
|
|
||||||
|
|
||||||
|
|
||||||
def remove_from_spatial_grid(self, x, y): # this is where we remove from the spatial grid.
|
|
||||||
cell_key = self.get_cell_key(x, y)
|
|
||||||
if cell_key in self.spatial_grid:
|
|
||||||
self.spatial_grid[cell_key].discard((x, y))
|
|
||||||
|
|
||||||
|
|
||||||
def create_particle_circle(self, center_x, center_y): # this is where we create the particle circle.
|
|
||||||
brush_size = int(self.brush_size)
|
|
||||||
for dx in range(-brush_size, brush_size + 1):
|
|
||||||
for dy in range(-brush_size, brush_size + 1):
|
|
||||||
if dx*dx + dy*dy <= brush_size*brush_size: # Circle check
|
|
||||||
self.create_particle(center_x + dx * self.particle_size,
|
|
||||||
center_y + dy * self.particle_size)
|
|
||||||
|
|
||||||
|
|
||||||
def create_particle(self, x, y): # this is where we create the particle.
|
def create_particle(self, x, y): # this is where we create the particle.
|
||||||
@ -351,13 +380,15 @@ class Simulation:
|
|||||||
self.particles[grid_x][grid_y] = new_particle
|
self.particles[grid_x][grid_y] = new_particle
|
||||||
self.active_particles.add((grid_x, grid_y))
|
self.active_particles.add((grid_x, grid_y))
|
||||||
|
|
||||||
|
|
||||||
def update_spatial_grid(self): # this is where we update the spatial grid.
|
def create_particle_circle(self, center_x, center_y): # this is where we create the particle circle.
|
||||||
"""Update spatial grid for optimized collision detection"""
|
brush_size = int(self.brush_size)
|
||||||
self.spatial_grid.clear()
|
for dx in range(-brush_size, brush_size + 1):
|
||||||
for x, y in self.active_particles:
|
for dy in range(-brush_size, brush_size + 1):
|
||||||
self.add_to_spatial_grid(self.particles[x][y], x, y)
|
if dx*dx + dy*dy <= brush_size*brush_size: # Circle check
|
||||||
|
self.create_particle(center_x + dx * self.particle_size,
|
||||||
|
center_y + dy * self.particle_size)
|
||||||
|
|
||||||
|
|
||||||
def apply_gravity(self, dt): # this is where we apply gravity.
|
def apply_gravity(self, dt): # this is where we apply gravity.
|
||||||
"""Handle only gravity and basic particle movement"""
|
"""Handle only gravity and basic particle movement"""
|
||||||
@ -419,33 +450,6 @@ class Simulation:
|
|||||||
particle.position = (new_x, new_y)
|
particle.position = (new_x, new_y)
|
||||||
|
|
||||||
|
|
||||||
def handle_special_particles(self, particle, x, y): # this is where we handle special particles.
|
|
||||||
"""Handle special particle behaviors"""
|
|
||||||
if particle.particle_type in ['fire', 'flame', 'smoke']:
|
|
||||||
if random.random() < 0.6: # % chance
|
|
||||||
self.particles[x][y] = None
|
|
||||||
self.active_particles.discard((x, y))
|
|
||||||
|
|
||||||
if particle.particle_type in ['fire', 'flame', 'lava']:
|
|
||||||
# Create smoke above with proper physics
|
|
||||||
if random.random() < 0.65 and y > 0: # % chance for smoke
|
|
||||||
properties = self.particle_properties['smoke']
|
|
||||||
new_smoke = Particle.from_type((x, y-1), 'smoke', properties)
|
|
||||||
if self.particles[x][y-1] is None:
|
|
||||||
self.particles[x][y-1] = new_smoke
|
|
||||||
self.active_particles.add((x, y-1))
|
|
||||||
|
|
||||||
else:
|
|
||||||
# Handle collision with water
|
|
||||||
if particle.particle_type == 'water':
|
|
||||||
self.particles[x][y-1] = None
|
|
||||||
self.active_particles.discard((x, y-1))
|
|
||||||
self.particles[x][y] = None
|
|
||||||
self.active_particles.discard((x, y))
|
|
||||||
self.particles[x][y] = Particle.from_type((x, y), 'water', self.particle_properties['water'])
|
|
||||||
self.active_particles.add((x, y))
|
|
||||||
|
|
||||||
|
|
||||||
def apply_physics(self, dt): # this is where we apply physics.
|
def apply_physics(self, dt): # this is where we apply physics.
|
||||||
"""Handle all physics effects"""
|
"""Handle all physics effects"""
|
||||||
new_active_particles = set()
|
new_active_particles = set()
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
# simulation_core.pyx
|
# simulation_core.pyx
|
||||||
|
# Cython code for simulating the physics of the system
|
||||||
|
|
||||||
cimport cython
|
cimport cython
|
||||||
from libc.math cimport sqrt
|
from libc.math cimport sqrt
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user