From a7214e049871616761a34cdc109bf462da4eac27 Mon Sep 17 00:00:00 2001 From: sergio Date: Mon, 18 May 2026 18:25:07 +0000 Subject: [PATCH] =?UTF-8?q?refactor(tahuantinsuyu):=20aros=20a/b/c/d/e=20c?= =?UTF-8?q?an=C3=B3nicos=20+=20un=20solo=20anillo=20por=20bloque?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reorganización de los radios siguiendo nomenclatura clara del usuario (de afuera hacia adentro): Aro A (1.00·r) externo zodiaco Zona AB signos ♈♉♊… (sign dial) Aro B (0.92·r) interno zodiaco / externo bloque ascensional Zona BC casas topo (cusps b→c) + planetas topo + coords Aro C (0.78·r) separador ascensional / casas geo Zona CD casas geo (cusps c→d) + sus coords Aro D (0.62·r) externo planetas natales (junto a D) planetas natales + coords Aro E (0.49·r) anclaje invisible de líneas de aspecto Overlays opcionales (transits, midpoints, progression, solar arc, composite) ahora viven todos INTERIORES al aro E — solo se pintan cuando su módulo está activo, así no compiten con el layout base. Cambios concretos en Radii: - Doc `Radii` reescrito con la nomenclatura a/b/c/d/e arriba. - Eliminado `bodies_inner` (la idea del "carril doble" confundía con el sistema de casas; ahora hay un único anillo por bloque). - Coord labels uniformes — `label_r = ring - disk_size * 0.7` (hacia adentro) tanto para natal como para topocéntrico, ya que cada bloque tiene su propia zona radial bien definida. - Coord pills de cusps de casa ahora se posan dentro de su propia zona (`r_in + (r_out - r_in) * 0.18`) — no se salen del bloque. - Stroke 3D del bloque de planetas natales se mueve a `houses_inner` (= aro D), que es el verdadero borde visible del cinturón. Si el usuario quiere un anillo adicional para algo en particular (p. ej. transits clásico afuera del zodiaco), se agrega cuando ese módulo se active. Co-Authored-By: Claude Opus 4.7 --- .../tahuantinsuyu-canvas/src/lib.rs | 194 ++++++++---------- 1 file changed, 89 insertions(+), 105 deletions(-) diff --git a/crates/modules/tahuantinsuyu/tahuantinsuyu-canvas/src/lib.rs b/crates/modules/tahuantinsuyu/tahuantinsuyu-canvas/src/lib.rs index e61d532..5bf314f 100644 --- a/crates/modules/tahuantinsuyu/tahuantinsuyu-canvas/src/lib.rs +++ b/crates/modules/tahuantinsuyu/tahuantinsuyu-canvas/src/lib.rs @@ -1067,13 +1067,25 @@ fn render_wheel( } // House numbers + (opcional) coord del cusp. + // + // El layer `natal` usa Zona CD (entre aros C y D); `topocentric` + // usa Zona BC (entre aros B y C). Los house numbers se posan al + // centro de la zona; las coord pills se posan adyacentes al aro + // interior de la propia zona, así no se sale del bloque. if visible.get(&LayerKind::Houses).copied().unwrap_or(true) { - let house_label_r = (radii.houses_outer + radii.houses_inner) / 2.0; let house_label_color = house_ring_color(palette); for layer in &render.layers { if matches!(layer.kind, LayerKind::Houses) { + let is_topo = layer.module_id == "topocentric"; + let (r_out, r_in) = if is_topo { + (radii.topo_houses_outer, radii.topo_houses_inner) + } else { + (radii.houses_outer, radii.houses_inner) + }; + let label_r = (r_out + r_in) / 2.0; + let coord_r = r_in + (r_out - r_in) * 0.18; for g in &layer.glyphs { - let (x, y) = polar_to_screen(g.deg, asc, rot_offset, house_label_r); + let (x, y) = polar_to_screen(g.deg, asc, rot_offset, label_r); if let Some(h) = g.house { wheel = wheel.child(centered_glyph( cx_center + x, @@ -1083,14 +1095,10 @@ fn render_wheel( format!("{}", h).into(), house_label_color, )); - // Coord del cusp justo dentro del anillo de - // casas — los grados se imprimen en una pill - // pequeña pegada al radio del cusp. if show_coords { let coord = format_coord_compact(g.deg); - let label_r = radii.houses_inner - 8.0 * s; let (lx, ly) = - polar_to_screen(g.deg, asc, rot_offset, label_r); + polar_to_screen(g.deg, asc, rot_offset, coord_r); wheel = wheel.child(coord_label( cx_center + lx, cy_center + ly, @@ -1167,23 +1175,14 @@ fn render_wheel( with_alpha(color, 0.85), )); - // Coord label: grado dentro del signo + glyph del - // signo, pintado afuera del disco del planeta - // (radialmente). Se pinta para el natal (afuera) - // y para el topocéntrico (más afuera aún, hacia - // el sign dial) — los dos sistemas conviven con - // sus coords. Otros overlays (progression, solar - // arc) usan badges en el footer. + // Coord label en pill — junto al planeta, dentro + // de su propia zona radial. Topo en zona BC + // (label hacia C, lado interior); natal en + // zona cerca de D (label hacia E, lado interior + // del cinturón natal — del lado de los aspectos). if show_coords && (is_natal || is_topo) { let coord = format_coord_compact(g.deg); - // Topo: label hacia ADENTRO (entre planeta y - // casas P-P arriba); natal: label hacia - // AFUERA (entre planeta y casas Placidus). - let label_r = if is_topo { - ring - disk_size * 0.7 - } else { - ring + disk_size * 0.7 - }; + let label_r = ring - disk_size * 0.7; let (lx, ly) = polar_to_screen(g.deg, asc, rot_offset, label_r); wheel = wheel.child(coord_label( cx_center + lx, @@ -1615,88 +1614,82 @@ fn format_offset(minutes: i64) -> String { // Painting // ===================================================================== +/// Geometría radial canónica de la rueda. Aros nombrados según +/// convención del usuario, de afuera hacia adentro: +/// +/// * **Aro A** (`sign_outer`) — externo del zodiaco. +/// * **Zona AB** — sign dial: glyphs de signos zodiacales. +/// * **Aro B** (`sign_inner` = `topo_houses_outer`) — interno del +/// zodiaco / externo del bloque ascensional. +/// * **Zona BC** — casas topocéntricas (cusps b→c) + planetas +/// topocéntricos, ambos con sus coordenadas. +/// * **Aro C** (`topo_houses_inner` = `houses_outer`) — separador +/// ascensional / casas geo. +/// * **Zona CD** — casas geocéntricas (cusps c→d) + sus coordenadas. +/// * **Aro D** (`houses_inner`) — externo de los planetas natales. +/// Junto a D, hacia adentro, se posan los planetas natales y sus +/// coordenadas. +/// * **Aro E** (`aspects`) — el más interno. Desde aquí nacen las +/// líneas de aspecto / relaciones / overlays opcionales. +/// +/// Los overlays adicionales (transits, midpoints, progression, solar +/// arc, composite) viven INTERIORES al aro E — solo se pintan +/// cuando el módulo correspondiente está activo, así no compiten +/// con el layout base. #[derive(Clone, Copy)] struct Radii { - // Layout outer→inner. La capa **ascensional** (sistema topocéntrico - // Polich-Page) va pegada al sign dial — su lógica nace del eje - // ASC/MC y de la ascensión recta del observador, conceptualmente - // hermana del zodiaco. La capa **geocéntrica** clásica - // (casas Placidus + planetas tropicales sin paralaje) vive más - // adentro, alrededor del cinturón de planetas natales. - sign_outer: f32, - sign_inner: f32, - /// Anillo exterior de las casas Polich-Page (topocéntricas), pegado - /// al sign dial. Los cusps llegan hasta el `sign_inner`. - topo_houses_outer: f32, - topo_houses_inner: f32, - /// Carril de planetas topocéntricos — apenas dentro del anillo - /// de casas P-P. Lleva sus propios coord labels. - topocentric: f32, - /// Anillo de glifos de tránsito (cuando el overlay está activo). + sign_outer: f32, // Aro A + sign_inner: f32, // Aro B + topo_houses_outer: f32, // = Aro B + topocentric: f32, // Zona BC: planetas topo + topo_houses_inner: f32, // Aro C + houses_outer: f32, // = Aro C + houses_inner: f32, // Aro D + bodies: f32, // Zona D-E: planetas natales (junto a D) + pd_direct: f32, // GR (cuando activo): exterior al cinturón natal + pd_converse: f32, // GR (cuando activo): interior al cinturón natal + aspects: f32, // Aro E (invisible, ancla de líneas) + // Overlays adicionales — todos interiores a E. transits: f32, - /// Casas geocéntricas (Placidus default) — más adentro que las - /// topocéntricas, claramente diferenciables. - houses_outer: f32, - houses_inner: f32, - /// Anillo de midpoints — entre cuerpos geocéntricos y `houses_inner`. midpoints: f32, - /// Anillo principal de cuerpos natales geocéntricos. - bodies: f32, - /// Borde interior del cinturón de planetas geocéntricos. - bodies_inner: f32, - /// Direcciones Primarias DIRECTAS (Sistema GR): ring exterior del - /// "abrazo" GR — justo afuera del cinturón natal. - pd_direct: f32, - /// Direcciones Primarias CONVERSAS (Sistema GR): ring interior — - /// el cinturón natal queda entre `pd_direct` (afuera) y - /// `pd_converse` (dentro), formando el dual-ring de rectificación. - pd_converse: f32, - /// Anillo interno con cuerpos progresados (overlay opcional). progression: f32, - /// Anillo más interno con cuerpos dirigidos por Solar Arc. solar_arc: f32, - /// Anillo de carta compuesta (midpoint Davison) con un partner. composite: f32, - /// Círculo donde anclan las líneas de aspecto entre cuerpos - /// natales. Justo dentro del cinturón de planetas. - aspects: f32, } impl Radii { fn from_outer(r: f32) -> Self { Self { + // Aro A — externo zodiaco. sign_outer: r, - sign_inner: r * 0.88, - // Ascensional (Polich-Page): pegado al sign dial. - topo_houses_outer: r * 0.875, - topo_houses_inner: r * 0.79, - // Carril topocéntrico de planetas: justo dentro de las - // casas P-P. Lleva sus coord labels al borde interior. - topocentric: r * 0.755, - // Tránsitos: ring intermedio entre las dos coronas (topo y - // geo), apenas debajo del topocéntrico. - transits: r * 0.71, - // Capa geocéntrica clásica más adentro — claramente - // separada del bloque ascensional. - houses_outer: r * 0.66, - houses_inner: r * 0.54, - midpoints: r * 0.50, - bodies: r * 0.47, - bodies_inner: r * 0.44, - // Dual-ring GR — abraza el cinturón natal por afuera y por - // adentro. Para Saturno los dos rings caen casi en la misma - // posición angular (poca rotación diurna afecta su lon en - // años humanos); para luminarias los rings divergen - // visiblemente y leen "directa rumbo a este grado, conversa - // hacia este otro". - pd_direct: r * 0.495, - pd_converse: r * 0.425, - // aspects justo bajo el carril natal — las líneas entran - // a este radio sin pintar el círculo (sería ruido extra). - aspects: r * 0.41, - progression: r * 0.36, - solar_arc: r * 0.30, - composite: r * 0.24, + // Aro B — interno zodiaco / externo bloque ascensional. + sign_inner: r * 0.92, + topo_houses_outer: r * 0.92, + // Zona BC: planetas topocéntricos centrados. + topocentric: r * 0.85, + // Aro C — separador ascensional / casas geo. + topo_houses_inner: r * 0.78, + houses_outer: r * 0.78, + // Aro D — externo planetas natales. + houses_inner: r * 0.62, + // Planetas natales justo dentro de D. + bodies: r * 0.57, + // GR dual-ring (cuando se activa): abraza el cinturón + // natal por afuera (`pd_direct`) y por adentro + // (`pd_converse`). Si GR está OFF, ninguno de los dos se + // pinta — no compite con el layout base. + pd_direct: r * 0.545, + pd_converse: r * 0.515, + // Aro E — anclaje invisible de las líneas de aspecto. + aspects: r * 0.49, + // Overlays adicionales — todos INTERIORES al aro E. Se + // pintan solo cuando el módulo correspondiente está + // activo, así no compiten con el layout base. + transits: r * 0.43, + midpoints: r * 0.39, + progression: r * 0.33, + solar_arc: r * 0.27, + composite: r * 0.21, } } @@ -1917,22 +1910,13 @@ fn paint_wheel( } } - // 2.5. Carril de planetas. `bodies` + `bodies_inner` muy juntos - // delimitan la franja estrecha donde viven los glyphs natales. - // El círculo de aspectos NO se pinta — `radii.aspects` solo - // existe como punto donde se anclan las líneas; un stroke ahí - // sería un anillo extra que confunde sin aportar. + // Aro D — único anillo visible del bloque de planetas natales + // (la idea del "carril doble" se descartó: confundía con el + // sistema de casas). El aro E (`radii.aspects`) no se pinta por + // diseño; solo es ancla invisible de las líneas. if show(LayerKind::Bodies) { let belt_color = with_alpha(palette.dial_ring, 0.55); - stroke_circle_3d(window, cx, cy, radii.bodies, 0.9, belt_color, theme); - stroke_circle( - window, - cx, - cy, - radii.bodies_inner, - 0.6, - with_alpha(palette.dial_ring, 0.35), - ); + stroke_circle_3d(window, cx, cy, radii.houses_inner, 0.9, belt_color, theme); // GR dual-ring: si las capas de direcciones primarias están // presentes, marcar sus anillos para que el visual lea como // "abrazo" del cinturón natal. La directa va punteada,