How do I make the particles move away from the threshold?

Hello! I’ve asked a similar question tonight but worded it very stupidly and can’t work out how to delete it (apologies! Will work it out).

Basically, I’d like the particles to move away from points of the highest threshold, these values are held in ‘v2.x’ ‘v2.y’ ‘v1.x’ ‘v1.y’

I’m using a Kinect, but I think it’s a really simple issue like I’m missing a loop or something. Could anyone of more experience be of any help with this? I’d appreciate it heaps! I’ve spent hours upon hours doing tutorials etc and I’m really struggling with this. Thank you in advance for any help!

void setup() {
  size(640, 420);
  /////KINECT/////
    kinect = new Kinect(this);
  tracker = new KinectTracker();
  
  smooth();
  particles = new ArrayList<Particle>();
  for (int i = 0; i < num; i++) {
    particles.add(new Particle());
  }
}

void draw() {
  //background(0);

/////KINECT/////
 // Run the tracking analysis
  tracker.track();
  // Show the image
  tracker.display();
  // Let's draw the raw location
  background(0);
  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);


   
  for (Particle p : particles) {
    p.move();
    p.sketch();
    //p.checkMouse();
    
        
  }
float dx = v2.x;
   float  dy = v2.y;
  float px = width / 2;
   float py = height/2;
  //void checkMouse() {
    float mouseRadius = 50;
    float d = dist(v2.x,v2.y, px, py);
    if (d<mouseRadius && d > 1) {
      dx += (px-v2.x) / d*mouseRadius;
      dy += (py-v2.y) / d*mouseRadius;
    }
  }
//}


class Particle {
  float px, py;
  float dx, dy;
  float damp;
  color sc;

  Particle() {
    px = width / 2;
    py = height/2;
    dx = random(width);
    dy = random(height);
    damp = random(0.01, 0.04);
    sc = color(random(100, 255), 0, random(15, 25));
  }

  void move() {
    dx += random(-5, +5);
    dy += random(-5, +5);
    px += (dx - px) * damp;
    py += (dy - py) * damp;
  }

  void sketch() {

    fill(sc, 100);
    noStroke();
    ellipse(px, py, 20, 20);
  }

---------------------------------------------------------------------
// Tab 2 for the Kinect Tracking!
// Daniel Shiffman
// Tracking the average location beyond a given depth threshold
// Thanks to Dan O'Sullivan

// https://github.com/shiffman/OpenKinect-for-Processing
// http://shiffman.net/p5/kinect/

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;
  }
}



1 Like

Hey,

I found this in the depth of my archives - it’s from www.openprocessing.org.

Especially rule 4 makes the swarm repel from the mouse.

Mouse pos is given to the function as a PVector parameter.

So you can replace this with your PVector v1 etc. when I’m not mistaken.

(I wonder why there are so many functions OUTSIDE the class. Dunno.)

Chrisir :wink:


/* OpenProcessing Tweak of *@*<a href="http://www.openprocessing.org/sketch/84563*@*" target="_blank" rel="nofollow">http://www.openprocessing.org/sketch/84563*@*</a> */
/* !do not delete the line above, required for linking your tweak if you upload again */
ArrayList<Boid> boids = new ArrayList<Boid>();
int NUM_BOIDS = 200;

int SCREEN_SIZEX ;
int SCREEN_SIZEY ;

final int MAX_SPEED = 6;

//LOWER = STRONGER ATTRACT
final float ATTRACT_STR = 250;

//HIGHER = STRONGER REPEL
final float REPEL_STR = .25;//.75

//LOWER = STRONGER CONFORM
final float CONFORM_STR = 90;

//LOWER = STRONGER MOUSE
final float MOUSE_STR = 5;//5 

//HIGHER = STRONGER EDGE
final float EDGE_STR = .45;

// ------------------------------------------------------------------------------

void setup() {
  size(displayWidth, displayHeight);
  SCREEN_SIZEX  = width;
  SCREEN_SIZEY  = height;

  background(0);

  smooth();

  for (int i = 0; i < NUM_BOIDS; i++) {
    PVector pos = new PVector(random(SCREEN_SIZEX), random(SCREEN_SIZEY), 0);
    PVector vel = new PVector(0, 0, 0);
    boids.add(new Boid(pos, vel));
  }
}

void draw() {
  background(0, 80);
  fill(0, 11);
  //fill(0); 
  noStroke(); 
  // rect(0, 0, width, height);
  fill(222, 222, 1); 

  PVector absCenter = getAbsCenter();
  PVector absAvgVel = getAbsAvgVel();
  PVector mousePos = new PVector(mouseX, mouseY, 0);

  for (Boid boid : boids) {
    PVector pos = boid.getPos();
    PVector vel = boid.getVel();
    //ellipse(pos.x, pos.y, 2, 2);
    render(pos, vel);

    PVector a, b, c, d, e;
    a = rule1(boid, absCenter);
    b = rule2(boid);
    //   b=new PVector(0, 0);
    c = rule3(boid, absAvgVel);
    d = rule4(boid, mousePos);
    e = rule5(boid);
    vel.set(
      vel.x + a.x + b.x + c.x + d.x + e.x, 
      vel.y + a.y + b.y + c.y + d.y + e.y, 
      0);

    if (vel.mag() > MAX_SPEED) {
      /**
       vel.normalize();
       vel = PVector.mult(vel, MAX_SPEED);
       **/
      vel.mult(0.85);
    }
    vel.mult(random(0.99, 1.01));
    pos = PVector.add(pos, vel);
    boid.setPos(pos);
    boid.setVel(vel);
  }
}

// ----------------------------------------------------------------------------------

void render(PVector pos, PVector vel) {
  pushMatrix();
  translate(pos.x, pos.y);
  rotate(atan2(vel.y, vel.x));
  //beginShape();
  //  ellipse(1, 1, 8, 5);   //size of shapes
  stroke(frameCount%255, 222, 2); 
  point(0, 0); 
  // int(random(5, 50));
  // endShape();
  popMatrix();
}

//Attract
PVector rule1(Boid b, PVector absCenter) {
  PVector perCenter = PVector.sub(absCenter, b.getPos());
  perCenter.div(NUM_BOIDS - 1);
  PVector dis = PVector.sub(perCenter, b.getPos());
  if (dis.mag() > ATTRACT_STR / 5) {
    return PVector.div(dis, ATTRACT_STR);
  }
  return new PVector(0, 0, 0);
}

//Repel
PVector rule2(Boid b) {
  PVector vel = new PVector(0, 0, 0);
  for (Boid boid : boids) {
    PVector dis = PVector.sub(b.getPos(), boid.getPos());
    float mag = dis.mag();
    if (mag != 0) {
      mag = REPEL_STR / mag;
      dis.normalize();
      dis.mult(mag);
      vel.add(dis);
    }
  }
  return vel;

  /**
   PVector vel = new PVector(0, 0, 0);
   for(Boid boid:boids) {
   PVector dis = PVector.sub(b.getPos(), boid.getPos());
   if (dis.mag() < REPEL_STR * 10) {
   vel = PVector.add(vel, dis);
   }
   }
   return vel;
   **/
}

//Conform
PVector rule3(Boid b, PVector absAvgVel) {
  PVector perAvgVel = PVector.sub(absAvgVel, b.getVel());
  perAvgVel.div(NUM_BOIDS - 1);
  return PVector.div(perAvgVel, CONFORM_STR);
}

//Mouse
PVector rule4(Boid b, PVector mousePos) {
  PVector dis = PVector.sub(mousePos, b.getPos());
  if (dis.mag() < 150) {
    dis.mult(-1);
    return PVector.div(dis, MOUSE_STR);
  }
  return new PVector(0, 0, 0);
}

//Edge
PVector rule5(Boid b) {
  PVector pos = b.getPos();
  PVector force = new PVector(0, 0, 0);
  if (pos.x < SCREEN_SIZEX * 0.05) {
    force.add(new PVector(EDGE_STR, 0, 0));
  }
  if (pos.x > SCREEN_SIZEX * 0.95) {
    force.add(new PVector(-EDGE_STR, 0, 0));
  }
  if (pos.y < SCREEN_SIZEY * 0.05) {
    force.add(new PVector(0, EDGE_STR, 0));
  }
  if (pos.y > SCREEN_SIZEY * 0.5) {
    force.add(new PVector(0, -EDGE_STR, 0));
  }
  return force;
}

PVector getAbsCenter() {
  float sumX = 0;
  float sumY = 0;
  for (Boid boid : boids) {
    sumX += boid.getPos().x;
    sumY += boid.getPos().y;
  }
  return new PVector(sumX, sumY);
}

PVector getAbsAvgVel() {
  float sumX = 0;
  float sumY = 0;
  for (Boid boid : boids) {
    sumX += boid.getVel().x;
    sumY += boid.getVel().y;
  }
  return new PVector(sumX, sumY);
}

// ========================================================

class Boid {

  PVector position;
  PVector velocity;

  //constr 
  Boid(PVector position, PVector velocity) {
    this.position = position;
    this.velocity = velocity;
  }

  PVector getPos() {
    return position;
  }
  PVector getVel() {
    return velocity;
  }
  void setPos(PVector position) {
    this.position = position;
  }
  void setVel(PVector velocity) {
    this.velocity = velocity;
  }
}//class
//

here is another version where the mouse has not so much influence but some





/* OpenProcessing Tweak of *@*<a href="http://www.openprocessing.org/sketch/84563*@*" target="_blank" rel="nofollow">http://www.openprocessing.org/sketch/84563*@*</a> */
/* !do not delete the line above, required for linking your tweak if you upload again */
ArrayList<Boid> boids = new ArrayList<Boid>();
int NUM_BOIDS = 200;

int SCREEN_SIZEX ;
int SCREEN_SIZEY ;

final int MAX_SPEED = 6;

//LOWER = STRONGER ATTRACT
final float ATTRACT_STR = 250;

//HIGHER = STRONGER REPEL
final float REPEL_STR = .25;//.75

//LOWER = STRONGER CONFORM
final float CONFORM_STR = 90;

//LOWER = STRONGER MOUSE (divided by MOUSE_STR)
final float MOUSE_STR = 5;//5 

//HIGHER = STRONGER EDGE
final float EDGE_STR = .45;

// ------------------------------------------------------------------------------

void setup() {
  size(displayWidth, displayHeight);
  SCREEN_SIZEX  = width;
  SCREEN_SIZEY  = height;

  background(0);

  smooth();

  for (int i = 0; i < NUM_BOIDS; i++) {
    PVector pos = new PVector(random(SCREEN_SIZEX), random(SCREEN_SIZEY), 0);
    PVector vel = new PVector(0, 0, 0);
    boids.add(new Boid(pos, vel));
  }
}

void draw() {
  background(0, 80);
  fill(0, 11);
  //fill(0); 
  noStroke(); 
  // rect(0, 0, width, height);
  fill(222, 222, 1); 

  PVector absCenter = getAbsCenter();
  PVector absAvgVel = getAbsAvgVel();
  PVector mousePos = new PVector(mouseX, mouseY, 0);

  for (Boid boid : boids) {
    PVector pos = boid.getPos();
    PVector vel = boid.getVel();
    //ellipse(pos.x, pos.y, 2, 2);
    ellipse(absCenter.x, absCenter.y, 22, 22);
    render(pos, vel);

    PVector a, b, c, d, e;
    a = rule1(boid, absCenter);
    b = rule2(boid);
    //   b=new PVector(0, 0);
    c = rule3(boid, absAvgVel);
    d = rule4(boid, mousePos);
    e = rule5(boid);
    vel.set(
      vel.x + a.x + b.x + c.x + d.x + e.x, 
      vel.y + a.y + b.y + c.y + d.y + e.y, 
      0);
    // without a 
    vel.set(
      vel.x +  b.x + c.x + d.x + e.x, 
      vel.y +  b.y + c.y + d.y + e.y );      

    if (vel.mag() > MAX_SPEED) {
      /**
       vel.normalize();
       vel = PVector.mult(vel, MAX_SPEED);
       **/
      vel.mult(0.85);
    }
    vel.mult(random(0.99, 1.01));
    pos = PVector.add(pos, vel);
    boid.setPos(pos);
    boid.setVel(vel);
  }//for
}

// ----------------------------------------------------------------------------------

void render(PVector pos, PVector vel) {
  pushMatrix();
  translate(pos.x, pos.y);
  rotate(atan2(vel.y, vel.x));
  //beginShape();
  //  ellipse(1, 1, 8, 5);   //size of shapes
  stroke(frameCount%255, 222, 2); 
  point(0, 0); 
  // int(random(5, 50));
  // endShape();
  popMatrix();
}

// ----------------------------------------------------------------------------------

//Attract
PVector rule1(Boid b, PVector absCenter) {
  PVector perCenter = PVector.sub(absCenter, b.getPos());
  perCenter.div(NUM_BOIDS - 1);
  PVector dis = PVector.sub(perCenter, b.getPos());
  if (dis.mag() > ATTRACT_STR / 5) {
    return PVector.div(dis, ATTRACT_STR);
  }
  return new PVector(0, 0, 0);
}

//Repel
PVector rule2(Boid b) {
  PVector vel = new PVector(0, 0, 0);
  for (Boid boid : boids) {
    PVector dis = PVector.sub(b.getPos(), boid.getPos());
    float mag = dis.mag();
    if (mag != 0) {
      mag = REPEL_STR / mag;
      dis.normalize();
      dis.mult(mag);
      vel.add(dis);
    }
  }
  return vel;

  /**
   PVector vel = new PVector(0, 0, 0);
   for(Boid boid:boids) {
   PVector dis = PVector.sub(b.getPos(), boid.getPos());
   if (dis.mag() < REPEL_STR * 10) {
   vel = PVector.add(vel, dis);
   }
   }
   return vel;
   **/
}

//Conform
PVector rule3(Boid b, PVector absAvgVel) {
  PVector perAvgVel = PVector.sub(absAvgVel, b.getVel());
  perAvgVel.div(NUM_BOIDS - 1);
  return PVector.div(perAvgVel, CONFORM_STR);
}

//Mouse
PVector rule4(Boid b, PVector mousePos) {
  final float allowedDistance=44; //150
  PVector dis = PVector.sub(mousePos, b.getPos());
  if (dis.mag() < allowedDistance) {

    // new 
    //dis.x = map(dis.x, 0, allowedDistance, 0, 12);
    //dis.y = map(dis.y, 0, allowedDistance, 0, 12);

    dis.mult(-1);

    return PVector.div(dis, MOUSE_STR);
  }
  return new PVector(0, 0, 0);
}

//Edge
PVector rule5(Boid b) {
  PVector pos = b.getPos();
  PVector force = new PVector(0, 0, 0);
  if (pos.x < SCREEN_SIZEX * 0.05) {
    force.add(new PVector(EDGE_STR, 0, 0));
  }
  if (pos.x > SCREEN_SIZEX * 0.95) {
    force.add(new PVector(-EDGE_STR, 0, 0));
  }
  if (pos.y < SCREEN_SIZEY * 0.05) {
    force.add(new PVector(0, EDGE_STR, 0));
  }
  if (pos.y > SCREEN_SIZEY) {
    force.add(new PVector(0, -EDGE_STR, 0));
  }
  return force;
}

PVector getAbsCenter() {
  float sumX = 0;
  float sumY = 0;
  for (Boid boid : boids) {
    sumX += boid.getPos().x;
    sumY += boid.getPos().y;
  }
  return new PVector(sumX, sumY);
}

PVector getAbsAvgVel() {
  float sumX = 0;
  float sumY = 0;
  for (Boid boid : boids) {
    sumX += boid.getVel().x;
    sumY += boid.getVel().y;
  }
  return new PVector(sumX, sumY);
}

// ========================================================

class Boid {

  PVector position;
  PVector velocity;

  //constr 
  Boid(PVector position, PVector velocity) {
    this.position = position;
    this.velocity = velocity;
  } //constr 

  PVector getPos() {
    return position;
  }
  PVector getVel() {
    return velocity;
  }
  void setPos(PVector position) {
    this.position = position;
  }
  void setVel(PVector velocity) {
    this.velocity = velocity;
  }
}//class
//