Task #6: Enter the Matrix

This week’s madness, as requested, picks a random set of x,y coordinates and draws a dot at that location. The
twist is that you can control the size of the dot with a slider. When I started writing this, I noticed that my larger dots were rarely symmetrical. A little thinking revealed that this was because the random numbers I was generating were rarely or never landing on pixel centers.

Solving this problem requires knowing the dimensions of the matrix. At this writing, there’s no straightforward way for a pattern to get that information, which is why you occasionally see matrix dimensions hard coded even in patterns that support render2D(). Here’s a way, only slightly hack-o-riffic, to get matrix dimensions on the fly:

// variables to help find matrix boundaries;
var sizeFound = 0;        
var xMax,yMax; 
var renderer = renderMapDimensions;

// variables used to generate random dot
var frameTimer = 9999;
var x1,y1,hue;

// variables used by UI
export var holdTime = 250;
export var dotSize = 1;

// UI Sliders
export function sliderDotSize(v) {
  dotSize = 0.5+10 * (v * v);
}

export function sliderHoldTime(v) {
  holdTime = 50 + (1500 * v);
}

// This is a sneaky way of determining the map dimensions for
// rectangular matrices while rendering (while not rendering, actually)
// the first frame. Will not work well on irregular 2D shapes.
// Far as I know, there's no direct way to get map data from a
// pattern right now.
// We do this because unless we know where the pixel centers are,
// it's difficult to generate random numbers that land on pixel centers.
function renderMapDimensions(index,x,y) {
  if (!sizeFound && x >= 0.999) {
    xMax = index;
    yMax = -1+ (pixelCount / (xMax+1));
    sizeFound = 1;
  }
}

// Render our random dot. Yay Pythagoras!!!  
function renderRandomDot(index,x,y) {
  x = ((x * xMax) - x1) ; y = ((y * yMax) - y1);
  bri = sqrt((x * x) + (y * y)) < dotSize;
  hsv(hue, 1, bri)  
}

// uses a straightforward timing mechanism based on 
// accumulating delta to periodically generate new
// random coordinates and color. 
export function beforeRender(delta) {
  frameTimer += delta
  if (sizeFound) renderer = renderRandomDot;
  
  if (frameTimer > holdTime) {
    frameTimer = 0;
    x1 = floor(random(xMax+1));
    y1 = floor(random(yMax+1));
    hue = random(1);
  }
}

export function render2D(index,x,y) {
  renderer(index,x,y);
}
3 Likes