Trails

click to explode

// some old processing code ported to p5js
// click to explode

const numAgents = 50
const agents = []
let rotX = 0
let rotY = 0
let rotZ = 0
let rx
let ry
let rz
let tx, ty, tz
let sx, sy, sz, sxDrift, syDrift, szDrift

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

  frameRate(30)
  mouseClicked()
}
function draw() {
  translate(tx, ty, tz)
  sx = sx + sxDrift
  sy = sy + syDrift
  sz = sz + szDrift
  scale(sx, sy, sz)
  rotX = rotX + radians(rx)
  rotateX(rotX)
  rotY = rotY + radians(ry)
  rotateY(rotY)
  rotZ = rotZ + radians(rz)
  rotateZ(rotZ)
  for (let i = 0; i < numAgents; i++) {
    agents[i].move()
    agents[i].draw()
  }
}
function mouseClicked() {
  background(150, 150, 120)
  initAgents()
  newTrans()
  newScale()
  newRotation()
}
function initAgents() {
  const world = new AWorld(3, 400, 400, 400, 0.95)
  for (let i = 0; i < numAgents; i++) {
    const loc = new ALocation(
      world,
      random(-0.1, 0.1),
      random(-0.1, 0.1),
      random(-0.1, 0.1),
    )
    const dir = new ADirection(
      random(-0.05, 0.05),
      random(-0.05, 0.05),
      random(-0.05, 0.05),
    )
    agents[i] = new Agent3D(loc, dir, random(1.0), color(255, 0, 0), color(0), 5)
    // agents[i] = new Agent2D(loc, dir, random(1.0), color(255, 0, 0), color(0), 5)
    // agents[i] = new Agent1D(loc, dir, random(1.0), color(255, 0, 0), color(0), 5)
  }
}
function newTrans() {
  tx = int(random(-width / 3, width / 3))
  ty = int(random(-height / 3, height / 3))
  tz = 0
}
function newScale() {
  if (random(0, 10) > 7) {
    sx = random(0.6, 1.2)
    sy = random(0.6, 1.2)
    sz = random(0.1, 2)
    sxDrift = 0
    syDrift = 0
    szDrift = 0
    if (random(0, 10) > 8) {
      sxDrift = random(-0.1, 0.1)
    }
    if (random(0, 10) > 8) {
      syDrift = random(-0.1, 0.1)
    }
    if (random(0, 10) > 8) {
      szDrift = random(-0.1, 0.1)
    }
  } else {
    if (random(0, 10) > 5) {
      sx = random(0.3, 0.7)
      sy = random(0.2, 0.6)
      sz = random(0.01, 0.25)
    } else {
      sx = 1
      sy = 1
      sz = 1
    }
  }
}
function newRotation() {
  rx = ry = rz = 0
  rotX = rotY = rotZ = 0
  if (random(0, 10) > 7) {
    ry = random(-4, 4)
  }
  if (random(0, 10) > 7) {
    rz = random(-4, 4)
  }
  if (random(0, 10) > 4) {
    rx = random(-4, 4)
  }
  if (rx + ry + rz === 0) {
    // make sure always some rotation
    rx = random(0.5, 3)
  }
}

// redFri - version 060225

class ALocation {
  constructor(_world, _x, _y, _z) {
    this.world = _world
    this.x = _x
    this.y = _y
    this.z = _z
  }

  distance(other) {
    const dx = other.x - this.x
    const dy = other.y - this.y
    const dz = other.z - this.z
    return abs(sqrt(pow(dx, 2) + pow(dy, 2) + pow(dz, 2)))
  }

  add(dir) {
    this.x = this.x + dir.vx
    this.y = this.y + dir.vy
    this.z = this.z + dir.vz
  }
}
class ADirection {
  constructor(_vx, _vy, _vz) {
    this.vx = _vx
    this.vy = _vy
    this.vz = _vz
  }

  mul(val) {
    this.vx = this.vx * val
    this.vy = this.vy * val
    this.vz = this.vz * val
  }
}
class AWorld {
  constructor(_dim, _w, _h, _d, _damp) {
    this.dim = _dim
    this.w = _w
    this.h = _h
    this.d = _d
    this.damp = _damp
  }
}

// --
class Agent {
  // abstract
  constructor(_loc, _dir, _energy, _col, _borderCol, _agentSize) {
    if (this.constructor === Agent) {
      throw new Error("Abstract classes can't be instantiated.")
    }
    this.loc = _loc
    this.dir = _dir
    this.energy = _energy
    this.col = _col
    this.borderCol = _borderCol
    this.agentSize = _agentSize
  }

  draw() {
    stroke(this.borderCol)
    fill(this.col)
    this.drawShape()
  }

  drawShape() {} // to override

  move() {
    this.loc.add(this.dir)
    this.dir.mul(this.loc.world.damp)
  }
}

// --
class Agent1D extends Agent {
  drawShape() {
    point(this.loc.x * width, this.height / 2) // agentSize???
  }
}
class Agent2D extends Agent {
  drawShape() {
    rect(this.loc.x * width, this.loc.y * height, this.agentSize, this.agentSize)
  }
}
class Agent3D extends Agent {
  drawShape() {
    push()
    translate(this.loc.x * width, this.loc.y * height, this.loc.z * 100)
    box(this.agentSize)
    pop()
  }
}