Hi there! I'm trying to learn processing via messing around with found script. I'm trying to make these fish repel away from the mouse, and, eventually, any red color data collected from my kinect.
Could anybody help me?
Just the fish code:
import org.openkinect.freenect.*;
import org.openkinect.processing.*;
// The kinect stuff is happening in another class
KinectTracker tracker;
Kinect kinect;
void setup() {
size(640, 520);
kinect = new Kinect(this);
tracker = new KinectTracker();
for(int v = 0; v < numVehicles; v++)
{
Vector2D startPosition = new Vector2D(random(width), random(height));
Vector2D startVelocity = new Vector2D(random(-2, 2), random(-2, 2));
Vehicles[v] = new SteeredVehicle(startPosition, startVelocity);
}
}
void draw() {
background(255);
// Run the tracking analysis
tracker.track();
// Show the image
tracker.display();
// Let's draw the raw location
PVector v1 = tracker.getPos();
fill(50, 100, 250, 200);
noStroke();
ellipse(v1.x, v1.y, 20, 20);
// Let's draw the "lerped" location
PVector v2 = tracker.getLerpedPos();
fill(100, 250, 50, 200);
noStroke();
ellipse(v2.x, v2.y, 20, 20);
// Display some info
int t = tracker.getThreshold();
fill(0);
text("threshold: " + t + " " + "framerate: " + int(frameRate) + " " +
"UP increase threshold, DOWN decrease threshold", 10, 500);
for(int v = 0; v < numVehicles; v++)
{
Vehicles[v].flock(Vehicles);
Vehicles[v].setEdgeBehaviour("wrap");
Vehicles[v].update();
}
}
// Adjust the threshold with key presses
void keyPressed() {
int t = tracker.getThreshold();
if (key == CODED) {
if (keyCode == UP) {
t+=5;
tracker.setThreshold(t);
} else if (keyCode == DOWN) {
t-=5;
tracker.setThreshold(t);
}
}
}
class KinectTracker {
// Depth threshold
int threshold = 745;
// Raw location
PVector loc;
// Interpolated location
PVector lerpedLoc;
// Depth data
int[] depth;
// What we'll show the user
PImage display;
KinectTracker() {
// This is an awkard use of a global variable here
// But doing it this way for simplicity
kinect.initDepth();
kinect.enableMirror(true);
// Make a blank image
display = createImage(kinect.width, kinect.height, RGB);
// Set up the vectors
loc = new PVector(0, 0);
lerpedLoc = new PVector(0, 0);
}
void track() {
// Get the raw depth as array of integers
depth = kinect.getRawDepth();
// Being overly cautious here
if (depth == null) return;
float sumX = 0;
float sumY = 0;
float count = 0;
for (int x = 0; x < kinect.width; x++) {
for (int y = 0; y < kinect.height; y++) {
int offset = x + y*kinect.width;
// Grabbing the raw depth
int rawDepth = depth[offset];
// Testing against threshold
if (rawDepth < threshold) {
sumX += x;
sumY += y;
count++;
}
}
}
// As long as we found something
if (count != 0) {
loc = new PVector(sumX/count, sumY/count);
}
// Interpolating the location, doing it arbitrarily for now
lerpedLoc.x = PApplet.lerp(lerpedLoc.x, loc.x, 0.3f);
lerpedLoc.y = PApplet.lerp(lerpedLoc.y, loc.y, 0.3f);
}
PVector getLerpedPos() {
return lerpedLoc;
}
PVector getPos() {
return loc;
}
void display() {
PImage img = kinect.getDepthImage();
// Being overly cautious here
if (depth == null || img == null) return;
// Going to rewrite the depth image to show which pixels are in threshold
// A lot of this is redundant, but this is just for demonstration purposes
display.loadPixels();
for (int x = 0; x < kinect.width; x++) {
for (int y = 0; y < kinect.height; y++) {
int offset = x + y * kinect.width;
// Raw depth
int rawDepth = depth[offset];
int pix = x + y * display.width;
if (rawDepth < threshold) {
// A red color instead
display.pixels[pix] = color(150, 50, 50);
} else {
display.pixels[pix] = img.pixels[offset];
}
}
}
display.updatePixels();
// Draw the image
image(display, 0, 0);
}
int getThreshold() {
return threshold;
}
void setThreshold(int t) {
threshold = t;
}
}
class SteeredVehicle extends Vehicle
{
// _maxForce best values
// seek 0.05 - 0.1, flee 0.01 - 0.05
float _maxForce = 0.1; //1.0;
Vector2D _steeringForce;
float _arrivalThreshold = 100;
float _wanderAngle = 0.0; //0
float _wanderDistance = 10.0; //10
float _wanderRadius = 5.0; //5
float _wanderRange = 1.0; //1
float _avoidDistance = 50;
float _avoidBuffer = 10;
int _pathIndex = 0;
float _pathThreshold = 20;
Boolean _loopRound = false;
float _inSightDist = 200;
float _tooCloseDist = 60;
SteeredVehicle()
{
super();
_steeringForce = new Vector2D();
}
SteeredVehicle(Vector2D _position, Vector2D _velocity)
{
super(_position, _velocity);
_steeringForce = new Vector2D();
}
// set/get maxForce
void setMaxForce(float value)
{
_maxForce = value;
}
float getMaxForce()
{
return _maxForce;
}
void update()
{
_steeringForce.limit(_maxForce);
_steeringForce.div(_mass);
_velocity.add(_steeringForce);
_steeringForce = new Vector2D();
// if (_position.x < 0 ) exit();
super.update();
}
//*** seek and flee
// differ only by addition or subtraction of force
void seek(Vector2D target)
{
Vector2D desiredVelocity = target.clone();
desiredVelocity.sub(_position);
desiredVelocity.normalize();
desiredVelocity.mult(_maxSpeed);
Vector2D force = desiredVelocity.clone();
force.sub(_velocity);
_steeringForce.add(force);
}
void flee(Vector2D target)
{
Vector2D desiredVelocity = target.clone();
desiredVelocity.sub(_position);
desiredVelocity.normalize();
desiredVelocity.mult(_maxSpeed);
Vector2D force = desiredVelocity.clone();
force.sub(_velocity);
_steeringForce.sub(force);
}
//*** arrive
void arrive(Vector2D target)
{
Vector2D desiredVelocity = target.clone();
desiredVelocity.sub(_position);
desiredVelocity.normalize();
float distV = _position.distV(target);
if(distV > _arrivalThreshold)
{
desiredVelocity.mult(_maxSpeed);
}
else
{
desiredVelocity.mult(_maxSpeed * distV / _arrivalThreshold);
}
Vector2D force = desiredVelocity.clone();
force.sub(_velocity);
_steeringForce.add(force);
}
//*** persue and evade
void persue(Vehicle target)
{
float lookAheadTime = _position.distV(target._position) / _maxSpeed;
Vector2D predictedPosition = target._position.clone();
Vector2D predictedVelocity = target._velocity.clone();
predictedVelocity.mult(lookAheadTime);
predictedPosition.add(predictedVelocity);
seek(predictedPosition);
}
void evade(Vehicle target)
{
float lookAheadTime = _position.distV(target._position) / _maxSpeed;
Vector2D predictedPosition = target._position.clone();
Vector2D predictedVelocity = target._velocity.clone();
predictedVelocity.mult(lookAheadTime);
predictedPosition.sub(predictedVelocity);
flee(predictedPosition);
}
//*** wander
void wander()
{
Vector2D centre = _velocity.clone();
centre.normalize();
centre.mult(_wanderDistance);
Vector2D offset = new Vector2D(0,0);
offset.setLength(_wanderRadius);
offset.setAngle(_wanderAngle);
_wanderAngle += random(-_wanderRange, _wanderRange);
Vector2D force = centre.clone();
force.add(offset);
_steeringForce.add(force);
}
//*** flocking
void flock(Vehicle[]Vehicles)
{
Vector2D averageVelocity = _velocity.clone();
Vector2D averagePosition = new Vector2D();
int inSightCount = 0;
for(int v = 0; v < Vehicles.length; v++)
{
if(Vehicles[v] != this && inSight(Vehicles[v]))
{
averageVelocity.add(Vehicles[v]._velocity);
averagePosition.add(Vehicles[v]._position);
if(tooClose(Vehicles[v])) flee(Vehicles[v]._position);
inSightCount++;
}
}
if(inSightCount > 0)
{
averageVelocity.div(inSightCount);
averagePosition.div(inSightCount);
seek(averagePosition);
averageVelocity.sub(_velocity);
_steeringForce.add(averageVelocity);
}
}
Boolean inSight(Vehicle vehicle)
{
if(_position.distV(vehicle._position) > _inSightDist) return false;
Vector2D heading = _velocity.clone();
heading.normalize();
Vector2D difference = vehicle._position.clone();
difference.sub(_position);
float dotProd = difference.dot(heading);
if(dotProd < 0) return false;
return true;
}
Boolean tooClose(Vehicle vehicle)
{
return _position.distV(vehicle._position) < _tooCloseDist;
}
void setInSightDist(float value)
{
_inSightDist = value;
}
float getInSightDist()
{
return _inSightDist;
}
void setTooCloseDist(float value)
{
_tooCloseDist = value;
}
float getTooCloseDist()
{
return _tooCloseDist;
}
}
class Vector2D extends PVector
{
Vector2D()
{
}
Vector2D(float x, float y)
{
super(x, y);
}
Vector2D clone()
{
return new Vector2D(x, y);
}
//*** zero and isZero
Vector2D zero()
{
x = 0;
y = 0;
return this;
}
Boolean isZero()
{
return x == 0 && y == 0;
}
//*** sets/gets length
void setLength(float someLength)
{
float a = getAngle();
x = cos(a) * someLength;
y = sin(a) * someLength;
}
float getLength()
{
return sqrt(x*x + y*y);
}
//*** sets/gets angle
void setAngle(float someAngle)
{
float len = getLength();
x = cos(someAngle) * len;
y = sin(someAngle) * len;
}
float getAngle()
{
return atan2(y, x);
}
//*** nomalise and isNormalised
// normalise = PVector.normalize()
Boolean isNormalised()
{
float diff = getLength() - 1.0;
if ((diff < 0.00001) && (diff >= 0.0)) return true;
if ((diff > - 0.00001) && (diff <= 0.0)) return true;
return false;
}
//*** sign
//is second vector to the right (+1) or left (-1)
//of current vector
int sign(Vector2D v2)
{
return perp().dot(v2) < 0 ? -1 : 1;
}
//*** perpendicular vector
Vector2D perp()
{
return new Vector2D(-y, x);
}
//*** isEqual
Boolean equal(Vector2D v2)
{
return (x == v2.x) && (y == v2.y);
}
//*** distance to second vector2d
float distV(Vector2D v2)
{
float dx = x - v2.x;
float dy = y - v2.y;
return sqrt(dx*dx + dy*dy);
}
}
class Vehicle
{
Vector2D _position;
Vector2D _velocity;
float _x, _y, _rotation;
float _maxSpeed = 2;
float _mass = 1.0;
float _bounce = -1;
String WRAP = new String("wrap");
String BOUNCE = new String("bounce");
String _edgeBehaviour = BOUNCE;
Vehicle()
{
}
Vehicle(Vector2D _position, Vector2D _velocity)
{
this._position = _position;
this._velocity = _velocity;
}
void update()
{
_velocity.limit(_maxSpeed);
_position.add(_velocity);
if(_edgeBehaviour.equals(WRAP)) wrapWalls();
else if(_edgeBehaviour.equals(BOUNCE)) bounceWalls();
display();
}
void display()
{
// image(fishy, _position.x, _position.y);
stroke(255);
noStroke();
pushMatrix();
translate(_position.x, _position.y);
rotate(_velocity.getAngle());
fill(0, 255, 255);
ellipse(0, 0, 20, 10);
beginShape(TRIANGLES);
vertex(5, 0);
vertex(-5, 10);
vertex(-5, -10);
endShape();
beginShape(TRIANGLES);
vertex(-5, 0);
vertex(-15, 5);
vertex(-15, -5);
endShape();
fill(0);
ellipse(5, 0, 3, 3);
popMatrix();
}
// set/get edgeBehaviour wrap or bounce
void setEdgeBehaviour(String value)
{
_edgeBehaviour = value;
}
String getEdgeBehaviour()
{
return _edgeBehaviour;
}
void wrapWalls()
{
if(_position.x > width) _position.x = 0;
else if(_position.x < 0) _position.x = width;
if(_position.y > height) _position.y = 0;
else if(_position.y < 0) _position.y = height;
}
void bounceWalls()
{
if(_position.x > width)
{
_position.x = width;
_velocity.x *= _bounce;
}
else if(_position.x < 0)
{
_position.x = 0;
_velocity.x *= _bounce;
}
if(_position.y > height)
{
_position.y = height;
_velocity.y *= _bounce;
}
else if(_position.y < 0)
{
_position.y = 0;
_velocity.y *= _bounce;
}
}
}
// steering behaviour
// Keith Peters - Advanced ActionScript Animation
// converted to processing - allonestring Jan 2010
// converted to fish August 2011
int numVehicles = 37;
SteeredVehicle[]Vehicles = new SteeredVehicle[numVehicles];