Creative Coding / Procedural Arts (p5js)

Links

openprocessing
OpenProcessing: open source codes and resources for creative coding practices and teaching

Here, I'd like to explain a few of my generative arts programming practices and algorithms. Please check the links above for more.

3D Spherical Vertex


IMG 5253
AudioVisual with P5js, P5LIVE, WEBGL, MIDI controller performance at Seoul Artists' Platform New & Young

Position small cubes into 3D Sphere vertex coordinates

  • Similar concept/result of Houdini's [CopyToPoints Node] with Sphere
  • Make class and properties for each cube. Each has a slightly different values for rotation, position, and colors.
  • Instead of making thousands of cubes, I make limited instanced of cubes for the performance.
    • I let the cubes to be rendered on the canvas and leave the rendering trace. And then, covering the canvas of black plane, imitaing as if the canvas is getting erased.
  • Reference: OpenGL Sphere algorithm
  • Basic Version Code Live Preview 1
for(let stAngle = 0; stAngle < 360; stAngle += 10) {
  let xy = radius*cos(stAngle);  
  let z = radius*sin(stAngle);
  
  for(let secAngle = -40; secAngle < 40; secAngle += 10) {
    let x = xy*cos(secAngle);
    let y = xy*sin(secAngle);
    
    let vec = createVector(x, y, z);
    let c = new Cube(vec, index, stAngle/10, secAngle/10, 0);
    index++;
    cubes.push(c);
  }		
}
class Cube {
	constructor(pos, ind, stIndex, secIndex, angle) {
		this.index = ind
		this.angle = angle;
		this.pos = pos;
		this.gap = 20;
		this.stIndex= stIndex;
		this.secIndex = secIndex;
		this.col = color(random(colors));
	}
	
	render() {
      rotateX(40+sin(frameCount/2)*(10*this.index));
      rotateZ(-100+sin(frameCount/2)*(10*this.index));
      push();
      translate(this.pos.x*this.gap, this.pos.y*this.gap, this.pos.z*this.gap);
      if(this.index%3 === 0) { 
        rotateX(this.angle);
      } else if(this.index%3 === 1) {
        rotateY(this.angle);
      } else if(this.index%3 === 2) {
        rotateZ(this.angle);
      }
      ambientMaterial(this.col);
      box(4);
      pop();
      if(this.index%numKey === 0) {
        this.gap = tan(frameCount/4) * 40;
      } else {
        this.gap = 10 + 20 * cos(frameCount/10);
      }
    }
	
	rotate(t) {
		this.angle += t;
	}
}
IMG 5282
AudioVisual with P5js, P5LIVE, WEBGL, MIDI controller LIVE CODING performance at Seoul Artists' Platform New & Young


2D Vertex + Bezier Manipulation

slide 7
AudioVisual with P5js, P5LIVE, WEBGL, MIDI controller LIVE CODING performance at JSCONF Korea

Progress & Development

  1. Divide each row, columns. Divide a row into several vertex points
  2. Conditionally fill the space inide vertex or stroke only
// trying to manage as a dataset

  let speedSin = sin(frameCount/slow)
  let speedCos = cos(frameCount/slow)
  let speedTan = tan(frameCount/slow)
  
  let change1 = speedCos*xSize
  let change2 = speedSin*xSize
  let change3 = speedTan*xSize*2
  
  let xOffset1 = speedCos*xSize
  let xOffset2 = speedSin*xSize
  let xOffset3 = speedTan*xSize
  
  const changes = [change1, change2, change3]
  const xOffsets = [xOffset1, xOffset2] // make rectangle to trapezoid/triangle
  const colorInd = [1, 2, 3, 4, 
                    3, 2, 1, 0,
                    // ...
                    3, 2, 1, 0]
// Draw rest number of vertex-rectangles in a row
// besides leftmost and rightmost
for(let i = 0; i < nums-3; i++) {
  strokeWeight(0.5)
  stroke(colorArr[colorInd[i]])
  
  let index = i % changes.length // 0, 1, 2
  let nextIndex = (i+1) % changes.length    
  let xInc = map(speedCos, -1, 1, 1, 2)
  let leftTopX = xSize * (i+xInc) + changes[index] + xOffsets[index]
  let v1 = {x: leftTopX, y: topY}

  beginShape()  
  // VERTEX 1 (LEFT TOP)
  vertex(v1.x, v1.y) 
  push()
  stroke(colorArr[colorInd[i]])
  strokeWeight(3)
  point(v1.x, v1.y)
  pop()

  // VERTEX 2 (RIGHT TOP)
  let rightTopX = xSize * (i+2) + changes[nextIndex] + xOffsets[nextIndex]
  let v2 = {x: rightTopX, y: topY}  
  vertex(v2.x , v2.y)
  push()
  stroke(colorArr[colorInd[i]])
  strokeWeight(3)
  point(v2.x , v2.y)
  pop()
  // ...
}
cc b1
2D horizontal, vertical bezier vertex segments
cc b2
2D horizontal, vertical bezier vertex segments
cc b5
2D horizontal, vertical bezier vertex segments
  1. Change vertex to Curve Vertex or Bezier Vertex makes the wavy, dynamic visuals
cc beziervertex
Bezier, Curve Vertex Update
cc bezier2
Bezier, Curve Vertex
cc bezier3
Bezier, Curve Vertex

2D Circular Vertex Animation (Trignometry)

cc circle0
Circular Vertex Segments
  1. Define each circular segment. It should start after the last inner circle.
function drawCircleSegments(speed, innerRadius, outerRadius, col) {
  let x1 = cos(speed)*innerRadius // change to tan, sin
  let y1 = sin(speed)*innerRadius 
  let x2 = cos(speed)*outerRadius
  let y2 = sin(speed)*outerRadius 
  let thickness = map(tan(speed), -5, 5, 1, strokeW) // change speed*2

  push()
  strokeWeight(thickness)
  stroke(col)
  point(x1, y1)
  point(x2, y2)
  line(x1, y1, x2, y2)
  pop()
}
  1. For each segment, loop through the amount of numbers you want for rotating elements inside each segment
for(let i = 0; i < 6; i++) {
  let speed = speed1
  if(i % 3 === 0) speed = speed2
  drawCircleSegments(speed + TWO_PI/10*i, r6, r6*1.25, colors[1][i])
}
// lines separating the segments at each radius
arc(0, 0, r6*1.25*2, r6*1.25*2, speed1 + TWO_PI/6*2, speed2 + TWO_PI/6*5)
arc(0, 0, r6*1.25*2, r6*1.25*2, speed2 + TWO_PI/6*1, speed1 + TWO_PI/6*5)
cc circular prototype
First version: Circular Vertex Segments
cc circle1
Second version: Circular Vertex Segments

For More

Tip for Cool Designer's eyes

Instagram feed

slide 11
Snapshots of performances and keynotes

Youtube for tutorials and more

slide 12
Snapshots of youtube tutorials