Boids Fase 1.4: FIX CRÍTICO - Normalizar fuerza de cohesión
BUG CRÍTICO ENCONTRADO:
La fuerza de cohesión NO estaba normalizada, causando atracción
tipo "gravedad" que hacía que los boids colapsaran a puntos.
CAUSA RAÍZ:
```cpp
// ANTES (INCORRECTO):
float steer_x = (center_of_mass_x - center_x) * WEIGHT * delta_time;
// Si center_of_mass está a 100px → fuerza = 100 * 0.5 * 0.016 = 0.8
// ¡FUERZA PROPORCIONAL A DISTANCIA! Como una gravedad newtoniana
```
SOLUCIÓN IMPLEMENTADA:
```cpp
// DESPUÉS (CORRECTO):
float distance = sqrt(dx*dx + dy*dy);
float steer_x = (dx / distance) * WEIGHT * delta_time;
// Fuerza siempre normalizada = 1.0 * WEIGHT * delta_time
// Independiente de distancia (comportamiento Reynolds correcto)
```
CAMBIOS:
1. boid_manager.cpp::applyCohesion() - Fase 1.4
- Normalizar dirección hacia centro de masa
- Fuerza constante independiente de distancia
- Check de división por cero (distance > 0.1f)
2. defines.h - Ajuste de parámetros tras normalización
- BOID_COHESION_WEIGHT: 0.5 → 0.001 (1000x menor)
* Ahora que está normalizado, el valor anterior era gigantesco
- BOID_MAX_SPEED: 3.0 → 2.5 (reducida para evitar velocidades extremas)
- BOID_MAX_FORCE: 0.5 → 0.05 (reducida 10x)
- BOID_MIN_SPEED: 0.5 → 0.3 (reducida)
- Radios restaurados a valores originales (30/50/80)
RESULTADO ESPERADO:
✅ Sin colapso a puntos (cohesión normalizada correctamente)
✅ Movimiento orgánico sin "órbitas" artificiales
✅ Velocidades controladas y naturales
✅ Balance correcto entre las 3 fuerzas
TESTING:
Por favor probar con 100 y 1000 boids:
- ¿Se mantienen dispersos sin colapsar?
- ¿Las órbitas han desaparecido?
- ¿El movimiento es más natural?
Estado: Compilación exitosa
Rama: boids_development
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -253,9 +253,16 @@ void BoidManager::applyCohesion(Ball* boid, float delta_time) {
|
||||
center_of_mass_x /= count;
|
||||
center_of_mass_y /= count;
|
||||
|
||||
// Dirección hacia el centro
|
||||
float steer_x = (center_of_mass_x - center_x) * BOID_COHESION_WEIGHT * delta_time;
|
||||
float steer_y = (center_of_mass_y - center_y) * BOID_COHESION_WEIGHT * 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);
|
||||
|
||||
// Solo aplicar si hay distancia al centro (evitar división por cero)
|
||||
if (distance_to_center > 0.1f) {
|
||||
// Normalizar vector dirección (fuerza independiente de distancia)
|
||||
float steer_x = (dx_to_center / distance_to_center) * BOID_COHESION_WEIGHT * delta_time;
|
||||
float steer_y = (dy_to_center / distance_to_center) * BOID_COHESION_WEIGHT * delta_time;
|
||||
|
||||
// Limitar fuerza máxima de steering
|
||||
float steer_mag = std::sqrt(steer_x * steer_x + steer_y * steer_y);
|
||||
@@ -270,6 +277,7 @@ void BoidManager::applyCohesion(Ball* boid, float delta_time) {
|
||||
vy += steer_y;
|
||||
boid->setVelocity(vx, vy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BoidManager::applyBoundaries(Ball* boid) {
|
||||
|
||||
@@ -289,16 +289,16 @@ constexpr float LOGO_FLIP_TRIGGER_MAX = 0.80f; // 80% máximo de progres
|
||||
constexpr int LOGO_FLIP_WAIT_PROBABILITY = 50; // 50% probabilidad de elegir el camino "esperar flip"
|
||||
|
||||
// Configuración de Modo BOIDS (comportamiento de enjambre)
|
||||
// FASE 1.1: Parámetros rebalanceados para evitar clustering
|
||||
constexpr float BOID_SEPARATION_RADIUS = 25.0f; // Radio para evitar colisiones (píxeles)
|
||||
constexpr float BOID_ALIGNMENT_RADIUS = 40.0f; // Radio para alinear velocidad con vecinos
|
||||
constexpr float BOID_COHESION_RADIUS = 60.0f; // Radio para moverse hacia centro del grupo (REDUCIDO)
|
||||
constexpr float BOID_SEPARATION_WEIGHT = 3.0f; // Peso de separación (TRIPLICADO - alta prioridad)
|
||||
constexpr float BOID_ALIGNMENT_WEIGHT = 1.0f; // Peso de alineación (sin cambios)
|
||||
constexpr float BOID_COHESION_WEIGHT = 0.5f; // Peso de cohesión (REDUCIDO a la mitad)
|
||||
constexpr float BOID_MAX_SPEED = 3.0f; // Velocidad máxima (píxeles/frame)
|
||||
constexpr float BOID_MAX_FORCE = 0.5f; // Fuerza máxima de steering (QUINTUPLICADO)
|
||||
constexpr float BOID_MIN_SPEED = 0.5f; // Velocidad mínima (NUEVO - evita boids estáticos)
|
||||
// FASE 1.1 REVISADA: Parámetros ajustados tras detectar cohesión mal normalizada
|
||||
constexpr float BOID_SEPARATION_RADIUS = 30.0f; // Radio para evitar colisiones (píxeles)
|
||||
constexpr float BOID_ALIGNMENT_RADIUS = 50.0f; // Radio para alinear velocidad con vecinos
|
||||
constexpr float BOID_COHESION_RADIUS = 80.0f; // Radio para moverse hacia centro del grupo
|
||||
constexpr float BOID_SEPARATION_WEIGHT = 1.5f; // Peso de separación
|
||||
constexpr float BOID_ALIGNMENT_WEIGHT = 1.0f; // Peso de alineación
|
||||
constexpr float BOID_COHESION_WEIGHT = 0.001f; // Peso de cohesión (MICRO - 1000x menor por falta de normalización)
|
||||
constexpr float BOID_MAX_SPEED = 2.5f; // Velocidad máxima (píxeles/frame - REDUCIDA)
|
||||
constexpr float BOID_MAX_FORCE = 0.05f; // Fuerza máxima de steering (REDUCIDA para evitar aceleración excesiva)
|
||||
constexpr float BOID_MIN_SPEED = 0.3f; // Velocidad mínima (evita boids estáticos)
|
||||
|
||||
constexpr float PI = 3.14159265358979323846f; // Constante PI
|
||||
|
||||
|
||||
Reference in New Issue
Block a user