<
PrototypeJungle
>

powerGrid

This module will be introduced, as usual, via annotated code, which generates the image

First, here's a simplified variant of the code, which generates

import {rs as rectPP} from '/shape/rectangle.mjs';
import {rs as basicsP} from '/generators/basics.mjs';
import {rs as addGridMethods} from '/mlib/grid.mjs';
import {rs as addRandomMethods} from '/mlib/boundedRandomGrids.mjs';
import {rs as addPowerGridMethods} from '/mlib/powerGrid.mjs';
let rs = basicsP.instantiate();

addGridMethods(rs);
addRandomMethods(rs);
addPowerGridMethods(rs);
rs.setName('grid_void_variant');


rs.powerParams  = {
  root:2,
  sizeMap:[0.5,0.5,1,1],
  fillMap:['red','yellow','blue','white']
};
	
let wd = 100;
let nr = 32;
let topParams = {pointJiggle:1,numRows:nr,numCols:nr,width:wd,height:wd,backgroundColorr:'red',framePadding:0.15*wd};
Object.assign(rs,topParams);

rs.initProtos = function () {
  let rectP = this.set('rectP',rectPP.instantiate()).hide();
  this.rectP['stroke-width'] = 0;
}

rs.shapeGenerator = function () {
  debugger;
  return this.rectP.instantiate().show();
}

rs.initialize = function () {
  this.initProtos();
  this.addRectangle(this.backFill);
  this.generateGrid();
  this.addFrame();
}

export {rs};

We've seen this all before except for the lines:

rs.powerParams  = {
  root:2,
  sizeMap:[0.5,0.5,1,1],
  fillMap:['red','yellow','blue','white']
};

rs.powerParams describes a particular way of computing the size, fill, and stroke, to be assigned to the shape which will populate the given cell. There is a sizeMap for sizes and a fillMap and strokeMap for colors (all of these maps are optional). These maps take as input the largest power of root which occurs as factor in both of the cell's coordinates. Call the largest power of root which occurs as a factor of a number its root-regularity. Then odd numbers have 2-regularity 0 because they are not multiples of any power of 2. Numbers of the form 2*<odd-number> have 2-regularity 1 because they have a factor which is 2**1. Numbers of the form 4*<odd-number> have 2-regularity 2 because they are multiples of 2**2. And so on. Here is a 2-regularity table for numbers up to 16:

input         0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16
2-regularity  0  0  1  0  2  0  1  0  3  0   1  0  2  0  1  0  4

The 2-regularity of a cell is the minimum of the regularity of its x coordinate, and the regularity of its y coordinate. Perhaps now you can see how the image immediately above was generated. Regularity 0 cells are populated by small red rectangles. Regularity 1 cells are populated by small yellow rectangles. Regularity 2 cells are populated by larger blue rectangles. Finally, regularity 3 cells are populated by larger white rectangles.

To generate the final image, we need to adjust widthFactor and heightFactor so that they go to zero near the center.

This is done by the following code:

rs.powerParamsByCell = function (cell) {
  let {numRows,numCols,powerParams} = this;
  let {x,y} = cell;
  let cx = numCols/2;
  let cy = numRows/2;
  // {x:cx,y:cy} are coordinates of center
  let maxd = Math.sqrt(cx*cx + cy*cy);
  let xdc = x - cx;
  let ydc = y - cy;
  let cd = Math.sqrt(xdc*xdc + ydc*ydc); // distance from center
  let df = cd/maxd; //fractional distance from center; 1 = far as possible; 0 = at center
  let yf = y/numRows;
  let wf =  1.3* df;
  powerParams.widthFactor = wf;
  powerParams.heightFactor = wf;
  return powerParams;
}

As a final, touch, a largish black square is added at the center by the following modified initializer:

rs.initialize = function () {
  this.initProtos();
  this.addRectangle(this.backFill);
  this.generateGrid();
  let rdim = 10;
  this.addRectangle({width:rdim,height:rdim,fill:'black'});
  this.addFrame();
}