diff --git a/steps/index.html b/steps/index.html index 741792f..8d8a8f4 100644 --- a/steps/index.html +++ b/steps/index.html @@ -394,12 +394,21 @@
+ class="w-full h-[75vh] bg-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg shadow-inner flex items-center justify-center relative">

Load JSON data to start visualization

+ + +
+ 80m + + Range +
+
Frame: | EGO State: | FPS: diff --git a/steps/src/drawUtils.js b/steps/src/drawUtils.js index 6a7ec03..cde2852 100644 --- a/steps/src/drawUtils.js +++ b/steps/src/drawUtils.js @@ -1,13 +1,10 @@ import { RADAR_X_MAX, RADAR_X_MIN, - RADAR_Y_MAX, RADAR_Y_MIN, MAX_TRAJECTORY_LENGTH, ROI_TRACKS_Y_MIN, - ROI_TRACKS_Y_MAX, ROI_CLOSE_Y_MIN, - ROI_CLOSE_Y_MAX, } from "./constants.js"; import { appState } from "./state.js"; import { @@ -163,7 +160,7 @@ export function drawAxes(p, plotScales) { // Draw horizontal grid lines. p.stroke(axisColor); p.strokeWeight(1); - for (let y = 5; y <= RADAR_Y_MAX; y += 5) + for (let y = 5; y <= appState.radarYMax; y += 5) p.line( RADAR_X_MIN * plotScales.plotScaleX, y * plotScales.plotScaleY, @@ -182,7 +179,7 @@ export function drawAxes(p, plotScales) { x * plotScales.plotScaleX, RADAR_Y_MIN * plotScales.plotScaleY, x * plotScales.plotScaleX, - RADAR_Y_MAX * plotScales.plotScaleY + appState.radarYMax * plotScales.plotScaleY ); } p.stroke(mainAxisColor); @@ -196,13 +193,13 @@ export function drawAxes(p, plotScales) { 0, RADAR_Y_MIN * plotScales.plotScaleY, 0, - RADAR_Y_MAX * plotScales.plotScaleY + appState.radarYMax * plotScales.plotScaleY ); // Draw Y-axis labels. p.fill(textColor); p.noStroke(); p.textSize(10); - for (let y = 5; y <= RADAR_Y_MAX; y += 5) { + for (let y = 5; y <= appState.radarYMax; y += 5) { p.push(); p.translate(5, y * plotScales.plotScaleY); // Flip text vertically to align with flipped Y-axis. @@ -1022,7 +1019,7 @@ export function drawRegionsOfInterest(p, frameData, plotScales) { left * plotScales.plotScaleX, ROI_TRACKS_Y_MIN * plotScales.plotScaleY, right * plotScales.plotScaleX, - ROI_TRACKS_Y_MAX * plotScales.plotScaleY + appState.radarYMax * plotScales.plotScaleY ); // --- Draw Close Region --- @@ -1031,7 +1028,7 @@ export function drawRegionsOfInterest(p, frameData, plotScales) { left * plotScales.plotScaleX, ROI_CLOSE_Y_MIN * plotScales.plotScaleY, right * plotScales.plotScaleX, - ROI_CLOSE_Y_MAX * plotScales.plotScaleY + (appState.radarYMax * 0.25) * plotScales.plotScaleY ); p.pop(); diff --git a/steps/src/p5/radarSketch.js b/steps/src/p5/radarSketch.js index 658d363..3b6b326 100644 --- a/steps/src/p5/radarSketch.js +++ b/steps/src/p5/radarSketch.js @@ -2,7 +2,6 @@ import { appState } from "../state.js"; import { debugFlags } from "../debug.js"; import { RADAR_X_MAX, - // Define radar plot boundaries RADAR_X_MIN, RADAR_Y_MAX, RADAR_Y_MIN, @@ -17,6 +16,8 @@ import { toggleVehicleDimensions, toggleClusterColor, toggleConfirmedOnly, + rangeSlider, + rangeValueDisplay, } from "../dom.js"; import { drawStaticRegionsToBuffer, @@ -60,6 +61,21 @@ export const radarSketch = function (p) { }; // Function to calculate scaling factors for radar coordinates to canvas pixels function calculatePlotScales() { + // --- START: Safety Fallback Logic --- + // Ensure we have valid numbers; if not, revert to constants from constants.js + const xMin = typeof appState.radarXMin === 'number' ? appState.radarXMin : RADAR_X_MIN; + const xMax = typeof appState.radarXMax === 'number' ? appState.radarXMax : RADAR_X_MAX; + const yMin = typeof appState.radarYMin === 'number' ? appState.radarYMin : RADAR_Y_MIN; + const yMax = typeof appState.radarYMax === 'number' ? appState.radarYMax : RADAR_Y_MAX; + + const dx = xMax - xMin; + const dy = yMax - yMin; + + // Final safety: Prevent division by zero if values are somehow identical or inverted + const safeDx = dx > 0 ? dx : 50; // Default width 50m + const safeDy = dy > 0 ? dy : 80; // Default height 80m + // --- END: Safety Fallback Logic --- + // Padding and offset values for the plot area const hPad = 0.05, vPad = 0.05, @@ -67,9 +83,10 @@ export const radarSketch = function (p) { // Calculate available width and height for the plot const aW = p.width * (1 - 2 * hPad); const aH = p.height * (1 - bOff - vPad); + // Determine plot scales based on radar boundaries and available canvas space - plotScales.plotScaleX = aW / (RADAR_X_MAX - RADAR_X_MIN); - plotScales.plotScaleY = aH / (RADAR_Y_MAX - RADAR_Y_MIN); + plotScales.plotScaleX = aW / safeDx; + plotScales.plotScaleY = aH / safeDy; } p.setup = function () { @@ -106,7 +123,7 @@ export const radarSketch = function (p) { appState.zoomSketchInstance && appState.zoomSketchInstance.updateAndDraw ) { - const hoveredItems = handleCloseUpDisplay(p, plotScales); + const hoveredItems = handleCloseUpDisplay(p, plotScales, p.mouseX, p.mouseY); appState.zoomSketchInstance.updateAndDraw( p.mouseX, p.mouseY, @@ -134,6 +151,38 @@ export const radarSketch = function (p) { // Reset FPS state to prevent stale values from previous sessions appState.fps = 0; + // --- START: Radar Range Slider Logic --- + if (rangeSlider && rangeValueDisplay) { + // Initialize slider value from appState + rangeSlider.value = appState.radarYMax; + rangeValueDisplay.textContent = appState.radarYMax + "m"; + + // Add listener to handle slider changes + rangeSlider.addEventListener("input", () => { + const newMax = parseInt(rangeSlider.value); + appState.radarYMax = newMax; + rangeValueDisplay.textContent = newMax + "m"; + + // Recalculate scales and redraw static background + calculatePlotScales(); + drawStaticRegionsToBuffer(p, staticBackgroundBuffer, plotScales); + + // Redraw main sketch to reflect new scale immediately + p.redraw(); + }); + + // Reset to default on double-click + rangeSlider.addEventListener("dblclick", () => { + appState.radarYMax = RADAR_Y_MAX; + rangeSlider.value = RADAR_Y_MAX; + rangeValueDisplay.textContent = RADAR_Y_MAX + "m"; + calculatePlotScales(); + drawStaticRegionsToBuffer(p, staticBackgroundBuffer, plotScales); + p.redraw(); + }); + } + // --- END: Radar Range Slider Logic --- + p.noLoop(); // Disable continuous looping, redraw will be called manually }; diff --git a/steps/src/state.js b/steps/src/state.js index 4093299..b0b976d 100644 --- a/steps/src/state.js +++ b/steps/src/state.js @@ -1,3 +1,10 @@ +import { + RADAR_X_MIN, + RADAR_X_MAX, + RADAR_Y_MIN, + RADAR_Y_MAX +} from "./constants.js"; + export const appState = { zoomHideDelayTimeout: null, // Timeout before the hide countdown begins zoomCountdown: null, // Holds the number of seconds left before zoom hides @@ -60,4 +67,9 @@ export const appState = { consecutiveResyncs: 0, // Counter for consecutive resyncs isInLockdown: false, // Flag to prevent nested lockdown triggers + // --- Dynamic Radar Boundaries --- + radarXMin: RADAR_X_MIN, + radarXMax: RADAR_X_MAX, + radarYMin: RADAR_Y_MIN, + radarYMax: RADAR_Y_MAX, };