style: aplicar fixes de clang-tidy (todo excepto uppercase-literal-suffix)
Corregidos ~2570 issues automáticamente con clang-tidy --fix-errors más ajustes manuales posteriores: - modernize: designated-initializers, trailing-return-type, use-auto, avoid-c-arrays (→ std::array<>), use-ranges, use-emplace, deprecated-headers, use-equals-default, pass-by-value, return-braced-init-list, use-default-member-init - readability: math-missing-parentheses, implicit-bool-conversion, braces-around-statements, isolate-declaration, use-std-min-max, identifier-naming, else-after-return, redundant-casting, convert-member-functions-to-static, make-member-function-const, static-accessed-through-instance - performance: avoid-endl, unnecessary-value-param, type-promotion, inefficient-vector-operation - dead code: XOR_KEY (orphan tras eliminar encryptData/decryptData), dead stores en engine.cpp y png_shape.cpp - NOLINT justificado en 10 funciones con alta complejidad cognitiva (initialize, render, main, processEvents, update×3, performDemoAction, randomizeOnDemoStart, renderDebugHUD, AppLogo::update) Compilación: gcc -Wall sin warnings. clang-tidy: 0 issues. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,39 +3,38 @@
|
||||
#include <algorithm> // for std::min, std::max
|
||||
#include <cmath> // for sqrt, atan2
|
||||
|
||||
#include "ball.hpp" // for Ball
|
||||
#include "engine.hpp" // for Engine (si se necesita)
|
||||
#include "scene/scene_manager.hpp" // for SceneManager
|
||||
#include "state/state_manager.hpp" // for StateManager
|
||||
#include "ui/ui_manager.hpp" // for UIManager
|
||||
#include "ball.hpp" // for Ball
|
||||
#include "engine.hpp" // for Engine (si se necesita)
|
||||
#include "scene/scene_manager.hpp" // for SceneManager
|
||||
#include "state/state_manager.hpp" // for StateManager
|
||||
#include "ui/ui_manager.hpp" // for UIManager
|
||||
|
||||
BoidManager::BoidManager()
|
||||
: engine_(nullptr)
|
||||
, scene_mgr_(nullptr)
|
||||
, ui_mgr_(nullptr)
|
||||
, state_mgr_(nullptr)
|
||||
, screen_width_(0)
|
||||
, screen_height_(0)
|
||||
, boids_active_(false)
|
||||
, spatial_grid_(800, 600, BOID_GRID_CELL_SIZE) // Tamaño por defecto, se actualiza en initialize()
|
||||
, separation_radius_(BOID_SEPARATION_RADIUS)
|
||||
, alignment_radius_(BOID_ALIGNMENT_RADIUS)
|
||||
, cohesion_radius_(BOID_COHESION_RADIUS)
|
||||
, separation_weight_(BOID_SEPARATION_WEIGHT)
|
||||
, alignment_weight_(BOID_ALIGNMENT_WEIGHT)
|
||||
, cohesion_weight_(BOID_COHESION_WEIGHT)
|
||||
, max_speed_(BOID_MAX_SPEED)
|
||||
, min_speed_(BOID_MIN_SPEED)
|
||||
, max_force_(BOID_MAX_FORCE)
|
||||
, boundary_margin_(BOID_BOUNDARY_MARGIN)
|
||||
, boundary_weight_(BOID_BOUNDARY_WEIGHT) {
|
||||
: engine_(nullptr),
|
||||
scene_mgr_(nullptr),
|
||||
ui_mgr_(nullptr),
|
||||
state_mgr_(nullptr),
|
||||
screen_width_(0),
|
||||
screen_height_(0),
|
||||
boids_active_(false),
|
||||
spatial_grid_(800, 600, BOID_GRID_CELL_SIZE) // Tamaño por defecto, se actualiza en initialize()
|
||||
,
|
||||
separation_radius_(BOID_SEPARATION_RADIUS),
|
||||
alignment_radius_(BOID_ALIGNMENT_RADIUS),
|
||||
cohesion_radius_(BOID_COHESION_RADIUS),
|
||||
separation_weight_(BOID_SEPARATION_WEIGHT),
|
||||
alignment_weight_(BOID_ALIGNMENT_WEIGHT),
|
||||
cohesion_weight_(BOID_COHESION_WEIGHT),
|
||||
max_speed_(BOID_MAX_SPEED),
|
||||
min_speed_(BOID_MIN_SPEED),
|
||||
max_force_(BOID_MAX_FORCE),
|
||||
boundary_margin_(BOID_BOUNDARY_MARGIN),
|
||||
boundary_weight_(BOID_BOUNDARY_WEIGHT) {
|
||||
}
|
||||
|
||||
BoidManager::~BoidManager() {
|
||||
}
|
||||
BoidManager::~BoidManager() = default;
|
||||
|
||||
void BoidManager::initialize(Engine* engine, SceneManager* scene_mgr, UIManager* ui_mgr,
|
||||
StateManager* state_mgr, int screen_width, int screen_height) {
|
||||
void BoidManager::initialize(Engine* engine, SceneManager* scene_mgr, UIManager* ui_mgr, StateManager* state_mgr, int screen_width, int screen_height) {
|
||||
engine_ = engine;
|
||||
scene_mgr_ = scene_mgr;
|
||||
ui_mgr_ = ui_mgr;
|
||||
@@ -65,7 +64,8 @@ void BoidManager::activateBoids() {
|
||||
auto& balls = scene_mgr_->getBallsMutable();
|
||||
for (auto& ball : balls) {
|
||||
// Dar velocidad inicial aleatoria si está quieto
|
||||
float vx, vy;
|
||||
float vx;
|
||||
float vy;
|
||||
ball->getVelocity(vx, vy);
|
||||
if (vx == 0.0f && vy == 0.0f) {
|
||||
// Velocidad aleatoria entre -60 y +60 px/s (time-based)
|
||||
@@ -76,13 +76,15 @@ void BoidManager::activateBoids() {
|
||||
}
|
||||
|
||||
// Mostrar notificación (solo si NO estamos en modo demo o logo)
|
||||
if (state_mgr_ && ui_mgr_ && state_mgr_->getCurrentMode() == AppMode::SANDBOX) {
|
||||
if ((state_mgr_ != nullptr) && (ui_mgr_ != nullptr) && state_mgr_->getCurrentMode() == AppMode::SANDBOX) {
|
||||
ui_mgr_->showNotification("Modo boids");
|
||||
}
|
||||
}
|
||||
|
||||
void BoidManager::deactivateBoids(bool force_gravity_on) {
|
||||
if (!boids_active_) return;
|
||||
if (!boids_active_) {
|
||||
return;
|
||||
}
|
||||
|
||||
boids_active_ = false;
|
||||
|
||||
@@ -92,7 +94,7 @@ void BoidManager::deactivateBoids(bool force_gravity_on) {
|
||||
}
|
||||
|
||||
// Mostrar notificación (solo si NO estamos en modo demo o logo)
|
||||
if (state_mgr_ && ui_mgr_ && state_mgr_->getCurrentMode() == AppMode::SANDBOX) {
|
||||
if ((state_mgr_ != nullptr) && (ui_mgr_ != nullptr) && state_mgr_->getCurrentMode() == AppMode::SANDBOX) {
|
||||
ui_mgr_->showNotification("Modo física");
|
||||
}
|
||||
}
|
||||
@@ -106,7 +108,9 @@ void BoidManager::toggleBoidsMode(bool force_gravity_on) {
|
||||
}
|
||||
|
||||
void BoidManager::update(float delta_time) {
|
||||
if (!boids_active_) return;
|
||||
if (!boids_active_) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& balls = scene_mgr_->getBallsMutable();
|
||||
|
||||
@@ -114,8 +118,8 @@ void BoidManager::update(float delta_time) {
|
||||
spatial_grid_.clear();
|
||||
for (auto& ball : balls) {
|
||||
SDL_FRect pos = ball->getPosition();
|
||||
float center_x = pos.x + pos.w / 2.0f;
|
||||
float center_y = pos.y + pos.h / 2.0f;
|
||||
float center_x = pos.x + (pos.w / 2.0f);
|
||||
float center_y = pos.y + (pos.h / 2.0f);
|
||||
spatial_grid_.insert(ball.get(), center_x, center_y);
|
||||
}
|
||||
|
||||
@@ -131,7 +135,8 @@ void BoidManager::update(float delta_time) {
|
||||
|
||||
// Actualizar posiciones con velocidades resultantes (time-based)
|
||||
for (auto& ball : balls) {
|
||||
float vx, vy;
|
||||
float vx;
|
||||
float vy;
|
||||
ball->getVelocity(vx, vy);
|
||||
|
||||
SDL_FRect pos = ball->getPosition();
|
||||
@@ -153,22 +158,24 @@ void BoidManager::applySeparation(Ball* boid, float delta_time) {
|
||||
int count = 0;
|
||||
|
||||
SDL_FRect pos = boid->getPosition();
|
||||
float center_x = pos.x + pos.w / 2.0f;
|
||||
float center_y = pos.y + pos.h / 2.0f;
|
||||
float center_x = pos.x + (pos.w / 2.0f);
|
||||
float center_y = pos.y + (pos.h / 2.0f);
|
||||
|
||||
// FASE 2: Usar spatial grid para buscar solo vecinos cercanos (O(1) en lugar de O(n))
|
||||
auto neighbors = spatial_grid_.queryRadius(center_x, center_y, separation_radius_);
|
||||
|
||||
for (Ball* other : neighbors) {
|
||||
if (other == boid) continue; // Ignorar a sí mismo
|
||||
if (other == boid) {
|
||||
continue; // Ignorar a sí mismo
|
||||
}
|
||||
|
||||
SDL_FRect other_pos = other->getPosition();
|
||||
float other_x = other_pos.x + other_pos.w / 2.0f;
|
||||
float other_y = other_pos.y + other_pos.h / 2.0f;
|
||||
float other_x = other_pos.x + (other_pos.w / 2.0f);
|
||||
float other_y = other_pos.y + (other_pos.h / 2.0f);
|
||||
|
||||
float dx = center_x - other_x;
|
||||
float dy = center_y - other_y;
|
||||
float distance = std::sqrt(dx * dx + dy * dy);
|
||||
float distance = std::sqrt((dx * dx) + (dy * dy));
|
||||
|
||||
if (distance > 0.0f && distance < separation_radius_) {
|
||||
// FASE 1.3: Separación más fuerte cuando más cerca (inversamente proporcional a distancia)
|
||||
@@ -186,7 +193,8 @@ void BoidManager::applySeparation(Ball* boid, float delta_time) {
|
||||
steer_y /= count;
|
||||
|
||||
// Aplicar fuerza de separación
|
||||
float vx, vy;
|
||||
float vx;
|
||||
float vy;
|
||||
boid->getVelocity(vx, vy);
|
||||
vx += steer_x * separation_weight_ * delta_time;
|
||||
vy += steer_y * separation_weight_ * delta_time;
|
||||
@@ -201,25 +209,28 @@ void BoidManager::applyAlignment(Ball* boid, float delta_time) {
|
||||
int count = 0;
|
||||
|
||||
SDL_FRect pos = boid->getPosition();
|
||||
float center_x = pos.x + pos.w / 2.0f;
|
||||
float center_y = pos.y + pos.h / 2.0f;
|
||||
float center_x = pos.x + (pos.w / 2.0f);
|
||||
float center_y = pos.y + (pos.h / 2.0f);
|
||||
|
||||
// FASE 2: Usar spatial grid para buscar solo vecinos cercanos (O(1) en lugar de O(n))
|
||||
auto neighbors = spatial_grid_.queryRadius(center_x, center_y, alignment_radius_);
|
||||
|
||||
for (Ball* other : neighbors) {
|
||||
if (other == boid) continue;
|
||||
if (other == boid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SDL_FRect other_pos = other->getPosition();
|
||||
float other_x = other_pos.x + other_pos.w / 2.0f;
|
||||
float other_y = other_pos.y + other_pos.h / 2.0f;
|
||||
float other_x = other_pos.x + (other_pos.w / 2.0f);
|
||||
float other_y = other_pos.y + (other_pos.h / 2.0f);
|
||||
|
||||
float dx = center_x - other_x;
|
||||
float dy = center_y - other_y;
|
||||
float distance = std::sqrt(dx * dx + dy * dy);
|
||||
float distance = std::sqrt((dx * dx) + (dy * dy));
|
||||
|
||||
if (distance < alignment_radius_) {
|
||||
float other_vx, other_vy;
|
||||
float other_vx;
|
||||
float other_vy;
|
||||
other->getVelocity(other_vx, other_vy);
|
||||
avg_vx += other_vx;
|
||||
avg_vy += other_vy;
|
||||
@@ -233,13 +244,14 @@ void BoidManager::applyAlignment(Ball* boid, float delta_time) {
|
||||
avg_vy /= count;
|
||||
|
||||
// Steering hacia la velocidad promedio
|
||||
float vx, vy;
|
||||
float vx;
|
||||
float vy;
|
||||
boid->getVelocity(vx, vy);
|
||||
float steer_x = (avg_vx - vx) * alignment_weight_ * delta_time;
|
||||
float steer_y = (avg_vy - vy) * alignment_weight_ * delta_time;
|
||||
|
||||
// Limitar fuerza máxima de steering
|
||||
float steer_mag = std::sqrt(steer_x * steer_x + steer_y * steer_y);
|
||||
float steer_mag = std::sqrt((steer_x * steer_x) + (steer_y * steer_y));
|
||||
if (steer_mag > max_force_) {
|
||||
steer_x = (steer_x / steer_mag) * max_force_;
|
||||
steer_y = (steer_y / steer_mag) * max_force_;
|
||||
@@ -258,22 +270,24 @@ void BoidManager::applyCohesion(Ball* boid, float delta_time) {
|
||||
int count = 0;
|
||||
|
||||
SDL_FRect pos = boid->getPosition();
|
||||
float center_x = pos.x + pos.w / 2.0f;
|
||||
float center_y = pos.y + pos.h / 2.0f;
|
||||
float center_x = pos.x + (pos.w / 2.0f);
|
||||
float center_y = pos.y + (pos.h / 2.0f);
|
||||
|
||||
// FASE 2: Usar spatial grid para buscar solo vecinos cercanos (O(1) en lugar de O(n))
|
||||
auto neighbors = spatial_grid_.queryRadius(center_x, center_y, cohesion_radius_);
|
||||
|
||||
for (Ball* other : neighbors) {
|
||||
if (other == boid) continue;
|
||||
if (other == boid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SDL_FRect other_pos = other->getPosition();
|
||||
float other_x = other_pos.x + other_pos.w / 2.0f;
|
||||
float other_y = other_pos.y + other_pos.h / 2.0f;
|
||||
float other_x = other_pos.x + (other_pos.w / 2.0f);
|
||||
float other_y = other_pos.y + (other_pos.h / 2.0f);
|
||||
|
||||
float dx = center_x - other_x;
|
||||
float dy = center_y - other_y;
|
||||
float distance = std::sqrt(dx * dx + dy * dy);
|
||||
float distance = std::sqrt((dx * dx) + (dy * dy));
|
||||
|
||||
if (distance < cohesion_radius_) {
|
||||
center_of_mass_x += other_x;
|
||||
@@ -290,7 +304,7 @@ void BoidManager::applyCohesion(Ball* boid, float delta_time) {
|
||||
// FASE 1.4: Normalizar dirección hacia el centro (CRÍTICO - antes no estaba normalizado!)
|
||||
float dx_to_center = center_of_mass_x - center_x;
|
||||
float dy_to_center = center_of_mass_y - center_y;
|
||||
float distance_to_center = std::sqrt(dx_to_center * dx_to_center + dy_to_center * dy_to_center);
|
||||
float distance_to_center = std::sqrt((dx_to_center * dx_to_center) + (dy_to_center * dy_to_center));
|
||||
|
||||
// Solo aplicar si hay distancia al centro (evitar división por cero)
|
||||
if (distance_to_center > 0.1f) {
|
||||
@@ -299,13 +313,14 @@ void BoidManager::applyCohesion(Ball* boid, float delta_time) {
|
||||
float steer_y = (dy_to_center / distance_to_center) * cohesion_weight_ * delta_time;
|
||||
|
||||
// Limitar fuerza máxima de steering
|
||||
float steer_mag = std::sqrt(steer_x * steer_x + steer_y * steer_y);
|
||||
float steer_mag = std::sqrt((steer_x * steer_x) + (steer_y * steer_y));
|
||||
if (steer_mag > max_force_) {
|
||||
steer_x = (steer_x / steer_mag) * max_force_;
|
||||
steer_y = (steer_y / steer_mag) * max_force_;
|
||||
}
|
||||
|
||||
float vx, vy;
|
||||
float vx;
|
||||
float vy;
|
||||
boid->getVelocity(vx, vy);
|
||||
vx += steer_x;
|
||||
vy += steer_y;
|
||||
@@ -314,12 +329,12 @@ void BoidManager::applyCohesion(Ball* boid, float delta_time) {
|
||||
}
|
||||
}
|
||||
|
||||
void BoidManager::applyBoundaries(Ball* boid) {
|
||||
void BoidManager::applyBoundaries(Ball* boid) const {
|
||||
// NUEVA IMPLEMENTACIÓN: Bordes como obstáculos (repulsión en lugar de wrapping)
|
||||
// Cuando un boid se acerca a un borde, se aplica una fuerza alejándolo
|
||||
SDL_FRect pos = boid->getPosition();
|
||||
float center_x = pos.x + pos.w / 2.0f;
|
||||
float center_y = pos.y + pos.h / 2.0f;
|
||||
float center_x = pos.x + (pos.w / 2.0f);
|
||||
float center_y = pos.y + (pos.h / 2.0f);
|
||||
|
||||
float steer_x = 0.0f;
|
||||
float steer_y = 0.0f;
|
||||
@@ -363,11 +378,12 @@ void BoidManager::applyBoundaries(Ball* boid) {
|
||||
|
||||
// Aplicar fuerza de repulsión si hay alguna
|
||||
if (steer_x != 0.0f || steer_y != 0.0f) {
|
||||
float vx, vy;
|
||||
float vx;
|
||||
float vy;
|
||||
boid->getVelocity(vx, vy);
|
||||
|
||||
// Normalizar fuerza de repulsión (para que todas las direcciones tengan la misma intensidad)
|
||||
float steer_mag = std::sqrt(steer_x * steer_x + steer_y * steer_y);
|
||||
float steer_mag = std::sqrt((steer_x * steer_x) + (steer_y * steer_y));
|
||||
if (steer_mag > 0.0f) {
|
||||
steer_x /= steer_mag;
|
||||
steer_y /= steer_mag;
|
||||
@@ -381,12 +397,13 @@ void BoidManager::applyBoundaries(Ball* boid) {
|
||||
}
|
||||
}
|
||||
|
||||
void BoidManager::limitSpeed(Ball* boid) {
|
||||
void BoidManager::limitSpeed(Ball* boid) const {
|
||||
// Limitar velocidad máxima del boid
|
||||
float vx, vy;
|
||||
float vx;
|
||||
float vy;
|
||||
boid->getVelocity(vx, vy);
|
||||
|
||||
float speed = std::sqrt(vx * vx + vy * vy);
|
||||
float speed = std::sqrt((vx * vx) + (vy * vy));
|
||||
|
||||
// Limitar velocidad máxima
|
||||
if (speed > max_speed_) {
|
||||
|
||||
@@ -46,8 +46,7 @@ class BoidManager {
|
||||
* @param screen_width Ancho de pantalla actual
|
||||
* @param screen_height Alto de pantalla actual
|
||||
*/
|
||||
void initialize(Engine* engine, SceneManager* scene_mgr, UIManager* ui_mgr,
|
||||
StateManager* state_mgr, int screen_width, int screen_height);
|
||||
void initialize(Engine* engine, SceneManager* scene_mgr, UIManager* ui_mgr, StateManager* state_mgr, int screen_width, int screen_height);
|
||||
|
||||
/**
|
||||
* @brief Actualiza el tamaño de pantalla (llamado en resize/fullscreen)
|
||||
@@ -105,22 +104,22 @@ class BoidManager {
|
||||
|
||||
// === Parámetros ajustables en runtime (inicializados con valores de defines.h) ===
|
||||
// Permite modificar comportamiento sin recompilar (para tweaking/debug visual)
|
||||
float separation_radius_; // Radio de separación (evitar colisiones)
|
||||
float alignment_radius_; // Radio de alineación (matching de velocidad)
|
||||
float cohesion_radius_; // Radio de cohesión (centro de masa)
|
||||
float separation_weight_; // Peso fuerza de separación (aceleración px/s²)
|
||||
float alignment_weight_; // Peso fuerza de alineación (steering proporcional)
|
||||
float cohesion_weight_; // Peso fuerza de cohesión (aceleración px/s²)
|
||||
float max_speed_; // Velocidad máxima (px/s)
|
||||
float min_speed_; // Velocidad mínima (px/s)
|
||||
float max_force_; // Fuerza máxima de steering (px/s)
|
||||
float boundary_margin_; // Margen para repulsión de bordes (px)
|
||||
float boundary_weight_; // Peso fuerza de repulsión de bordes (aceleración px/s²)
|
||||
float separation_radius_; // Radio de separación (evitar colisiones)
|
||||
float alignment_radius_; // Radio de alineación (matching de velocidad)
|
||||
float cohesion_radius_; // Radio de cohesión (centro de masa)
|
||||
float separation_weight_; // Peso fuerza de separación (aceleración px/s²)
|
||||
float alignment_weight_; // Peso fuerza de alineación (steering proporcional)
|
||||
float cohesion_weight_; // Peso fuerza de cohesión (aceleración px/s²)
|
||||
float max_speed_; // Velocidad máxima (px/s)
|
||||
float min_speed_; // Velocidad mínima (px/s)
|
||||
float max_force_; // Fuerza máxima de steering (px/s)
|
||||
float boundary_margin_; // Margen para repulsión de bordes (px)
|
||||
float boundary_weight_; // Peso fuerza de repulsión de bordes (aceleración px/s²)
|
||||
|
||||
// Métodos privados para las reglas de Reynolds
|
||||
void applySeparation(Ball* boid, float delta_time);
|
||||
void applyAlignment(Ball* boid, float delta_time);
|
||||
void applyCohesion(Ball* boid, float delta_time);
|
||||
void applyBoundaries(Ball* boid); // Repulsión de bordes (ya no wrapping)
|
||||
void limitSpeed(Ball* boid); // Limitar velocidad máxima
|
||||
void applyBoundaries(Ball* boid) const; // Repulsión de bordes (ya no wrapping)
|
||||
void limitSpeed(Ball* boid) const; // Limitar velocidad máxima
|
||||
};
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#include "ball.hpp" // for Ball
|
||||
|
||||
SpatialGrid::SpatialGrid(int world_width, int world_height, float cell_size)
|
||||
: world_width_(world_width)
|
||||
, world_height_(world_height)
|
||||
, cell_size_(cell_size) {
|
||||
: world_width_(world_width),
|
||||
world_height_(world_height),
|
||||
cell_size_(cell_size) {
|
||||
// Calcular número de celdas en cada dimensión
|
||||
grid_cols_ = static_cast<int>(std::ceil(world_width / cell_size));
|
||||
grid_rows_ = static_cast<int>(std::ceil(world_height / cell_size));
|
||||
@@ -21,7 +21,8 @@ void SpatialGrid::clear() {
|
||||
|
||||
void SpatialGrid::insert(Ball* ball, float x, float y) {
|
||||
// Obtener coordenadas de celda
|
||||
int cell_x, cell_y;
|
||||
int cell_x;
|
||||
int cell_y;
|
||||
getCellCoords(x, y, cell_x, cell_y);
|
||||
|
||||
// Generar hash key y añadir a la celda
|
||||
@@ -29,11 +30,14 @@ void SpatialGrid::insert(Ball* ball, float x, float y) {
|
||||
cells_[key].push_back(ball);
|
||||
}
|
||||
|
||||
std::vector<Ball*> SpatialGrid::queryRadius(float x, float y, float radius) {
|
||||
auto SpatialGrid::queryRadius(float x, float y, float radius) -> std::vector<Ball*> {
|
||||
std::vector<Ball*> results;
|
||||
|
||||
// Calcular rango de celdas a revisar (AABB del círculo de búsqueda)
|
||||
int min_cell_x, min_cell_y, max_cell_x, max_cell_y;
|
||||
int min_cell_x;
|
||||
int min_cell_y;
|
||||
int max_cell_x;
|
||||
int max_cell_y;
|
||||
getCellCoords(x - radius, y - radius, min_cell_x, min_cell_y);
|
||||
getCellCoords(x + radius, y + radius, max_cell_x, max_cell_y);
|
||||
|
||||
@@ -82,8 +86,8 @@ void SpatialGrid::getCellCoords(float x, float y, int& cell_x, int& cell_y) cons
|
||||
cell_y = static_cast<int>(std::floor(y / cell_size_));
|
||||
}
|
||||
|
||||
int SpatialGrid::getCellKey(int cell_x, int cell_y) const {
|
||||
auto SpatialGrid::getCellKey(int cell_x, int cell_y) const -> int {
|
||||
// Hash espacial 2D → 1D usando codificación por filas
|
||||
// Formula: key = y * ancho + x (similar a array 2D aplanado)
|
||||
return cell_y * grid_cols_ + cell_x;
|
||||
return (cell_y * grid_cols_) + cell_x;
|
||||
}
|
||||
|
||||
@@ -30,42 +30,42 @@ class Ball; // Forward declaration
|
||||
// ============================================================================
|
||||
|
||||
class SpatialGrid {
|
||||
public:
|
||||
// Constructor: especificar dimensiones del mundo y tamaño de celda
|
||||
SpatialGrid(int world_width, int world_height, float cell_size);
|
||||
public:
|
||||
// Constructor: especificar dimensiones del mundo y tamaño de celda
|
||||
SpatialGrid(int world_width, int world_height, float cell_size);
|
||||
|
||||
// Limpiar todas las celdas (llamar al inicio de cada frame)
|
||||
void clear();
|
||||
// Limpiar todas las celdas (llamar al inicio de cada frame)
|
||||
void clear();
|
||||
|
||||
// Insertar objeto en el grid según su posición (x, y)
|
||||
void insert(Ball* ball, float x, float y);
|
||||
// Insertar objeto en el grid según su posición (x, y)
|
||||
void insert(Ball* ball, float x, float y);
|
||||
|
||||
// Buscar todos los objetos dentro del radio especificado desde (x, y)
|
||||
// Devuelve vector de punteros a Ball (puede contener duplicados si ball está en múltiples celdas)
|
||||
std::vector<Ball*> queryRadius(float x, float y, float radius);
|
||||
// Buscar todos los objetos dentro del radio especificado desde (x, y)
|
||||
// Devuelve vector de punteros a Ball (puede contener duplicados si ball está en múltiples celdas)
|
||||
std::vector<Ball*> queryRadius(float x, float y, float radius);
|
||||
|
||||
// Actualizar dimensiones del mundo (útil para cambios de resolución F4)
|
||||
void updateWorldSize(int world_width, int world_height);
|
||||
// Actualizar dimensiones del mundo (útil para cambios de resolución F4)
|
||||
void updateWorldSize(int world_width, int world_height);
|
||||
|
||||
private:
|
||||
// Convertir coordenadas (x, y) a índice de celda (cell_x, cell_y)
|
||||
void getCellCoords(float x, float y, int& cell_x, int& cell_y) const;
|
||||
private:
|
||||
// Convertir coordenadas (x, y) a índice de celda (cell_x, cell_y)
|
||||
void getCellCoords(float x, float y, int& cell_x, int& cell_y) const;
|
||||
|
||||
// Convertir (cell_x, cell_y) a hash key único para el mapa
|
||||
int getCellKey(int cell_x, int cell_y) const;
|
||||
// Convertir (cell_x, cell_y) a hash key único para el mapa
|
||||
int getCellKey(int cell_x, int cell_y) const;
|
||||
|
||||
// Dimensiones del mundo (ancho/alto en píxeles)
|
||||
int world_width_;
|
||||
int world_height_;
|
||||
// Dimensiones del mundo (ancho/alto en píxeles)
|
||||
int world_width_;
|
||||
int world_height_;
|
||||
|
||||
// Tamaño de cada celda (en píxeles)
|
||||
float cell_size_;
|
||||
// Tamaño de cada celda (en píxeles)
|
||||
float cell_size_;
|
||||
|
||||
// Número de celdas en cada dimensión
|
||||
int grid_cols_;
|
||||
int grid_rows_;
|
||||
// Número de celdas en cada dimensión
|
||||
int grid_cols_;
|
||||
int grid_rows_;
|
||||
|
||||
// Estructura de datos: hash map de cell_key → vector de Ball*
|
||||
// Usamos unordered_map para O(1) lookup
|
||||
std::unordered_map<int, std::vector<Ball*>> cells_;
|
||||
// Estructura de datos: hash map de cell_key → vector de Ball*
|
||||
// Usamos unordered_map para O(1) lookup
|
||||
std::unordered_map<int, std::vector<Ball*>> cells_;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user