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,22 +253,30 @@ 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);
|
||||
|
||||
// Limitar fuerza máxima de steering
|
||||
float steer_mag = std::sqrt(steer_x * steer_x + steer_y * steer_y);
|
||||
if (steer_mag > BOID_MAX_FORCE) {
|
||||
steer_x = (steer_x / steer_mag) * BOID_MAX_FORCE;
|
||||
steer_y = (steer_y / steer_mag) * BOID_MAX_FORCE;
|
||||
// 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);
|
||||
if (steer_mag > BOID_MAX_FORCE) {
|
||||
steer_x = (steer_x / steer_mag) * BOID_MAX_FORCE;
|
||||
steer_y = (steer_y / steer_mag) * BOID_MAX_FORCE;
|
||||
}
|
||||
|
||||
float vx, vy;
|
||||
boid->getVelocity(vx, vy);
|
||||
vx += steer_x;
|
||||
vy += steer_y;
|
||||
boid->setVelocity(vx, vy);
|
||||
}
|
||||
|
||||
float vx, vy;
|
||||
boid->getVelocity(vx, vy);
|
||||
vx += steer_x;
|
||||
vy += steer_y;
|
||||
boid->setVelocity(vx, vy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user