Reemplazar Wave Grid por Lissajous Curve 3D

Cambiar figura "Wave Grid" (malla ondeante) por curva de Lissajous 3D,
con ecuaciones paramétricas más hipnóticas y resultónas visualmente.

## Cambios Principales

**Archivos renombrados:**
- `wave_grid_shape.h/cpp` → `lissajous_shape.h/cpp`
- Clase `WaveGridShape` → `LissajousShape`

**Ecuaciones implementadas:**
- x(t) = A * sin(3t + φx)  - Frecuencia 3 en X
- y(t) = A * sin(2t)       - Frecuencia 2 en Y
- z(t) = A * sin(t + φz)   - Frecuencia 1 en Z
- Ratio 3:2:1 produce patrón de "trenza elegante"

**Animación:**
- Rotación global dual (ejes X/Y)
- Animación de fase continua (morphing)
- Más dinámica y orgánica que Wave Grid

**defines.h:**
- `WAVE_GRID_*` → `LISSAJOUS_*` constantes
- `ShapeType::WAVE_GRID` → `ShapeType::LISSAJOUS`

**engine.cpp:**
- Actualizado include y instanciación
- Arrays de figuras DEMO actualizados
- Tecla W ahora activa Lissajous

## Resultado

Curva 3D paramétrica hipnótica con patrón entrelazado,
rotación continua y morphing de fase. Más espectacular
que el grid ondeante anterior. 🌀

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-07 12:31:38 +02:00
parent c55d6de687
commit 6cb3c2eef9
8 changed files with 233 additions and 232 deletions

View File

@@ -1,7 +1,8 @@
#pragma once
#include <SDL3/SDL_stdinc.h> // for Uint64
#include <vector> // for std::vector in DynamicThemeKeyframe/DynamicTheme
#include <vector> // for std::vector in DynamicThemeKeyframe/DynamicTheme
// Configuración de ventana y pantalla
constexpr char WINDOW_CAPTION[] = "ViBe3 Physics (JailDesigner 2025)";
@@ -100,7 +101,7 @@ enum class ShapeType {
CUBE, // Cubo rotante
HELIX, // Espiral 3D
TORUS, // Toroide/donut
WAVE_GRID, // Malla ondeante
LISSAJOUS, // Malla ondeante
CYLINDER, // Cilindro rotante
ICOSAHEDRON, // Icosaedro D20
ATOM, // Átomo con órbitas
@@ -149,12 +150,14 @@ constexpr float HELIX_NUM_TURNS = 3.0f; // Número de vueltas completas
constexpr float HELIX_ROTATION_SPEED_Y = 1.2f; // Velocidad rotación eje Y (rad/s)
constexpr float HELIX_PHASE_SPEED = 0.5f; // Velocidad de animación vertical (rad/s)
// Configuración de Wave Grid (malla ondeante 3D)
constexpr float WAVE_GRID_SIZE_FACTOR = 0.35f; // Tamaño del grid (proporción de altura)
constexpr float WAVE_GRID_AMPLITUDE = 0.15f; // Amplitud de las ondas (proporción de altura)
constexpr float WAVE_GRID_FREQUENCY = 3.0f; // Frecuencia de ondas (ciclos por grid)
constexpr float WAVE_GRID_PHASE_SPEED = 2.0f; // Velocidad de animación de ondas (rad/s)
constexpr float WAVE_GRID_ROTATION_SPEED_Y = 0.4f; // Velocidad rotación eje Y (rad/s)
// Configuración de Lissajous Curve 3D (curva paramétrica)
constexpr float LISSAJOUS_SIZE_FACTOR = 0.35f; // Amplitud de la curva (proporción de altura)
constexpr float LISSAJOUS_FREQ_X = 3.0f; // Frecuencia en eje X (ratio 3:2:1)
constexpr float LISSAJOUS_FREQ_Y = 2.0f; // Frecuencia en eje Y
constexpr float LISSAJOUS_FREQ_Z = 1.0f; // Frecuencia en eje Z
constexpr float LISSAJOUS_PHASE_SPEED = 1.0f; // Velocidad de animación de fase (rad/s)
constexpr float LISSAJOUS_ROTATION_SPEED_X = 0.4f; // Velocidad rotación global X (rad/s)
constexpr float LISSAJOUS_ROTATION_SPEED_Y = 0.6f; // Velocidad rotación global Y (rad/s)
// Configuración de Torus (toroide/donut 3D)
constexpr float TORUS_MAJOR_RADIUS_FACTOR = 0.25f; // Radio mayor R (centro torus a centro tubo)
@@ -187,12 +190,12 @@ constexpr float PNG_EXTRUSION_DEPTH_FACTOR = 0.12f; // Profundidad de extrusió
constexpr int PNG_NUM_EXTRUSION_LAYERS = 15; // Capas de extrusión (más capas = más pegajosidad)
constexpr bool PNG_USE_EDGES_ONLY = false; // true = solo bordes, false = relleno completo
// Rotación "legible" (texto de frente con volteretas ocasionales)
constexpr float PNG_IDLE_TIME_MIN = 0.5f; // Tiempo mínimo de frente (segundos) - modo MANUAL
constexpr float PNG_IDLE_TIME_MAX = 2.0f; // Tiempo máximo de frente (segundos) - modo MANUAL
constexpr float PNG_IDLE_TIME_MIN = 0.5f; // Tiempo mínimo de frente (segundos) - modo MANUAL
constexpr float PNG_IDLE_TIME_MAX = 2.0f; // Tiempo máximo de frente (segundos) - modo MANUAL
constexpr float PNG_IDLE_TIME_MIN_LOGO = 3.0f; // Tiempo mínimo de frente en LOGO MODE
constexpr float PNG_IDLE_TIME_MAX_LOGO = 5.0f; // Tiempo máximo de frente en LOGO MODE
constexpr float PNG_FLIP_SPEED = 3.0f; // Velocidad voltereta (rad/s)
constexpr float PNG_FLIP_DURATION = 1.5f; // Duración voltereta (segundos)
constexpr float PNG_FLIP_SPEED = 3.0f; // Velocidad voltereta (rad/s)
constexpr float PNG_FLIP_DURATION = 1.5f; // Duración voltereta (segundos)
// Control manual de escala de figuras 3D (Numpad +/-)
constexpr float SHAPE_SCALE_MIN = 0.3f; // Escala mínima (30%)
@@ -231,21 +234,21 @@ constexpr int DEMO_LITE_WEIGHT_IMPULSE = 10; // Aplicar impulso (10%)
// TOTAL: 100
// Configuración de Modo LOGO (easter egg - "marca de agua")
constexpr int LOGO_MODE_MIN_BALLS = 500; // Mínimo de pelotas para activar modo logo
constexpr float LOGO_MODE_SHAPE_SCALE = 1.2f; // Escala de figura en modo logo (120%)
constexpr float LOGO_ACTION_INTERVAL_MIN = 3.0f; // Tiempo mínimo entre alternancia SHAPE/PHYSICS (escalado con resolución)
constexpr float LOGO_ACTION_INTERVAL_MAX = 5.0f; // Tiempo máximo entre alternancia SHAPE/PHYSICS (escalado con resolución)
constexpr int LOGO_WEIGHT_TOGGLE_PHYSICS = 100; // Único peso: alternar SHAPE ↔ PHYSICS (100%)
constexpr int LOGO_MODE_MIN_BALLS = 500; // Mínimo de pelotas para activar modo logo
constexpr float LOGO_MODE_SHAPE_SCALE = 1.2f; // Escala de figura en modo logo (120%)
constexpr float LOGO_ACTION_INTERVAL_MIN = 3.0f; // Tiempo mínimo entre alternancia SHAPE/PHYSICS (escalado con resolución)
constexpr float LOGO_ACTION_INTERVAL_MAX = 5.0f; // Tiempo máximo entre alternancia SHAPE/PHYSICS (escalado con resolución)
constexpr int LOGO_WEIGHT_TOGGLE_PHYSICS = 100; // Único peso: alternar SHAPE ↔ PHYSICS (100%)
// Sistema de convergencia para LOGO MODE (evita interrupciones prematuras en resoluciones altas)
constexpr float LOGO_CONVERGENCE_MIN = 0.75f; // 75% mínimo (permite algo de movimiento al disparar)
constexpr float LOGO_CONVERGENCE_MAX = 1.00f; // 100% máximo (completamente formado)
constexpr float LOGO_CONVERGENCE_DISTANCE = 20.0f; // Distancia (px) para considerar pelota "convergida" (más permisivo que SHAPE_NEAR)
constexpr float LOGO_CONVERGENCE_MIN = 0.75f; // 75% mínimo (permite algo de movimiento al disparar)
constexpr float LOGO_CONVERGENCE_MAX = 1.00f; // 100% máximo (completamente formado)
constexpr float LOGO_CONVERGENCE_DISTANCE = 20.0f; // Distancia (px) para considerar pelota "convergida" (más permisivo que SHAPE_NEAR)
// Probabilidad de salto a Logo Mode desde DEMO/DEMO_LITE (%)
// Relación DEMO:LOGO = 6:1 (pasa 6x más tiempo en DEMO que en LOGO)
constexpr int LOGO_JUMP_PROBABILITY_FROM_DEMO = 5; // 5% probabilidad en DEMO normal (más raro)
constexpr int LOGO_JUMP_PROBABILITY_FROM_DEMO_LITE = 3; // 3% probabilidad en DEMO LITE (aún más raro)
constexpr int LOGO_JUMP_PROBABILITY_FROM_DEMO = 5; // 5% probabilidad en DEMO normal (más raro)
constexpr int LOGO_JUMP_PROBABILITY_FROM_DEMO_LITE = 3; // 3% probabilidad en DEMO LITE (aún más raro)
constexpr float PI = 3.14159265358979323846f; // Constante PI
@@ -254,11 +257,11 @@ constexpr float PI = 3.14159265358979323846f; // Constante PI
#ifdef _WIN32
#include <windows.h>
#elif defined(__APPLE__)
#include <limits.h>
#include <mach-o/dyld.h>
#include <limits.h>
#else
#include <unistd.h>
#include <limits.h>
#include <unistd.h>
#endif
inline std::string getExecutableDirectory() {