From 0affb60ae1d840ad0e219fc1ddd6f7de5d3169df Mon Sep 17 00:00:00 2001 From: Sara Date: Tue, 28 Oct 2025 22:22:12 +0100 Subject: [PATCH] feat: updated for documentation and testing --- CHANGES.md | 15 +++++++++++++++ src/collision_crisis.cpp | 2 +- src/simulation_v2.cpp | 11 +++++++---- 3 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 CHANGES.md diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..f4e7e69 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,15 @@ +# Optimalizaties + +## Spatial Hashing + +In 2d, de meest efficiente spatial-hashing strategie is vlakkenverdeling. Het is simpel voor hashing en hash searches om een ruimte op te delen in gelijkmatige vlakken. + +Voor hashing moet een datastructuur worden teruggebracht naar een nummer. Mijn implementatie verdeeld een 8-bit unsigned int over 2 delen, de meest significante 4 bits worden gebruikt door de x coordinaat, en de minst significante 4 de y coordinaat. + +Het systeem waar deze coordinaten naar verwijzen is de het vlak in de vlakkenverdeling waarin een positie zich bevind. + +> Met 8 bits hebben we 255 mogelijke opties, dit betekend dat de grootste vlakkenverdeling mogelijk 16x16 is. + +## Performance + +De performance-verbetering door deze hashing-strategie is redelijk hoog. Gemiddelde frametime valt van `0.08...` naar `0.03...` gemiddeld op mijn AMD Ryzen AI 9 HX 370 met `2500` particles (de standaard hoeveelheid waarmee de voorbeeldimplementatie is aangeleverd). diff --git a/src/collision_crisis.cpp b/src/collision_crisis.cpp index 465dbb1..2d45311 100644 --- a/src/collision_crisis.cpp +++ b/src/collision_crisis.cpp @@ -32,7 +32,7 @@ void setup() { ImGui::GetIO().ConfigFlags |= (ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad | ImGuiConfigFlags_DockingEnable); sf::View view{get_window().getView()}; set_render_view(view); - v2::initialize(2500, {{50,50}, {1000, 1000}}); + v2::initialize(2500, {{50,50}, {3000, 2000}}); } void handle_input_event(sf::Event const &event) { diff --git a/src/simulation_v2.cpp b/src/simulation_v2.cpp index a685af2..f33adcc 100644 --- a/src/simulation_v2.cpp +++ b/src/simulation_v2.cpp @@ -15,8 +15,8 @@ #include #include -#define HASH_BUCKETS 10 -#define HASH_GRID_DIVISIONS 2 +#define HASH_BUCKETS 24 +#define HASH_GRID_DIVISIONS 18 namespace v2 { typedef uint8_t PointHash; @@ -67,7 +67,8 @@ void initialize(size_t particleCount, sf::FloatRect bounds) { worldBounds = bounds; std::mt19937 rng{std::mt19937()}; - std::uniform_real_distribution positionDist{std::uniform_real_distribution(5.0f, 795.0f)}; + std::uniform_real_distribution xPositionDist{std::uniform_real_distribution(bounds.position.x, bounds.position.x + bounds.size.x)}; + std::uniform_real_distribution yPositionDist{std::uniform_real_distribution(bounds.position.y, bounds.position.y + bounds.size.y)}; std::uniform_real_distribution velocityDist{std::uniform_real_distribution(-200.0f, 200.0f)}; std::uniform_int_distribution colorDist{std::uniform_int_distribution(0, 255)}; std::uniform_real_distribution radiusDist{std::uniform_real_distribution(2.5f, 2.5f)}; @@ -77,7 +78,7 @@ void initialize(size_t particleCount, sf::FloatRect bounds) { sf::CircleShape(radiusDist(rng)), sf::Vector2f{0, 0}); Particle &particle{particles[particles.size() - 1]}; - particle.shape.setPosition({positionDist(rng), positionDist(rng)}); + particle.shape.setPosition({xPositionDist(rng), yPositionDist(rng)}); particle.velocity = {velocityDist(rng), velocityDist(rng)}; particle.spatialHash = hashParticlePosition(particle); particle.shape.setFillColor({colorDist(rng), colorDist(rng), colorDist(rng), 255}); @@ -160,6 +161,7 @@ void tick(double delta) { } void draw(sf::RenderTarget *target) { +#if 0 sf::RectangleShape rect{worldBounds.size}; rect.setPosition(worldBounds.position); rect.setFillColor(sf::Color::Transparent); @@ -167,6 +169,7 @@ void draw(sf::RenderTarget *target) { rect.setOutlineThickness(3); target->draw(rect); sf::Vertex polygon[2]; +#endif for (Particle &particle : particles) { if (particle.active) { target->draw(particle.shape);