How to display blob (tracking color) size (x,y) to use for collision with another object?

Hi, Totalely NOOB Asking:

I took some code from Train coding that fits an idea I have in head.

How can I Interact the ellipse with the blob zone (that appears on click with color picking (color tracking)

For now, there’s an interaction with the pointer…

Please be kind with me :wink:

My code below:

// Daniel Shiffman
// http://codingtra.in
// http://patreon.com/codingtrain
// Code for: https://youtu.be/r0lvsMPGEoY

import processing.video.*;

Capture video;

int blobCounter = 0;

int maxLife = 200;

color trackColor; 
float threshold = 40;
float distThreshold = 50;

//circle
float px =     0;      // point position
float py =     0;

float cx =     300;    // circle center position
float cy =     200;
float radius = 100;    // circle's radius
float cxspeed = 2.5;
float cyspeed = 2;

//endcircle

//square
float bx =     0;      // point position blob
float by =     0;

ArrayList<Blob> blobs = new ArrayList<Blob>();

void setup() {
  size(640, 480);
  video = new Capture(this, 640, 480, 30);
  video.start();
  trackColor = color(183, 12, 83);
  
  
  //circle
  noCursor();
  strokeWeight(20);   // thicker stroke = easier to see
  //endcircle
}

void captureEvent(Capture video) {
  video.read();
}

void keyPressed() {
  if (key == 'a') {
    distThreshold+=5;
  } else if (key == 'z') {
    distThreshold-=5;
  }
  if (key == 's') {
    threshold+=5;
  } else if (key == 'x') {
    threshold-=5;
  }
}

void draw() {
  video.loadPixels();
  image(video, 0, 0);
 
 //circle
  // update point position to mouse coordinates
  px = mouseX;
  py = mouseY;
  
  //square


    // Add the current speed to the position.
  cx = cx + cxspeed;
  cy = cy + cyspeed;

  if ((cx > width) || (cx < 0)) {
    cxspeed = cxspeed * -1;
  }
  if ((cy > height) || (cy < 0)) {
    cyspeed = cyspeed * -1;
  }

  // check for collision!
 /* boolean hit = pointCircle(px,py, cx,cy, radius);


  // draw circle
  // change fill color if hit
  if (hit) {
    fill(255,150,0);
  }
  else {
    fill(0,150,255);
  }*/
    boolean hits = blobSquare(bx,by, cx,cy, radius);
if (hits) {
    fill(255,150,0);
  }
  else {
    fill(0,150,255);
  }
  


  noStroke();
  ellipse(cx,cy, radius*2,radius*2);

  // draw the point
  stroke(0);
  point(px, py);
  
  //endcircle
  
  ArrayList<Blob> currentBlobs = new ArrayList<Blob>();

  // Begin loop to walk through every pixel
  for (int x = 0; x < video.width; x++ ) {
    for (int y = 0; y < video.height; y++ ) {
      int loc = x + y * video.width;
      // What is current color
      color currentColor = video.pixels[loc];
      float r1 = red(currentColor);
      float g1 = green(currentColor);
      float b1 = blue(currentColor);
      float r2 = red(trackColor);
      float g2 = green(trackColor);
      float b2 = blue(trackColor);

      float d = distSq(r1, g1, b1, r2, g2, b2); 

      if (d < threshold*threshold) {

        boolean found = false;
        for (Blob b : currentBlobs) {
          if (b.isNear(x, y)) {
            b.add(x, y);
            found = true;
            break;
          }
        }

        if (!found) {
          Blob b = new Blob(x, y);
          currentBlobs.add(b);
        }
      }
    }
  }

  for (int i = currentBlobs.size()-1; i >= 0; i--) {
    if (currentBlobs.get(i).size() < 500) {
      currentBlobs.remove(i);
    }
  }

  // There are no blobs!
  if (blobs.isEmpty() && currentBlobs.size() > 0) {
    println("Adding blobs!");
    for (Blob b : currentBlobs) {
      b.id = blobCounter;
      blobs.add(b);
      blobCounter++;
    }
  } else if (blobs.size() <= currentBlobs.size()) {
    // Match whatever blobs you can match
    for (Blob b : blobs) {
      float recordD = 1000;
      Blob matched = null;
      for (Blob cb : currentBlobs) {
        PVector centerB = b.getCenter();
        PVector centerCB = cb.getCenter();         
        float d = PVector.dist(centerB, centerCB);
        if (d < recordD && !cb.taken) {
          recordD = d; 
          matched = cb;
        }
      }
      matched.taken = true;
      b.become(matched);
    }

    // Whatever is leftover make new blobs
    for (Blob b : currentBlobs) {
      if (!b.taken) {
        b.id = blobCounter;
        blobs.add(b);
        blobCounter++;
      }
    }
  } else if (blobs.size() > currentBlobs.size()) {
    for (Blob b : blobs) {
      b.taken = false;
    }


    // Match whatever blobs you can match
    for (Blob cb : currentBlobs) {
      float recordD = 1000;
      Blob matched = null;
      for (Blob b : blobs) {
        PVector centerB = b.getCenter();
        PVector centerCB = cb.getCenter();         
        float d = PVector.dist(centerB, centerCB);
        if (d < recordD && !b.taken) {
          recordD = d; 
          matched = b;
        }
      }
      if (matched != null) {
        matched.taken = true;
        // Resetting the lifespan here is no longer necessary since setting `lifespan = maxLife;` in the become() method in Blob.pde
        // matched.lifespan = maxLife;
        matched.become(cb);
      }
    }

    for (int i = blobs.size() - 1; i >= 0; i--) {
      Blob b = blobs.get(i);
      if (!b.taken) {
        if (b.checkLife()) {
          blobs.remove(i);
        }
      }
    }
  }

  for (Blob b : blobs) {
    b.show();
  } 




  textAlign(RIGHT);
  fill(0);
  //text(currentBlobs.size(), width-10, 40);
  //text(blobs.size(), width-10, 80);
  textSize(24);
  text("color threshold: " + threshold, width-10, 50);  
  text("distance threshold: " + distThreshold, width-10, 25);
}


float distSq(float x1, float y1, float x2, float y2) {
  float d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
  return d;
}


float distSq(float x1, float y1, float z1, float x2, float y2, float z2) {
  float d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) +(z2-z1)*(z2-z1);
  return d;
}

void mousePressed() {
  // Save color where the mouse is clicked in trackColor variable
  int loc = mouseX + mouseY*video.width;
  trackColor = video.pixels[loc];
  println(red(trackColor), green(trackColor), blue(trackColor));
}

void mouseClicked() {
}
/*
//circle
// POINT/CIRCLE

boolean pointCircle(float px, float py, float cx, float cy, float r) {

  // get distance between the point and circle's center
  // using the Pythagorean Theorem
  float distX = px - cx;
  float distY = py - cy;
  float distance = sqrt( (distX*distX) + (distY*distY) );

  // if the distance is less than the circle's
  // radius the point is inside!
  if (distance <= r) {
    return true;
  }
  return false;
}
//endcircle
*/
//square
boolean blobSquare(float bx, float by, float cx, float cy, float r) {

  // get distance between the blob and circle's center
  // using the Pythagorean Theorem
  float distX = bx - cx;
  float distY = by - cy;
  float distance = sqrt( (distX*distX) + (distY*distY) );

  // if the distance is less than the circle's
  // radius the point is inside!
  if (distance <= r) {
    return true;
  }
  return false;
}

To be more precise, i want that circle changes color (or state) when it hits the blob square zone

So here, I’m looking to define bx and by as any Blob width and any Blob height…

If you need the BLOB Part :
slight_smile:`// Daniel Shiffman
// http://codingtra.in
// The Coding Train | creating Creative Coding Videos! | Patreon
// Code for: https://youtu.be/o1Ob28sF0N8

class Blob {
float minx;
float miny;
float maxx;
float maxy;

int id = 0;

int lifespan = maxLife;

boolean taken = false;

Blob(float bx, float by) {
minx = bx;
miny = by;
maxx = bx;
maxy = by;
}

boolean checkLife() {
lifespan–;
if (lifespan < 0) {
return true;
} else {
return false;
}
}

void show() {
stroke(0);
fill(255, lifespan);
strokeWeight(10);
rectMode(CORNERS);
rect(minx, miny, maxx, maxy);

textAlign(CENTER);
textSize(32);
fill(0);
text(id, minx + (maxx-minx)*0.5, miny + (maxy-miny)*0.5+10);
textSize(16);
//text(lifespan, minx + (maxx-minx)*0.5, miny - 10);

}

void add(float bx, float by) {
minx = min(minx, bx);
miny = min(miny, by);
maxx = max(maxx, bx);
maxy = max(maxy, by);
}

void become(Blob other) {
minx = other.minx;
maxx = other.maxx;
miny = other.miny;
maxy = other.maxy;
lifespan = maxLife;
}

float size() {
return (maxx-minx)*(maxy-miny);
}

PVector getCenter() {
float x = (maxx - minx)* 0.5 + minx;
float y = (maxy - miny)* 0.5 + miny;
return new PVector(x, y);
}

boolean isNear(float bx, float by) {

float cx = max(min(bx, maxx), minx);
float cy = max(min(by, maxy), miny);
float d = distSq(cx, cy, bx, by);

if (d < distThreshold*distThreshold) {
  return true;
} else {
  return false;
}

}
}`