feat(cosmobiologia): espectro de fuerza armónica — histograma clicable

Completa la feature de armónicos: además de la carta armónica, ahora
hay un espectro que guía qué armónico mirar.

- cosmobiologia-render: harmonic_spectrum computa la fuerza de cada
  armónica 1-32 (suma de cercanía a conjunción exacta de los pares de
  cuerpos en esa armónica). apply_harmonic lo puebla + expone el
  armónico activo. Campos RenderModel.harmonic / .harmonic_spectrum.
  2 tests nuevos (el pico cae en la armónica resonante).
- cosmobiologia-canvas: render_harmonic_spectrum pinta el histograma
  en el footer; cada barra es clicable y emite HarmonicSelected — un
  clic salta a esa armónica. La barra activa va resaltada.
- shell: select_harmonic fija el slider del módulo natal y recompone.
- modules: el slider de armónico pasa de 1-20 a 1-32 (rango del
  espectro).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-22 13:57:54 +00:00
parent 968255f4cd
commit 54de7849c5
7 changed files with 208 additions and 2 deletions
@@ -92,6 +92,19 @@ pub struct RenderModel {
/// y resalta los `event = true` (convergencias directo+converso).
#[serde(default)]
pub gr_triggers: Vec<GrTrigger>,
/// Orden de la carta armónica activa. `1` = carta natal pura.
#[serde(default = "default_harmonic")]
pub harmonic: u32,
/// Espectro de fuerza armónica: índice `i` = fuerza de la armónica
/// `i + 1`. Vacío salvo en modo armónico (`harmonic > 1`). La UI
/// lo pinta como histograma para guiar qué armónico mirar.
#[serde(default)]
pub harmonic_spectrum: Vec<f32>,
}
/// Default serde del campo `harmonic`: 1 (carta natal sin transformar).
fn default_harmonic() -> u32 {
1
}
/// Etiqueta legible de un overlay para el footer del canvas. La engine