let noiseSpace;

let step = 2;
let thresholdSlide;

let pointArr;

function setup() {
    sketchesCreateCanvas(600, 600);
    noiseSpace = new PerlinSpace(0.005);

    pointArr = createArray(noiseSpace);
    thresholdSlide = createSlider(0, 1, 0.5, 0.001);
    thresholdSlide.input(updateSquares);

    thresholdSlide.label("Threshold");

    updateSquares();
}

function createArray(noiseSpace) {
    let out = [];
    for (let x = 0; x <= width; x += step) {
        out.push([]);
        for (let y = 0; y <= height; y += step)
            out[x / step].push(noiseSpace.getNoise(x, y));
    }
    return out;
}

function updateSquares() {
    background(220);
    noiseSpace.fillCanvas();

    strokeWeight(5);

    for (let x = 0; x < pointArr.length - 1; x++)
        for (let y = 0; y < pointArr[x].length - 1; y++)
            drawSqaure(indexFromPoints([
                pointArr[x][y],
                pointArr[x + 1][y],
                pointArr[x][y + 1],
                pointArr[x + 1][y + 1]
            ], thresholdSlide.value()), createVector(x * step, y * step), step);

}
    
    class PerlinSpace{
  constructor(scale, xoff = null, yoff = null){
    this.scale = scale;
    
    this.xoff = xoff ? xoff : random(100, 1000);
    this.yoff = yoff ? xoff : random(100, 1000);
  }
  getNoise(x, y){
    return noise(this.xoff + x*this.scale, this.yoff + y*this.scale);
  }
  fillCanvas(){
    for (let x = 0; x < width; x++)
      for(let y = 0; y < height; y++)
        set(x, y, this.getNoise(x, y)*255);
    updatePixels();
  }
}
    
    let msqLookup = [
  [],
  [[0, 3]],
  [[0, 1]],
  [[1, 3]],
  [[3, 2]],
  [[0, 2]],
  [[0,3], [1, 2]],
  [[1, 2]],
  [[1, 2]],
  [[0,3], [1, 2]],
  [[0, 2]],
  [[3, 2]],
  [[1, 3]],
  [[0, 1]],
  [[0, 3]],
  [],
];

function linesToPoint(line){
  switch (line){
    case 0:
      return createVector(0.5, 0);
    case 1:
      return createVector(1, 0.5);
    case 2:
      return createVector(0.5, 1);
    case 3:
      return createVector(0, 0.5);
  }
}

function indexFromPoints(points, thresh = 0.5){
  let index = 0;
  for (let i = 0; i < 4; i++)
    if (points[i] < thresh)
      index += 1 << i;
  return index;
}

function drawSqaure(index, off, size = 1){
  msqLookup[index].forEach(function (lines){
    var pointa = linesToPoint(lines[0]).mult(size);
    var pointb = linesToPoint(lines[1]).mult(size);
    line(pointa.x+off.x, pointa.y+off.y, pointb.x+off.x, pointb.y+off.y);
  })
}
    
    
Return to Sketch