‹ Construct2

Construct2_3d

click to generate new pattern

See /f0blog/useless-supercollider-class-no-2/

//
//  construct2_3d.js
//
//  Copyright (c) 2003 Fredrik Olofsson Musikproduktion. All rights reserved.
//
//  2001 original code in java
//  010502 max patch (rev.011004)
//  040920 ported to processing
//  060227 3d version for processing
//  071201 ported to sc (RedConstruct)
//  200326 ported to p5js

// ----------------------------------------------------------------------------

let stepX, stepY, stepZ
let x = 10
let y = 10
let z = 10
let dx = 1
let dy = 1
let dz = 1
let v // variant
let m // mapping
let col, row, depth
const movX = 95
const movY = 95
const movZ = 95
let maxXPerCol, maxYPerRow, maxZPerDepth

function setup() {
  const d = new Date().getMilliseconds()
  randomSeed(d)

  const div = select('#sketch')
  const cnv = createCanvas(div.width, div.height, WEBGL)
  cnv.parent('sketch')

  frameRate(60) // frameRate(25)
  background(255)
  nytt()
}

function mouseClicked() {
  background(255)
  nytt()
}

function keyTyped() {
  if (key === ' ') {
    background(255) // rensa skärmen
    nytt() // nya värden
  }
}

function draw() {
  if (int(random(1881)) === 0) {
    // lite då och då
    background(255) // rensa skärmen
    nytt() // nya värden
  }
  drawFO() // rita punkt(er)

  x += dx * stepX // flytta position x
  if (x < 1) {
    // om vänster kant
    dx = int(random(2)) // vänd eller stå still i x-led
  } else if (x > maxXPerCol) {
    // om höger kant
    dx = 0 - int(random(2)) // vänd eller stå still i x-led
  }

  y += dy * stepY // flytta position y
  if (y < 1) {
    // om övre kanten
    dy = int(random(2)) // vänd eller stå still i y-led
  } else if (y > maxYPerRow) {
    // om nedre kanten
    dy = 0 - int(random(2)) // vänd eller stå still i y-led
  }

  z += dz * stepZ // flytta position z
  if (z < 1) {
    // om botten
    dz = int(random(2)) // vänd eller stå still i z-led
  } else if (z > maxZPerDepth) {
    // om högst upp
    dz = 0 - int(random(2)) // vänd eller stå still i z-led
  }

  switch (v) {
    case 1:
      variant1()
      break
    case 2:
      variant2()
      break
    case 3:
      variant3()
      break
    case 4:
      variant4()
      break
    case 5:
      variant5()
      break
    case 6:
      variant6()
      break
    case 7:
      variant7()
      break
    case 8:
      variant8()
      break
    case 9:
      variant9()
      break
    case 10:
      variant10()
      break
  }
}

// ----------------------------------------------------------------------------
function variant1() {
  // 1. slumpa riktningar individuellt
  if (random(100) >= movX) {
    slumpaRiktningX()
  }
  if (random(100) >= movY) {
    slumpaRiktningY()
  }
  if (random(100) >= movZ) {
    slumpaRiktningZ()
  }
}
function variant2() {
  // 2. slumpa alltid riktningar tillsammans
  slumpaRiktningXYZ()
}
function variant3() {
  // 3. slumpa riktningar individuellt
  if (random(100) >= movX) {
    draVanster()
  }
  if (random(100) >= movY) {
    draUppat()
  }
  if (random(100) >= movZ) {
    draHogre()
  }
}
function variant4() {
  // 4. slumpa riktningar individuellt
  if (random(100) >= movX) {
    draHoger()
  }
  if (random(100) >= movY) {
    draUppat()
  }
  if (random(100) >= movZ) {
    draHogre()
  }
}
function variant5() {
  // 5. slumpa riktningar individuellt
  if (random(100) >= movX) {
    draVanster()
  }
  if (random(100) >= movY) {
    draNedat()
  }
  if (random(100) >= movZ) {
    draHogre()
  }
}
function variant6() {
  // 6. slumpa riktningar individuellt
  if (random(100) >= movX) {
    draHoger()
  }
  if (random(100) >= movY) {
    draNedat()
  }
  if (random(100) >= movZ) {
    draHogre()
  }
}
function variant7() {
  // 7. slumpa riktningar individuellt
  if (random(100) >= movX) {
    draVanster()
  }
  if (random(100) >= movY) {
    draUppat()
  }
  if (random(100) >= movZ) {
    draLagre()
  }
}
function variant8() {
  // 8. slumpa riktningar individuellt
  if (random(100) >= movX) {
    draHoger()
  }
  if (random(100) >= movY) {
    draUppat()
  }
  if (random(100) >= movZ) {
    draLagre()
  }
}
function variant9() {
  // 9. slumpa riktningar individuellt
  if (random(100) >= movX) {
    draVanster()
  }
  if (random(100) >= movY) {
    draNedat()
  }
  if (random(100) >= movZ) {
    draLagre()
  }
}
function variant10() {
  // 10. slumpa riktningar individuellt
  if (random(100) >= movX) {
    draHoger()
  }
  if (random(100) >= movY) {
    draNedat()
  }
  if (random(100) >= movZ) {
    draLagre()
  }
}

// ----------------------------------------------------------------------------
function nytt() {
  v = int(random(10)) + 1 // variant
  m = int(random(36)) // mapping
  col = int(random(15)) + 1
  row = int(random(13)) + 1
  depth = int(random(11)) + 1
  maxXPerCol = width / col
  maxYPerRow = height / row
  maxZPerDepth = int(random(600) + 20) / depth
  stepX = 1
  // stepX = int(random(2)) + 1
  stepY = 1
  // stepY = int(random(2)) % 2) + 1
  stepZ = 1
  // stepZ = int(random(2)) + 1
  slumpaRiktningXYZ()
  // print(
  //   `v:${v} m:${m} col:${col} row:${row} depth:${depth}
  //   maxXPerCol:${maxXPerCol}
  //   maxYPerRow:${maxYPerRow}
  //   maxZPerDepth:${maxZPerDepth}`
  // )
  stroke(random(255), 55, 66)
}
function slumpaRiktningX() {
  dx = int(random(2))
}
function slumpaRiktningY() {
  dy = int(random(2))
}
function slumpaRiktningZ() {
  dz = int(random(2))
}
function slumpaRiktningXYZ() {
  while (dx === 0 && dy === 0 && dz === 0) {
    // kolla att inte alla riktningar blir 0
    dx = int(random(2))
    dy = int(random(2))
    dz = int(random(2))
  }
}
function draVanster() {
  if (dx === 0 && x >= 1) {
    dx = -1
  } else {
    dx = 0
  } // dra åt vänster
}
function draHoger() {
  if (dx === 0 && x <= maxXPerCol) {
    dx = 1
  } else {
    dx = 0
  } // dra åt höger
}
function draNedat() {
  if (dy === 0 && y <= maxYPerRow) {
    dy = 1
  } else {
    dy = 0
  } // dra nedåt
}
function draUppat() {
  if (dy === 0 && y >= 1) {
    dy = -1
  } else {
    dy = 0
  } // dra uppåt
}
function draHogre() {
  if (dz === 0 && z >= 1) {
    dz = -1
  } else {
    dz = 0
  } // dra högre
}
function draLagre() {
  if (dz === 0 && z <= maxZPerDepth) {
    dz = 1
  } else {
    dz = 0
  } // dra lägre
}

// ----------------------------------------------------------------------------
function drawFO() {
  let iCol, jRow, kDepth
  const mx = m % 3
  const my = int(m / 3) % 3
  const mz = int(m / 6) % 3
  translate(-0.5 * width, -0.5 * height)
  for (let i = 0; i < col; i++) {
    iCol = round(maxXPerCol * i)
    if ((mx === 1 && i % 2 === 0) || (mx === 2 && i % 2 === 1)) {
      x = mirrorX(x)
    }
    for (let j = 0; j < row; j++) {
      jRow = round(maxYPerRow * j)
      if ((my === 1 && j % 2 === 0) || (my === 2 && j % 2 === 1)) {
        y = mirrorY(y)
      }
      for (let k = 0; k < depth; k++) {
        kDepth = round(maxZPerDepth * k)
        if ((mz === 1 && k % 2 === 0) || (mz === 2 && k % 2 === 1)) {
          z = mirrorZ(z)
        }
        push()
        translate(x + iCol, y + jRow, z + kDepth)
        box(0.1)
        pop()
      }
    }
  }
}
function mirrorX(x) {
  return round(maxXPerCol - x)
}
function mirrorY(y) {
  return round(maxYPerRow - y)
}
function mirrorZ(z) {
  return round(maxZPerDepth - z)
}