class OkuboBug extends Bug { // behavioral model parameters: Okubo and Anderson / Banas et al. 2003, Daphnia values // units are mm and s float omega = 0.49; // attractive force = - omega x^2 float beta = 0.54; // damping = - k u float B = 3.6; // power of excitation; excitation acceleration is sqrt(2B/dt)*randn boolean swarmZ = false; OkuboBug(OkuboTank thetank) { super(thetank); } void force(float dt) { float E = sqrt(2*B/dt); acc.x = E * randn() - beta * vel.x - sq(omega) * (pos.x - ((OkuboTank) tank).laserPos.x); acc.y = E * randn() - beta * vel.y - sq(omega) * (pos.y - ((OkuboTank) tank).laserPos.y); acc.z = E * randn() - beta * vel.z; if (swarmZ) { acc.z -= omega * sq(pos.z); } } } class Bug { vector pos = new vector(0,0,0); vector vel = new vector(0,0,0); vector acc = new vector(0,0,0); color col = shift(orangeColor,random(-0.25,0.25)); Universe tank; Bug(Universe thetank) { tank = thetank; pos.x = random(tank.modelMin.x,tank.modelMax.x); pos.y = random(tank.modelMin.y,tank.modelMax.y); pos.z = random(tank.modelMin.z,tank.modelMax.z); constrainPos(); } void force(float dt) { // the actual equations of motion go here } void move(float dt) { force(dt); vel = vel.plus(acc.times(dt)); pos = pos.plus(vel.times(dt)); constrainPos(); } void constrainPos() { float newx = constrain(pos.x, tank.modelMin.x, tank.modelMax.x); if (newx != pos.x) {vel.x = 0;} float newy = constrain(pos.y, tank.modelMin.y, tank.modelMax.y); if (newy != pos.y) {vel.y = 0;} float newz = constrain(pos.z, tank.modelMin.z, tank.modelMax.z); if (newz != pos.z) {vel.z = 0;} pos = new vector(newx, newy, newz); } void draw() { pushMatrix(); noStroke(); fill(col); vector scr = tank.pos2scr(pos); translate(scr.x,scr.z); rotate(atan2(vel.z,vel.x)); ellipse(0, 0, 12, 6); popMatrix(); } void update(float dt) { move(dt); draw(); } }