A high-performance particle simulation system with advanced spatial partitioning in C++.
Sand_Cmulation is a project that implements a particle-based sand simulation with efficient spatial queries and grid operations. The system uses a combination of grid-based storage and spatial hashing to achieve high-performance particle operations.
- High-performance spatial partitioning with O(1) lookups
- Thread-safe operations with OpenMP parallelization
- Advanced spatial queries (radius, box, k-nearest neighbors)
- Memory-efficient particle storage
- Real-time memory usage monitoring
- Optimized batch operations
The project is currently in development. The grid system is visually functional, demonstrating the basic particle simulation capabilities.
The core of the simulation is the GridSpatialConnector
which provides a unified interface between the grid storage and spatial hash systems:
- Grid: Stores particles in a 2D array
- SpatialHash: Provides O(1) spatial lookups
- QuerySystem: Handles advanced spatial queries
- GridOperations: Manages grid-level operations
The following metrics were measured on an i9 9900KF processor with DDR4 @ 3200MHz:
- Insertion: ~613k particles/second
- Queries: ~49k queries/second
- Batch sync: ~2.4M updates/second
- Movement: ~79k moves/second
// Initialize systems
Grid grid(1000, 1000);
SpatialHash spatialHash;
GridSpatialConnector connector(grid, spatialHash);
// Basic particle operations
Particle sand;
connector.addParticle(x, y, sand);
connector.moveParticle(oldX, oldY, newX, newY);
// Get neighboring cells
auto neighbors = connector.getNeighbors(x, y);
// Advanced spatial queries
Vector2D pos(x, y);
float radius = 5.0f;
auto nearbyParticles = connector.queryRadius(pos, radius);
// Box query
Vector2D min(x1, y1), max(x2, y2);
auto particlesInBox = connector.queryBox(min, max);
// K-nearest neighbors
auto nearestParticles = connector.queryKNearest(pos, 10);
addParticle()
: Add new particleremoveParticle()
: Remove particlemoveParticle()
: Move particle with boundary checkinggetNeighbors()
: Get valid neighboring cells
queryArea()
: Simple area queryisValidPosition()
: Position validationisEmpty()
: Cell emptiness check
queryRadius()
: Radius-based searchqueryRadiusFiltered()
: Filtered radius searchqueryBox()
: Box-bounded searchqueryKNearest()
: K-nearest neighborsqueryDenseRegions()
: Density-based search
getWidth()
: Grid widthgetHeight()
: Grid heightgetParticle()
: Particle access
update()
: System syncclear()
: System resetbatchSyncDirtyStates()
: Force sync
getMetrics()
: Performance metricsresetMetrics()
: Reset counters
getCurrentMemoryUsage()
: Get current memory usagegetPeakMemoryUsage()
: Get peak memory usagegetMemoryAllocationMap()
: Get detailed memory allocation map
The current user interface is minimal and designed primarily to visually verify that the grid system is working correctly. As this was a CS50X final project idea, the focus has been on implementing the core simulation functionality rather than a polished UI.
- Implement a more user-friendly interface
- Add more particle types and interactions
- Optimize memory usage for larger simulations
- Add persistence for saving/loading simulation states
make
./sand_simulation
- C++17 compatible compiler
- OpenMP for parallel processing
- SDL2 library