‹ eco

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)
    if (random(0, 10) > 8) { sxDrift = random(-0.1, 0.1) } else { sxDrift = 0 }
    if (random(0, 10) > 8) { syDrift = random(-0.1, 0.1) } else { syDrift = 0 }
    if (random(0, 10) > 8) { szDrift = random(-0.1, 0.1) } else { szDrift = 0 }
  } else {
    sxDrift = 0
    syDrift = 0
    szDrift = 0
    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) {
    return abs(sqrt(pow(other.x - this.x, 2) + pow(other.y - this.y, 2) + pow(other.z - this.z, 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 (_const) {
    this.vx = this.vx * _const
    this.vy = this.vy * _const
    this.vz = this.vz * _const
  }
}
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()
  }
}