From bbc1f38dc9b15af744439fdd31973c81c99cb5bc Mon Sep 17 00:00:00 2001 From: Frank Loesche Date: Fri, 23 Jan 2026 00:19:45 -0500 Subject: [PATCH 1/2] remove G5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit G5 never worked. Even if it did, I believe the panels had a different number of LEDs… --- CLAUDE.md | 7 +- README.md | 4 +- arena_3d_viewer.html | 15 +-- arena_editor.html | 10 +- js/arena-calculations.js | 259 +++++++++++++++++++-------------------- 5 files changed, 138 insertions(+), 157 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 8d440bd..853be51 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -42,13 +42,12 @@ Standard panel generations: - G3: 32mm width, 8x8 pixels (circle LEDs) - G4: 40.45mm width, 16x16 pixels (circle LEDs) - G4.1: 40mm width, 16x16 pixels (rotated rectangle LEDs) -- G5: 40mm width, 20x20 pixels (rotated rectangle LEDs) - G6: 45.4mm width, 20x20 pixels (rotated rectangle LEDs) Arena radius formula: `cRadius = panelWidth / (tan(alpha/2)) / 2` where `alpha = 2*PI/numPanels` ### LED Specifications -- G4.1, G5, G6 use 0604 LED package: 0.6mm × 0.4mm = 1.5:1 aspect ratio +- G4.1, G6 use 0604 LED package: 0.6mm × 0.4mm = 1.5:1 aspect ratio - LEDs are rectangles rotated 45° on the panel (not diamonds) - G3, G4 use circular LED visualization @@ -64,7 +63,7 @@ Arena radius formula: `cRadius = panelWidth / (tan(alpha/2)) / 2` where `alpha = ### State Object ```javascript state = { - panelType: 'G6', // G3, G4, G4.1, G5, G6 + panelType: 'G6', // G3, G4, G4.1, G6 numCols: 12, // panels around (from 2D editor URL params) numRows: 3, // panels vertically activePanels: null, // array of active column indices, null = all @@ -85,7 +84,7 @@ Format: `arena_{gen}_{cols}c{rows}r_{pattern}[_stats]_{timestamp}.png` Example: `arena_G6_12c3r_sine120_stats_2026-01-17T10-30-45.png` ### URL Parameters -- `gen`: Panel generation (G3, G4, G4.1, G5, G6) - defaults to G6 +- `gen`: Panel generation (G3, G4, G4.1, G6) - defaults to G6 - `cols`: Number of columns (panels around) - defaults to 10 - `rows`: Number of rows (panels vertically) - defaults to 3 - `active`: Comma-separated 0-based indices of active panels (omitted if all active) diff --git a/README.md b/README.md index bfcd9fa..d70dbc8 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Create and edit 20×20 pixel patterns for G6 panels with: ### Arena Layout Editor ✅ Ready Configure arena geometry and panel layout for G3-G6 display systems with: - SVG-based visualization with labeled dimensions -- Support for all panel generations (G3, G4, G4.1, G5, G6, Custom) +- Support for all panel generations (G3, G4, G4.1, G6, Custom) - Click-to-toggle panels for partial arena designs - Angle offset control for arena rotation - Export PDF for documentation @@ -37,7 +37,7 @@ Configure arena geometry and panel layout for G3-G6 display systems with: ### Arena 3D Viewer ✅ Ready Interactive 3D visualization of arena configurations with: - Three.js-based 3D rendering with orbit controls -- Accurate LED visualization (rotated rectangles for G4.1/G5/G6, circles for G3/G4) +- Accurate LED visualization (rotated rectangles for G4.1/G6, circles for G3/G4) - Pattern visualization: All On, Grating (square wave), Sine wave - Animated pattern rotation with efficient color-only updates - Standard view presets (top-down, cardinal directions, fly view from center) diff --git a/arena_3d_viewer.html b/arena_3d_viewer.html index 1ec23ce..424dafe 100644 --- a/arena_3d_viewer.html +++ b/arena_3d_viewer.html @@ -453,7 +453,6 @@

Arena 3D Viewer

- @@ -607,13 +606,7 @@

View Controls

pixels_horizontal: 16, pixels_vertical: 16 }, - 'G5': { - panel_width_mm: 40, - panel_height_mm: 40, - panel_depth_mm: 6.35, - pixels_horizontal: 20, - pixels_vertical: 20 - }, + 'G6': { panel_width_mm: 45.4, panel_height_mm: 45.4, @@ -1357,8 +1350,8 @@

View Controls

const ledSpacingY = height / totalPixelsV; const ledSize = Math.min(ledSpacingX, ledSpacingY) * 0.35; // LED size relative to spacing - // Check if this panel type uses rotated rectangle LEDs (G4.1, G5, G6) - const useRotatedRectLEDs = ['G4.1', 'G5', 'G6'].includes(state.panelType); + // Check if this panel type uses rotated rectangle LEDs (G4.1, G6) + const useRotatedRectLEDs = ['G4.1', 'G6'].includes(state.panelType); // 0604 LED package: 0.6mm x 0.4mm = 1.5:1 aspect ratio // The LED is a rectangle rotated 45 degrees on the panel @@ -1375,7 +1368,7 @@

View Controls

const localZ = panelThickness + 0.001; // just in front of border if (useRotatedRectLEDs) { - // Create rectangle rotated 45 degrees for G4.1, G5, G6 + // Create rectangle rotated 45 degrees for G4.1, G6 // 0604 package: 0.6mm x 0.4mm = 1.5:1 aspect ratio const baseSize = ledSize * 0.5; const rectW = baseSize; // half-width of rectangle diff --git a/arena_editor.html b/arena_editor.html index e1b9ef5..55e2569 100644 --- a/arena_editor.html +++ b/arena_editor.html @@ -464,7 +464,6 @@

Configuration

- @@ -622,14 +621,7 @@

Custom Panel Configuration

pin_dist_mm: 4.57, pin_config: 'single' }, - 'G5': { - panel_width_mm: 40, - panel_depth_mm: 6.35, - pixels_per_panel: 20, - num_pins: 10, - pin_dist_mm: 4.57, - pin_config: 'single' - }, + 'G6': { panel_width_mm: 45.4, panel_depth_mm: 3.45, diff --git a/js/arena-calculations.js b/js/arena-calculations.js index e5693d8..f4dfe07 100644 --- a/js/arena-calculations.js +++ b/js/arena-calculations.js @@ -8,100 +8,93 @@ // Panel specifications (from MATLAB design_arena.m) const PANEL_SPECS = { - 'G3': { - panel_width_mm: 32, - panel_depth_mm: 18, - pixels_per_panel: 8, - num_pins: 8, - pin_dist_mm: 15.24, - pin_config: 'single' - }, - 'G4': { - panel_width_mm: 40.45, - panel_depth_mm: 18, - pixels_per_panel: 16, - num_pins: 15, - pin_dist_mm: 13, - pin_config: 'single' - }, - 'G4.1': { - panel_width_mm: 40, - panel_depth_mm: 6.35, - pixels_per_panel: 16, - num_pins: 15, - pin_dist_mm: 4.57, - pin_config: 'single' - }, - 'G5': { - panel_width_mm: 40, - panel_depth_mm: 6.35, - pixels_per_panel: 20, - num_pins: 10, - pin_dist_mm: 4.57, - pin_config: 'single' - }, - 'G6': { - panel_width_mm: 45.4, - panel_depth_mm: 3.45, - pixels_per_panel: 20, - num_pins: 10, - pin_dist_mm: 4.57, - pin_config: 'dual', - header_separation_mm: 30.8 - } + G3: { + panel_width_mm: 32, + panel_depth_mm: 18, + pixels_per_panel: 8, + num_pins: 8, + pin_dist_mm: 15.24, + pin_config: "single", + }, + G4: { + panel_width_mm: 40.45, + panel_depth_mm: 18, + pixels_per_panel: 16, + num_pins: 15, + pin_dist_mm: 13, + pin_config: "single", + }, + "G4.1": { + panel_width_mm: 40, + panel_depth_mm: 6.35, + pixels_per_panel: 16, + num_pins: 15, + pin_dist_mm: 4.57, + pin_config: "single", + }, + + G6: { + panel_width_mm: 45.4, + panel_depth_mm: 3.45, + pixels_per_panel: 20, + num_pins: 10, + pin_dist_mm: 4.57, + pin_config: "dual", + header_separation_mm: 30.8, + }, }; /** * Calculate arena geometry for a given panel type and number of panels - * @param {string} panelType - Panel generation (G3, G4, G4.1, G5, G6) + * @param {string} panelType - Panel generation (G3, G4, G4.1, G6) * @param {number} numPanels - Number of panels in the arena * @param {number[]} panelsInstalled - Array of installed panel indices (1-based) * @returns {object} Geometry calculations */ function calculateGeometry(panelType, numPanels, panelsInstalled = null) { - const specs = PANEL_SPECS[panelType]; - if (!specs) { - throw new Error(`Unknown panel type: ${panelType}`); - } - - // Default to all panels installed - if (!panelsInstalled) { - panelsInstalled = Array.from({ length: numPanels }, (_, i) => i + 1); - } - - // Convert to working units (inches internally, like MATLAB) - const panelWidth = specs.panel_width_mm / 25.4; - const panelDepth = specs.panel_depth_mm / 25.4; - - // Calculate geometry - const alpha = (2 * Math.PI) / numPanels; - const cRadius = panelWidth / (Math.tan(alpha / 2)) / 2; - const backCRadius = cRadius + panelDepth; - - // Resolution - const degsPerPixel = 360 / (numPanels * specs.pixels_per_panel); - const azimuthalPixels = numPanels * specs.pixels_per_panel; - - // Coverage - const azimuthCoverage = 360 * (panelsInstalled.length / numPanels); - const azimuthGap = 360 - azimuthCoverage; - - return { - panel_type: panelType, - num_panels: numPanels, - panels_installed: panelsInstalled, - c_radius_inches: cRadius, - c_radius_mm: cRadius * 25.4, - back_c_radius_inches: backCRadius, - back_c_radius_mm: backCRadius * 25.4, - degs_per_pixel: degsPerPixel, - azimuthal_pixels: azimuthalPixels, - azimuth_coverage: azimuthCoverage, - azimuth_gap: azimuthGap, - panel_width_mm: specs.panel_width_mm, - panel_depth_mm: specs.panel_depth_mm, - pixels_per_panel: specs.pixels_per_panel - }; + const specs = PANEL_SPECS[panelType]; + if (!specs) { + throw new Error(`Unknown panel type: ${panelType}`); + } + + // Default to all panels installed + if (!panelsInstalled) { + panelsInstalled = Array.from({ length: numPanels }, (_, i) => i + 1); + } + + // Convert to working units (inches internally, like MATLAB) + const panelWidth = specs.panel_width_mm / 25.4; + const panelDepth = specs.panel_depth_mm / 25.4; + + // Calculate geometry + const alpha = (2 * Math.PI) / numPanels; + const cRadius = panelWidth / Math.tan(alpha / 2) / 2; + const backCRadius = cRadius + panelDepth; + + // Resolution + const degsPerPixel = 360 / (numPanels * specs.pixels_per_panel); + const azimuthalPixels = numPanels * specs.pixels_per_panel; + + // Coverage + const azimuthCoverage = 360 * (panelsInstalled.length / numPanels); + const azimuthGap = 360 - azimuthCoverage; + + return { + panel_type: panelType, + num_panels: numPanels, + panels_installed: panelsInstalled, + c_radius_inches: cRadius, + c_radius_mm: cRadius * 25.4, + back_c_radius_inches: backCRadius, + back_c_radius_mm: backCRadius * 25.4, + degs_per_pixel: degsPerPixel, + azimuthal_pixels: azimuthalPixels, + azimuth_coverage: azimuthCoverage, + azimuth_gap: azimuthGap, + panel_width_mm: specs.panel_width_mm, + panel_depth_mm: specs.panel_depth_mm, + pixels_per_panel: specs.pixels_per_panel, + }; } /** @@ -112,58 +105,62 @@ function calculateGeometry(panelType, numPanels, panelsInstalled = null) { * @returns {object} Comparison results */ function compareGeometry(computed, reference, tolerance = 0.0001) { - const results = { - pass: true, - details: [] - }; - - const comparisons = [ - { field: 'c_radius_inches', label: 'Inner Radius (in)' }, - { field: 'back_c_radius_inches', label: 'Outer Radius (in)', refField: 'back_c_radius_inches' }, - { field: 'degs_per_pixel', label: 'Deg/Pixel' }, - { field: 'azimuthal_pixels', label: 'Azimuthal Pixels' } - ]; - - for (const comp of comparisons) { - const refField = comp.refField || comp.field; - const computedVal = computed[comp.field]; - const refVal = reference[refField]; - - if (refVal === undefined) continue; - - const diff = Math.abs(computedVal - refVal); - const pass = diff < tolerance; - - results.details.push({ - field: comp.label, - computed: computedVal, - reference: refVal, - diff: diff, - pass: pass - }); - - if (!pass) { - results.pass = false; - } + const results = { + pass: true, + details: [], + }; + + const comparisons = [ + { field: "c_radius_inches", label: "Inner Radius (in)" }, + { + field: "back_c_radius_inches", + label: "Outer Radius (in)", + refField: "back_c_radius_inches", + }, + { field: "degs_per_pixel", label: "Deg/Pixel" }, + { field: "azimuthal_pixels", label: "Azimuthal Pixels" }, + ]; + + for (const comp of comparisons) { + const refField = comp.refField || comp.field; + const computedVal = computed[comp.field]; + const refVal = reference[refField]; + + if (refVal === undefined) continue; + + const diff = Math.abs(computedVal - refVal); + const pass = diff < tolerance; + + results.details.push({ + field: comp.label, + computed: computedVal, + reference: refVal, + diff: diff, + pass: pass, + }); + + if (!pass) { + results.pass = false; } + } - return results; + return results; } // Export for Node.js -if (typeof module !== 'undefined' && module.exports) { - module.exports = { - PANEL_SPECS, - calculateGeometry, - compareGeometry - }; +if (typeof module !== "undefined" && module.exports) { + module.exports = { + PANEL_SPECS, + calculateGeometry, + compareGeometry, + }; } // Export for browser (ES6 modules) -if (typeof window !== 'undefined') { - window.ArenaCalculations = { - PANEL_SPECS, - calculateGeometry, - compareGeometry - }; +if (typeof window !== "undefined") { + window.ArenaCalculations = { + PANEL_SPECS, + calculateGeometry, + compareGeometry, + }; } From 75695da67e1ee5f89e5b1663f5562da1bc4a3dde Mon Sep 17 00:00:00 2001 From: Frank Loesche Date: Fri, 23 Jan 2026 00:25:45 -0500 Subject: [PATCH 2/2] remove reference data --- data/reference_data.json | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/data/reference_data.json b/data/reference_data.json index 5424a9e..58125e3 100644 --- a/data/reference_data.json +++ b/data/reference_data.json @@ -93,21 +93,6 @@ "panel_depth_mm":6.35, "pixels_per_panel":16 },{ -"panel_type":"G5", -"num_panels":8, -"panels_installed":[1,2,3,4,5,6,7,8], -"c_radius_inches":1.9009555609236968, -"c_radius_mm":48.284271247461895, -"back_c_radius_inches":2.1509555609236966, -"back_c_radius_mm":54.634271247461889, -"degs_per_pixel":2.25, -"azimuthal_pixels":160, -"azimuth_coverage":360, -"azimuth_gap":0, -"panel_width_mm":40, -"panel_depth_mm":6.35, -"pixels_per_panel":20 -},{ "panel_type":"G6", "num_panels":8, "panels_installed":[1,2,3,4,5,6,7,8], @@ -194,14 +179,6 @@ "pin_dist_mm":4.57, "pin_config":"single" }, -"G5":{ -"panel_width_mm":40, -"panel_depth_mm":6.35, -"pixels_per_panel":20, -"num_pins":10, -"pin_dist_mm":4.57, -"pin_config":"single" -}, "G6":{ "panel_width_mm":45.4, "panel_depth_mm":3.45,