<
Kingdom of Pattern
>

Bounded Random Grids

The principal methods of this module create grids of random numbers, which are constrained to vary by only so much per step in the x or y directions, and to lie within given bounds. That is, they create smooth, bounded surfaces. There are two principal methods:

this.setupRandomGridForShapes(nm:string,params:{step:number,min:number,max:number,numRows:integer,numCols:integer})

where nm is the name of the grid

step is the maximum amount that the random value can vary in one step of x or y on the grid. If numRows and numCols are not specified explicitly in the params argument, they are taken from this. A bounded random grid of the size specified by numRows and numCols is produced.

this.setupRandomGridForBoundaries(nm,params:{step:number,min:number,max:number,numRows:integer,numCols:integer}) is the same, except that a random grid of dimensions this.numRows+1 and this.numCols+1 is produced (thus one for each boundary line in a grid).

When several such grids, named, say a,b,c have been setup by setupRandomGridForShapes, they are used to produce the rvs argument to shapeGenerator in the grid module. Specifically, shapeGenerator will be called, for each grid cell, with rvs set to {a:<va>,b:<vb>,c:<vc>} where va,vb, and vc are the values at the given cell in the grids that have been setup by the calls:

this.setupRandomGridForShapes('a',params); 
this.setupRandomGridForShapes('b',params);
this.setupRandomGridForShapes('c',params); 

Similarly, setupRandomGridForBoundaries(nm,params) sets up grids which are used to produce the rvs argument to boundaryLineGenerator.

This is how the methods in this module are added to an image generator ig:

import {rs as addRandomMethods} from '/mlib/boundedRandomGrids.mjs';
addRandomMethods(ig);

For the grid module, two bounded grids are created when the pointJiggle parameter is defined at the top level, as in

let topParams = {width:wd,height:wd,numRows:nr,numCols:nr,pointJiggle:5,framePadding:0.15*wd};
Object.assign(rs,topParams);

These grids are named xJiggle and yJiggle. The points in the main grid are jiggled by the amounts specified in those bounded grids. The maximum amount of jiggle is given by the pointJiggle parameter. Instead of pointJiggle, jiggleParams may be specified instead as in

 let topParams = {...,jiggleParams:{step:1,min:-5,max:5}...};

Sometimes, instead of fixing bounding parameters for the entire grid, it is desirable to have them vary with grid coordinates. For this case, params can take on the value of a function of type (i:number,j:number) => {step:number,min:number,max:number}, where i is the column number, and j the row number. Here is an example

 

rs.initialize = function () {
  this.initProtos();
  let {numRows,numCols,lowJiggle,highJiggle,lowJiggleStep,highJiggleStep} = this;
  this.addFrame();
  let root2 = Math.sqrt(2);
  let hnr = numRows/2;
  const computeParams =  (i,j) => {
    let di = i - hnr;
    let dj = j - hnr;
    let maxFromCenter = root2*hnr;
    let fromCenter = Math.sqrt(di*di + dj*dj);
    let factor = 1 - fromCenter/maxFromCenter;// 0 at corners, up to 1 at center
    let jiggleMax = factor * highJiggle;
    let jiggleStep = factor * highJiggleStep;
    return {step:jiggleStep,min:-jiggleMax,max:jiggleMax,bias:i};
  }
  this.jiggleParams = computeParams;
  this.generateGrid();
}

in the context of /generators/grid_distortion_field.mjs

This produces the following image, in which the jiggle increases towards the center: