// visualiser.js // Dynamic 6x6 sensor visualiser with external centroid and mass input // Now supports 4 highlight indices (green points) // --- Core setup --- autowatch = 1; mgraphics.init(); mgraphics.autofill = 0; mgraphics.relative_coords = 0; // --- Data storage --- var gridSize = 6; var values = new Array(36).fill(0); var sensorMax = new Array(36).fill(700); // default max per sensor var tracers = []; var highlightIndices = []; // stores indices (1–36) that will be green // --- Parameters --- var fadeFactor = 0.9; var radiusMin = 5; var radiusMax = 30; var scaleCircles = 1.0; var scaleCentroid = 1.0; var tracerCount = 20; // --- Centroid --- var cx = 0.5; var cy = 0.5; var weight = 0.5; // --- Initialize --- function initValues() { values = new Array(gridSize * gridSize).fill(0); } initValues(); // --- Receive list: 36 sensor values + centroidX + centroidY + mass + 4 highlights --- function list() { var a = arrayfromargs(arguments); if (a.length != 43) return; // expect 43 values total (36 + 3 + 4) // --- First 36: sensor values --- for (var i = 0; i < 36; i++) { var v = Math.max(0, a[i]); var vmax = Math.max(1, sensorMax[i]); values[i] = v / vmax; } // --- Next 3: centroid x, y, mass --- cx = Math.max(0, Math.min(1, a[36])); cy = Math.max(0, Math.min(1, a[37])); weight = Math.max(0, a[38]); // --- Last 4: highlight indices (1–36) --- highlightIndices = []; for (var i = 39; i < 43; i++) { var idx = Math.floor(a[i]) - 1; // convert 1-based to 0-based if (idx >= 0 && idx < 36 && highlightIndices.indexOf(idx) === -1) highlightIndices.push(idx); } // Add to tracers tracers.push({x: cx, y: cy, alpha: 1.0}); if (tracers.length > tracerCount) tracers.shift(); mgraphics.redraw(); } // --- Set sensormax uniformly --- function sensormax(v) { v = Math.max(1, v); for (var i = 0; i < 36; i++) sensorMax[i] = v; } // --- Scaling controls --- function scalecircles(v) { scaleCircles = Math.max(0.1, v); } function scalecentroid(v) { scaleCentroid = Math.max(0.1, v); } // --- Grid size (optional) --- function grid(n) { gridSize = Math.max(1, Math.floor(n)); initValues(); mgraphics.redraw(); } // --- Drawing --- function paint() { with (mgraphics) { var w = box.rect[2] - box.rect[0]; var h = box.rect[3] - box.rect[1]; var margin = 0.1; var gridW = w * (1 - 2 * margin); var gridH = h * (1 - 2 * margin); var gridCells = gridSize - 1; var cellW = gridW / gridCells; var cellH = gridH / gridCells; // Background set_source_rgba(0.05, 0.05, 0.05, 1); rectangle(0, 0, w, h); fill(); // Grid lines set_source_rgba(0.4, 0.4, 0.4, 0.2); for (var i = 0; i <= gridCells; i++) { move_to(margin * w + i * cellW, margin * h); line_to(margin * w + i * cellW, margin * h + gridH); stroke(); move_to(margin * w, margin * h + i * cellH); line_to(margin * w + gridW, margin * h + i * cellH); stroke(); } // Circles (sensor nodes) for (var i = 0; i < gridSize; i++) { for (var j = 0; j < gridSize; j++) { var idx = i * gridSize + j; var val = values[idx]; var radius = (radiusMin + val * (radiusMax - radiusMin)) * scaleCircles; var x = margin * w + j * cellW; var y = margin * h + (gridSize - 1 - i) * cellH; // Determine color if (highlightIndices.indexOf(idx) !== -1) { set_source_rgba(0.2, 0.9, 0.3, 0.9); // green } else { set_source_rgba(0.2, 0.6, 0.9, 0.8); // blue } ellipse(x - radius / 2, y - radius / 2, radius, radius); fill(); } } // Tracers for (var t = 0; t < tracers.length; t++) { var tr = tracers[t]; set_source_rgba(1, 0.2, 0.2, tr.alpha * 0.6); var tx = margin * w + tr.y * gridW; var ty = margin * h + (1 - tr.x) * gridH; ellipse(tx - 4, ty - 4, 8, 8); fill(); tr.alpha *= fadeFactor; } // Centroid var cxPix = margin * w + cy * gridW; var cyPix = margin * h + (1 - cx) * gridH; var crad = (radiusMin + 15 * weight) * scaleCentroid; set_source_rgba(1, 0.2, 0.2, 1); ellipse(cxPix - crad / 2, cyPix - crad / 2, crad, crad); fill(); } }