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