Intersection of ellipses

Hi guys. I’m finding this quite a challenge.

The way I have it in this code, any ellipse avoids contact with the others whilst dragging it, which is kind of what I want. However, in order to keep on dragging an ellipse after it comes close to contact, I need to re-set the boolean (mouseReleased), etc. It doesn’t work very nicely and because of all the iterations, it’s rather clumsy whilst dragging.

I would like to be able to drag any of the ellipses freely whilst keeping the mouse pressed, and naturally, avoiding contact with the other ellipses. Also, I don’t want to code the ellipses as instances of an object. Any ideas? Thanks.


ArrayList<PVector> point = new ArrayList();
boolean allow=true;
int i;
int j;

void setup() {
  size(300, 200);
  point.add(new PVector(50, 100));
  point.add(new PVector(100, 100));
  point.add(new PVector(150, 100));
  point.add(new PVector(200, 100));
}

void draw() {
  background(255);

  for (j=0; j<point.size(); j++) {
    fill(255, 0, 0);
    noStroke();
    ellipse(point.get(j).x, point.get(j).y, 20, 20);//red balls
  }//for


  if (mousePressed) {

    for (j=0; j<point.size(); j++) {
      if (dist(mouseX, mouseY, point.get(j).x, point.get(j).y)<20 ) {

        if (allow) {
          point.get(j).x=mouseX;
          point.get(j).y=mouseY;       
        }

        for (i=0; i<point.size(); i++) {
          if (i!=j && dist(mouseX, mouseY, point.get(i).x, point.get(i).y)<22 ) { 
           allow=false;
          }
        }
      }
    }
  }//mousePressed
}//draw



void mouseReleased() {
  allow=true;
}

1 Like

ArrayList<PVector> point = new ArrayList();

// dragging at the moment? 
boolean allow=false;

// if so which ellipse are we dragging?
int foundEllipse=-1; 

void setup() {
  size(300, 200);
  point.add(new PVector(50, 100));
  point.add(new PVector(100, 100));
  point.add(new PVector(150, 100));
  point.add(new PVector(200, 100));
}

void draw() {
  background(255);

  // display ellipses
  fill(255, 0, 0);
  noStroke();
  for (PVector pv : point) {    
    ellipse(pv.x, pv.y, 
      20, 20);//red balls
  }//for

  dragAndDrop();
}//draw

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

void dragAndDrop() {
  if (!allow) {
    return; // leave
  }

  point.get(foundEllipse).x=mouseX;
  point.get(foundEllipse).y=mouseY;

  // check collision 
  for (int i=0; i<point.size(); i++) {
    if (i != foundEllipse && dist(mouseX, mouseY, point.get(i).x, point.get(i).y)<22 ) { 
      allow=false;
    }
  }
}//func 

void mousePressed() {

  // reset 
  allow = false; 

  // search 
  for (int j=0; j<point.size(); j++) {
    if (dist(mouseX, mouseY, point.get(j).x, point.get(j).y)<20 ) {
      allow=true; 
      foundEllipse=j;
      return; // leave here
    }
  }
}//func

void mouseReleased() {
  allow=false;
}//func
//
1 Like

Hi Chrisir,

Thank you for your interest, I tried your version, it’s certainly an improvement, but it still needs the mouse release to allow you to keep dragging the ellipse after contact. Also, sometimes two ellipses make contact and it’s quite difficult to separate them again. I think it’s almost there.

PS. I don’t mind if the dragged ellipse collides and intersects whilst it is being dragged, so long as one can keep on dragging away from the other ellipse, so it’s not hidden underneath.

I see

Chrisir


ArrayList<PVector> point = new ArrayList();

// dragging at the moment? 
boolean allow=false;

boolean firstTime=false;

// if so which ellipse are we dragging?
int foundEllipse=-1; 

void setup() {
  size(300, 200);
  point.add(new PVector(50, 100));
  point.add(new PVector(100, 100));
  point.add(new PVector(150, 100));
  point.add(new PVector(200, 100));

  //ellipseMode(CENTER);
}

void draw() {
  background(255);

  // display ellipses
  fill(255, 0, 0);
  noStroke();
  for (PVector pv : point) {    
    ellipse(pv.x, pv.y, 
      20, 20);//red balls
  }//for

  dragAndDrop();
}//draw

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

void dragAndDrop() {
  if (!allow) {
    return; // leave
  }

  // check collision
  boolean foundOne=false; // did we find any collision? Then don't allow pos change!!!  
  for (int i=0; i<point.size(); i++) {
    if (i != foundEllipse ) {
      if (dist(mouseX, mouseY, point.get(i).x, point.get(i).y) < 20) {
        foundOne=true;
      }
    }
  }
  if (!foundOne||firstTime) {
    point.get(foundEllipse).x=mouseX;
    point.get(foundEllipse).y=mouseY;
    firstTime=false;
  }
}//func 

void mousePressed() {

  // reset 
  allow = false; 

  // search 
  for (int j=0; j<point.size(); j++) {
    if (dist(mouseX, mouseY, point.get(j).x, point.get(j).y)<20 ) {
      allow=true; 
      foundEllipse=j;
      firstTime=true; 
      return; // leave here
    }
  }
}//func

void mouseReleased() {
  allow=false;
}//func
//
1 Like

Hi Chrisir,

That’s more like it! Thank you, this works. I’m going to test it for a while, but it appears to do what the doctor ordered! Thanks again.
Edward

1 Like

And a shortened version of your code if you don’t mind the ellipses colliding, but just want to reposition them.


ArrayList<PVector> point = new ArrayList();


int foundEllipse; 

void setup() {
  size(300, 200);
  point.add(new PVector(50, 100));
  point.add(new PVector(100, 100));
  point.add(new PVector(150, 100));
  point.add(new PVector(200, 100));
}

void draw() {
  background(255);

  // display ellipses
  fill(255, 0, 0);
  noStroke();
  for (PVector pv : point) {    
    ellipse(pv.x, pv.y, 
      20, 20);
  }//for


  if (mousePressed) {

    if (dist(mouseX, mouseY, point.get(foundEllipse).x, point.get(foundEllipse).y) < 20) {
      point.get(foundEllipse).x=mouseX;
      point.get(foundEllipse).y=mouseY;
    }
  }//mousePressed
}//draw




void mousePressed() {

  for (int j=0; j<point.size(); j++) {
    if (dist(mouseX, mouseY, point.get(j).x, point.get(j).y)<20 ) {
      foundEllipse=j;
    }
  }
}

1 Like

Just a note – this thread is about the intersection of circles, which you can draw with ellipse(x, y, r, r);

The collision check works for regular circles specifically. So, x and y radius are equal, and collision check is distance from the center – the circle radius

Collision between an axis-aligned ellipse and a circle is harder. Axis-aligned ellipse-ellipse collision detection is much harder. Ellipse-ellipse collision detection in the general case (allowing rotation) is a nightmare.

1 Like