Ellipse moving in rectangular shape

Hi there!
The solution is probably right in front of me, but I’m struggling with my code.

I have an ellipse that are meant to move in a rectangular shape, from top right (x0, y0) > bottom right (x1, y1) > diagonal bottom left (x2, y2) > top left (x3, y3) > top right (in a loop).

I’m currently stuck in the bottom left position, with the ellipse disappearing when it hits the x2, y2 coordinates, instead of moving upwards. It seems that the first two blocks of if’s are working, but the error hits at the third block.

float x0 = 630;
float y0 = 165;
float x1 = 630;
float y1 = 609.5;
float x2 = 165;
float y2 = 880;
float x3 = 165;
float y3 = 165;
float speed = 5;

float circleX = x0;
float circleY = y0;

// ellipse movement

if (((circleY >= y0) && (circleY <= y1)) && (circleX == x0)) {
    circleX = x0;
    circleY = circleY + speed;
    ellipse(circleX, circleY, 230, 230);
  }

  if (((circleY >= y1) && (circleY <= y2)) && ((circleX >= x2) && (circleX <= x1))) {    
    circleX = circleX-speed;
    circleY = circleY + 0.6*speed;
    ellipse(circleX, circleY, 230, 230);
  }

  if (((circleY <= y2) && (circleY >= y3)) && (circleX == x2)) {
    circleX = x2;
    circleY = circleY-speed;
    ellipse(circleX, circleY, 230, 230);
  }

  if (((circleX >= x3) && (circleX <= x0)) && (circleY == y0)) {
    circleY = y3;
    circleX = x3 + speed;
    ellipse(circleX, circleY, 230, 230);
  }

I hope that someone can help me figuring out the solution!
Kind regards,
Cathrine

equality testing with floats is different to integers and you probably have some rounding you need to do to get it to work. as you didn’t post a runnable sample i didn’t test it but i would saying the way you are calculating when the ellipse has arrived at a point on its path is not the best approach and you would probably be better off testing if your ellipse is withing a certain distance of the point with some circle intersection testing. personally i’d do something like the below as you can customise the path shape and control the behaviour of the ellipsed with some simple tweaks to the arrival behaviour.

this is just based on the nature of code - autonomous agents example

ZoomZoom zoomie;

void setup() {
  size(512, 512, P2D);
  
  zoomie = new ZoomZoom(width / 2, height / 2, 128, 4);
}

void draw() {
  background(0);
  zoomie.update();
  zoomie.present();
}

class ZoomZoom
{
  PVector pos, vel, acc;
  float maxSpeed = 4;
  int target;
  PVector[] pathNodes;
  float radius = 32;
  boolean pathVisible = true;
  
  public ZoomZoom(float pathX, float pathY, float pathRadius, int pathSides) {
    pathSides = Math.max(3, pathSides);
    pathNodes = new PVector[pathSides];
    float stepSize = TWO_PI / pathSides;
    float angle = 0;
    for(int i = 0; i < pathSides; i++, angle += stepSize) {
      pathNodes[i] = new PVector(pathX + pathRadius * sin(angle), pathY + pathRadius * cos(angle));
    }
    pos = new PVector(pathNodes[0].x, pathNodes[0].y);
    vel = new PVector();
    acc = new PVector();
    target = 1;
  }
  
  private void applyForce(PVector force) {
    acc.add(force);
  }
  
  public void update() {
    vel.add(acc);
    acc.mult(0);
    pos.add(vel);
    
    PVector desired = PVector.sub(pathNodes[target], pos);
    float dist = desired.mag();
    desired.normalize();
    
    if(dist < 5) {
      desired.mult(map(dist, 0, 5, 0, maxSpeed));
      target = (target + 1) % pathNodes.length;
    }
    else {
      desired.mult(maxSpeed);
    }
    
    applyForce(desired.sub(vel));
  }
  
  public void present() {
    stroke(255);

    if(pathVisible) {
      for(int i = 0; i < pathNodes.length; i++) {
        PVector p1 = pathNodes[i];
        PVector p2 = pathNodes[(i + 1) % pathNodes.length];
        
        line(p1.x, p1.y, p2.x, p2.y);
      }
    }
    
    noStroke();
    fill(255);
    ellipse(pos.x, pos.y, radius, radius);
  }
}
1 Like

Ah, alright! I’ll look into that - thanks a lot!