Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // V8UI OBJECT CODE FOR PAINTING IN A GRID
- inlets = 2; // inlet 0: bang for redraw, inlet 1: bang for random paint
- outlets = 1; // for outputting matrix data
- mgraphics.init();
- mgraphics.autofill = 0;
- mgraphics.relative_coords = 0;
- var gridSize = 32; // grid size
- var canvasSize = 450; // 450x450 pixels
- var cellSize = canvasSize / gridSize; // pixels per cell
- var fadeTime = 2500; // ms until stroke fully disappears
- var brushRadius = 2; // cells (radius from center)
- var fadeCurve = 2;
- // Grid data: each cell stores array of {intensity, timestamp} values
- var grid = [];
- var maxIntensityPerCell = 1.0; // cap intensity accumulation
- // Initialize grid
- function initGrid() {
- grid = [];
- for (var y = 0; y < gridSize; y++) {
- grid[y] = [];
- for (var x = 0; x < gridSize; x++) {
- grid[y][x] = []; // array of {intensity, t} objects
- }
- }
- }
- function loadbang() {
- this.box.message("size", canvasSize, canvasSize);
- initGrid();
- post("Grid initialized: " + gridSize + "x" + gridSize + " cells\n");
- post("Fade curve: " + fadeCurve + " (try 'curve 1.0' for linear, 'curve 2.0' for quadratic, 'curve 3.0' for cubic)\n");
- post("Inlet 0: bang for redraw, Inlet 1: bang for random paint\n");
- }
- // inlet 0: bang from [qmetro n] — forces redraw every n ms
- function bang() {
- if (inlet === 0) {
- mgraphics.redraw();
- } else if (inlet === 1) {
- // Generate random paint stroke
- var randomX = Math.random() * canvasSize;
- var randomY = Math.random() * canvasSize;
- paintGrid(randomX, randomY);
- // Optionally trigger a redraw immediately to see the stroke
- mgraphics.redraw();
- }
- }
- // set fade duration with 'fade n'
- function fade(n) {
- fadeTime = Math.max(1, n);
- }
- // set fade curve with 'curve n' (1.0 = linear, 2.0 = quadratic, 3.0 = cubic, etc.)
- function curve(n) {
- fadeCurve = Math.max(0.1, n);
- post("Fade curve: " + fadeCurve + " (1.0=linear, >1.0=exponential)\n");
- }
- // set grid size with 'gridsize n'
- function gridsize(n) {
- gridSize = Math.max(1, Math.min(100, n)); // limit between 1-100
- cellSize = canvasSize / gridSize;
- initGrid();
- post("Grid size changed to: " + gridSize + "x" + gridSize + "\n");
- }
- // set brush radius with 'radius n'
- function radius(n) {
- brushRadius = Math.max(1, n);
- post("Brush radius: " + brushRadius + " cells\n");
- }
- // Convert pixel coordinates to grid coordinates
- function pixelToGrid(x, y) {
- return {
- x: Math.floor(x / cellSize),
- y: Math.floor(y / cellSize)
- };
- }
- // Add intensity to grid cells in brush pattern
- function paintGrid(centerX, centerY) {
- // Safety check: ensure grid is initialised
- if (!grid || grid.length === 0) {
- initGrid();
- }
- var now = Date.now();
- var gridPos = pixelToGrid(centerX, centerY);
- // Paint center cell and surrounding cells based on distance
- for (var dy = -brushRadius; dy <= brushRadius; dy++) {
- for (var dx = -brushRadius; dx <= brushRadius; dx++) {
- var x = gridPos.x + dx;
- var y = gridPos.y + dy;
- // Check bounds
- if (x >= 0 && x < gridSize && y >= 0 && y < gridSize) {
- // Calculate distance from center (using Euclidean distance)
- var distance = Math.sqrt(dx * dx + dy * dy);
- if (distance <= brushRadius) {
- // Calculate intensity based on distance (1.0 at center, 0.0 at edge)
- var intensity = Math.max(0, 1.0 - (distance / brushRadius));
- // Add this paint stroke to the cell
- grid[y][x].push({
- intensity: intensity,
- t: now
- });
- }
- }
- }
- }
- }
- // v8ui mouse callbacks
- function onclick(x, y, button) {
- if (button) { // only paint if button is pressed
- paintGrid(x, y);
- }
- }
- function ondrag(x, y, button) {
- if (button) { // only paint while button is held down
- paintGrid(x, y);
- }
- }
- // Calculate current intensity for a cell (sum of all non-faded strokes)
- function getCurrentCellIntensity(x, y) {
- // Safety check: ensure grid is initialised
- if (!grid || !grid[y] || !grid[y][x]) {
- return 0;
- }
- var now = Date.now();
- var totalIntensity = 0;
- var cell = grid[y][x];
- // Remove faded strokes and sum remaining intensities
- grid[y][x] = cell.filter(function(stroke) {
- var age = now - stroke.t;
- if (age < fadeTime) {
- // Linear fade (0.0 to 1.0)
- var linearFade = 1 - (age / fadeTime);
- // Apply exponential curve for more musical fade
- var ageAlpha = Math.pow(linearFade, fadeCurve);
- totalIntensity += stroke.intensity * ageAlpha;
- return true;
- }
- return false;
- });
- return Math.min(totalIntensity, maxIntensityPerCell);
- }
- // Output current grid state as matrix
- function output() {
- // Safety check: ensure grid is initialised
- if (!grid || grid.length === 0) {
- post("Grid not initialized, cannot output matrix\n");
- return;
- }
- var matrix = [];
- for (var y = 0; y < gridSize; y++) {
- var row = [];
- for (var x = 0; x < gridSize; x++) {
- row.push(getCurrentCellIntensity(x, y));
- }
- matrix.push(row);
- }
- // Send matrix data out outlet 0
- outlet(0, "matrix", JSON.stringify(matrix));
- // post("Matrix output: " + gridSize + "x" + gridSize + " intensities\n");
- }
- // Output current grid state as flat list
- function outputlist() {
- // Safety check: ensure grid is initialised
- if (!grid || grid.length === 0) {
- post("Grid not initialized, cannot output list\n");
- return;
- }
- var flatList = [];
- for (var y = 0; y < gridSize; y++) {
- for (var x = 0; x < gridSize; x++) {
- flatList.push(getCurrentCellIntensity(x, y));
- }
- }
- // Send as list out outlet 0 (row-major order: row0, row1, row2, ...)
- outlet(0, "list", flatList);
- // post("List output: " + flatList.length + " values (" + gridSize + "x" + gridSize + " grid)\n");
- }
- // Clear the grid
- function clear() {
- initGrid();
- mgraphics.redraw();
- post("Grid cleared\n");
- }
- function paint() {
- var w = this.box.rect[2];
- var h = this.box.rect[3];
- // Background
- mgraphics.set_source_rgba(0, 0, 0, 1);
- mgraphics.rectangle(0, 0, w, h);
- mgraphics.fill();
- // Safety check: ensure grid is initialized
- if (!grid || grid.length === 0) {
- initGrid();
- return;
- }
- // Draw grid cells
- for (var y = 0; y < gridSize; y++) {
- for (var x = 0; x < gridSize; x++) {
- var intensity = getCurrentCellIntensity(x, y);
- if (intensity > 0) {
- // Cell position in pixels
- var cellX = x * cellSize;
- var cellY = y * cellSize;
- // Draw cell with intensity-based alpha
- mgraphics.set_source_rgba(0, 1, 1, intensity);
- mgraphics.rectangle(cellX, cellY, cellSize, cellSize);
- mgraphics.fill();
- }
- }
- }
- // Draw grid lines
- mgraphics.set_source_rgba(0.2, 0.2, 0.2, 0.3);
- mgraphics.set_line_width(1);
- for (var i = 0; i <= gridSize; i++) {
- var pos = i * cellSize;
- // Vertical lines
- mgraphics.move_to(pos, 0);
- mgraphics.line_to(pos, h);
- // Horizontal lines
- mgraphics.move_to(0, pos);
- mgraphics.line_to(w, pos);
- }
- mgraphics.stroke();
- }
Advertisement
Add Comment
Please, Sign In to add comment