feat(cosmobiologia): rectificador per-segundo + direcciones primarias reales
El rectificador deja la aproximación y pasa a la trigonometría exacta, con precisión de segundo — el "microajuste argentino". LA MATEMÁTICA. El rectificador ya NO usa el modelo simplificado (directed_longitude, rotación uniforme de RA + convergencia GR). Ahora usa `eternal_astrology::primary_direction::all_directions` — el método Placidus-mundano: semi-arcos diurnos/nocturnos bajo el polo de cada cuerpo, la trigonometría esférica de la escuela ascensional. No se reimplementó nada: la matemática, ya probada, vive en eternal; el engine sólo aporta la capa de optimización. - error_de_carta: por cada evento, la distancia en años a la dirección primaria que perfecciona más cerca; el error total es la suma. Es la función de coste del microajuste — el valle es la hora real. PRECISIÓN DE SEGUNDO. compute_natal_chart / build_eternal_inputs / natal_cache pasan a trabajar en SEGUNDOS (compose convierte ×60). El rectificador barre en dos pasadas: gruesa minuto a minuto sobre la ventana (el perfil que dibuja la curva), fina segundo a segundo en ±60 s alrededor del mejor minuto. - Rectificacion: mejor_offset_segundos; el perfil va en segundos. - UI: panel y curva muestran «±Xm Ys · error N.NNa». Las barras siguen siendo clicables (scrub a esa hora candidata). Tests verdes (engine 12, render 28). Limitación conocida: all_directions es sólo directo — converso necesita crecer en eternal (upstream). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -2064,24 +2064,28 @@ fn render_rectify_profile(
|
||||
let rango = (max_p - min_p).max(1e-3);
|
||||
let primero = r.perfil.first().map(|&(o, _)| o).unwrap_or(0);
|
||||
let ultimo = r.perfil.last().map(|&(o, _)| o).unwrap_or(0);
|
||||
// El perfil va en segundos a paso de minuto; el mejor offset es
|
||||
// fino (segundos). La barra resaltada es la del minuto más cercano.
|
||||
let mejor_barra = (r.mejor_offset_segundos as f64 / 60.0).round() as i64 * 60;
|
||||
|
||||
let mut bars = div().flex().flex_row().items_end().gap(px(2.0));
|
||||
for &(offset, puntaje) in &r.perfil {
|
||||
// Fitness: el mejor candidato (puntaje mínimo) → barra más alta.
|
||||
let fitness = ((max_p - puntaje) / rango).clamp(0.0, 1.0);
|
||||
let bar_h = (fitness * BAR_AREA_H).max(2.0);
|
||||
let es_mejor = offset == r.mejor_offset_minutos;
|
||||
let es_mejor = offset == mejor_barra;
|
||||
let color = if es_mejor {
|
||||
palette.angle_highlight
|
||||
} else {
|
||||
with_alpha(palette.angle_highlight, 0.25 + fitness * 0.45)
|
||||
};
|
||||
// Etiquetar sólo los hitos: el mejor, el 0 y los dos extremos.
|
||||
// El offset va en segundos; la etiqueta lo muestra en minutos.
|
||||
let label = if es_mejor || offset == 0 || offset == primero || offset == ultimo {
|
||||
if offset == 0 {
|
||||
"0".to_string()
|
||||
} else {
|
||||
format!("{offset:+}")
|
||||
format!("{:+}", offset / 60)
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
@@ -2113,17 +2117,23 @@ fn render_rectify_profile(
|
||||
)
|
||||
.on_click({
|
||||
// Un clic lleva la carta a esta hora candidata reusando
|
||||
// el scrub de tiempo del jog-dial (`TimeOffsetChanged`).
|
||||
// el scrub de tiempo del jog-dial (`TimeOffsetChanged`,
|
||||
// en minutos — el offset del perfil va en segundos).
|
||||
let entity = entity.clone();
|
||||
move |_: &gpui::ClickEvent, _w, cx: &mut gpui::App| {
|
||||
entity.update(cx, |_this, cx| {
|
||||
cx.emit(CanvasEvent::TimeOffsetChanged(offset));
|
||||
cx.emit(CanvasEvent::TimeOffsetChanged(offset / 60));
|
||||
});
|
||||
}
|
||||
});
|
||||
bars = bars.child(column);
|
||||
}
|
||||
|
||||
// La hora rectificada, fina: «±Xm Ys».
|
||||
let seg = r.mejor_offset_segundos;
|
||||
let signo = if seg < 0 { "-" } else { "+" };
|
||||
let abs = seg.abs();
|
||||
|
||||
div()
|
||||
.flex()
|
||||
.flex_col()
|
||||
@@ -2134,8 +2144,11 @@ fn render_rectify_profile(
|
||||
.text_size(px(10.0))
|
||||
.text_color(theme.fg_muted)
|
||||
.child(SharedString::from(format!(
|
||||
"Rectificación · hora {:+} min · puntaje {:.2} · el valle es la hora",
|
||||
r.mejor_offset_minutos, r.mejor_puntaje
|
||||
"Rectificación · hora {}{}m {:02}s · error {:.2}a · el valle es la hora",
|
||||
signo,
|
||||
abs / 60,
|
||||
abs % 60,
|
||||
r.mejor_puntaje
|
||||
))),
|
||||
)
|
||||
.child(bars)
|
||||
|
||||
Reference in New Issue
Block a user