From 2f3379180918fcdb8a5f0af6eb64732e8629a3eb Mon Sep 17 00:00:00 2001 From: Maximus Gorog Date: Wed, 8 Apr 2026 01:21:45 -0600 Subject: [PATCH] Fix render_braiding.rs: transitive for wire endpoints, direct for surface boundaries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wire endpoints and surface boundaries require different computation methods: - Wire endpoints: TRANSITIVE reachability to vertices A strand spans between vertices even if poset path has intermediate points. Most wires connect both v₀ and v₁; only wire 14 is a self-loop. - Surface boundary_wires: DIRECT covering relations only The immediate boundary of a surface is its direct predecessor/successor wires. Surfaces have 1-3 boundary wires (was 1-7 with transitive). Updated: - examples/render_braiding.rs: restored reachable_from for wire endpoints - fixtures/half_braid_geometry.json: correct wire endpoints + direct surface boundaries - web/zigzag-renderer.jsx: updated embedded geometry data Co-Authored-By: Claude Opus 4.5 --- examples/render_braiding.rs | 16 +++++++------- fixtures/half_braid_geometry.json | 36 +++++-------------------------- web/zigzag-renderer.jsx | 16 +++++++------- 3 files changed, 21 insertions(+), 47 deletions(-) diff --git a/examples/render_braiding.rs b/examples/render_braiding.rs index f0163c1..ea1c7ed 100644 --- a/examples/render_braiding.rs +++ b/examples/render_braiding.rs @@ -126,7 +126,7 @@ fn main() { predecessors[upper].push(lower); } - // Helper: find all reachable points + // Helper: find all transitively reachable points (for wire→vertex connections) let reachable_from = |start: usize, adj: &[Vec]| -> HashSet { let mut visited = HashSet::new(); let mut queue = VecDeque::new(); @@ -166,7 +166,8 @@ fn main() { for (i, &idx) in wire_indices.iter().enumerate() { let point = &pts.elements()[idx]; - // Find connected vertices + // Find connected vertices via TRANSITIVE reachability + // A wire (strand) spans between vertices even if the poset path has intermediate points let reachable_up = reachable_from(idx, &successors); let reachable_down = reachable_from(idx, &predecessors); @@ -213,12 +214,11 @@ fn main() { for (i, &idx) in surface_indices.iter().enumerate() { let point = &pts.elements()[idx]; - // Find connected wires (boundary) - let reachable_up = reachable_from(idx, &successors); - let reachable_down = reachable_from(idx, &predecessors); - - let mut boundary_wires: Vec = reachable_up - .union(&reachable_down) + // Find boundary wires via DIRECT covering relations only + // Surface (geom_dim=2) connects to wires (geom_dim=1) via single covers + let mut boundary_wires: Vec = successors[idx] + .iter() + .chain(predecessors[idx].iter()) .filter(|v| wire_set.contains(v)) .copied() .collect(); diff --git a/fixtures/half_braid_geometry.json b/fixtures/half_braid_geometry.json index 962f339..ef0b440 100644 --- a/fixtures/half_braid_geometry.json +++ b/fixtures/half_braid_geometry.json @@ -223,12 +223,7 @@ ], "boundary_wires": [ 5, - 8, - 14, - 15, - 18, - 19, - 20 + 18 ] }, { @@ -242,9 +237,7 @@ ], "boundary_wires": [ 5, - 15, - 19, - 20 + 19 ] }, { @@ -258,11 +251,7 @@ ], "boundary_wires": [ 8, - 14, - 15, - 18, - 19, - 20 + 18 ] }, { @@ -276,9 +265,7 @@ ], "boundary_wires": [ 8, - 15, - 19, - 20 + 19 ] }, { @@ -292,7 +279,6 @@ ], "boundary_wires": [ 14, - 15, 18 ] }, @@ -306,11 +292,8 @@ 2.0 ], "boundary_wires": [ - 5, - 8, 14, 15, - 18, 19 ] }, @@ -324,12 +307,7 @@ 2.0 ], "boundary_wires": [ - 5, - 8, - 14, 15, - 18, - 19, 20 ] }, @@ -343,11 +321,7 @@ 1.0 ], "boundary_wires": [ - 14, - 15, - 18, - 19, - 20 + 18 ] }, { diff --git a/web/zigzag-renderer.jsx b/web/zigzag-renderer.jsx index 5a24b67..c7fb2ae 100644 --- a/web/zigzag-renderer.jsx +++ b/web/zigzag-renderer.jsx @@ -29,14 +29,14 @@ const GEOMETRY_DATA = { "endpoints": [21, 22], "endpoint_coords": [[1.0, 1.0, 1.0], [3.0, 1.0, 1.0]] } ], "surfaces": [ - { "id": 3, "label": "surface_0", "point": "r0,s0,r0", "coords": [0.0, 1.0, 0.0], "boundary_wires": [5, 8, 14, 15, 18, 19, 20] }, - { "id": 4, "label": "surface_1", "point": "r1,s0,r0", "coords": [2.0, 1.0, 0.0], "boundary_wires": [5, 15, 19, 20] }, - { "id": 6, "label": "surface_2", "point": "r0,s1,r0", "coords": [0.0, 3.0, 0.0], "boundary_wires": [8, 14, 15, 18, 19, 20] }, - { "id": 7, "label": "surface_3", "point": "r1,s1,r0", "coords": [2.0, 3.0, 0.0], "boundary_wires": [8, 15, 19, 20] }, - { "id": 11, "label": "surface_4", "point": "r0,s0,r1", "coords": [0.0, 1.0, 2.0], "boundary_wires": [14, 15, 18] }, - { "id": 12, "label": "surface_5", "point": "r1,s0,r1", "coords": [2.0, 1.0, 2.0], "boundary_wires": [5, 8, 14, 15, 18, 19] }, - { "id": 13, "label": "surface_6", "point": "r2,s0,r1", "coords": [4.0, 1.0, 2.0], "boundary_wires": [5, 8, 14, 15, 18, 19, 20] }, - { "id": 16, "label": "surface_7", "point": "r0,r0,s0", "coords": [0.0, 0.0, 1.0], "boundary_wires": [14, 15, 18, 19, 20] }, + { "id": 3, "label": "surface_0", "point": "r0,s0,r0", "coords": [0.0, 1.0, 0.0], "boundary_wires": [5, 18] }, + { "id": 4, "label": "surface_1", "point": "r1,s0,r0", "coords": [2.0, 1.0, 0.0], "boundary_wires": [5, 19] }, + { "id": 6, "label": "surface_2", "point": "r0,s1,r0", "coords": [0.0, 3.0, 0.0], "boundary_wires": [8, 18] }, + { "id": 7, "label": "surface_3", "point": "r1,s1,r0", "coords": [2.0, 3.0, 0.0], "boundary_wires": [8, 19] }, + { "id": 11, "label": "surface_4", "point": "r0,s0,r1", "coords": [0.0, 1.0, 2.0], "boundary_wires": [14, 18] }, + { "id": 12, "label": "surface_5", "point": "r1,s0,r1", "coords": [2.0, 1.0, 2.0], "boundary_wires": [14, 15, 19] }, + { "id": 13, "label": "surface_6", "point": "r2,s0,r1", "coords": [4.0, 1.0, 2.0], "boundary_wires": [15, 20] }, + { "id": 16, "label": "surface_7", "point": "r0,r0,s0", "coords": [0.0, 0.0, 1.0], "boundary_wires": [18] }, { "id": 17, "label": "surface_8", "point": "r0,r1,s0", "coords": [0.0, 2.0, 1.0], "boundary_wires": [18] } ], "volumes": [