‹ 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)
}