Daymnn
Daymnn

Reputation: 229

Collision between two shape

I was working on an animation on processing.
But, I have a question about the code below:

So, you can see on the output, the ball is going everywhere on the window. I want to make a barrier for the ball. The ball can pass from the middle but if it hit the line it goes somewhere with the speed of (int)random(1, 3).

How to make that?
Here is a picture of what I would like to achieve:

Upvotes: 1

Views: 161

Answers (3)

Laos Los
Laos Los

Reputation: 176

For your toy model, the easiest way to handle collisions is considering a collision zone. So,

  1. Establish the collision zone limits x1, x2, y1, y2. When the center of the ball enters this zone, collision rules apply.
  2. Consider elastic collisions: your ball only collides with an horizontal line, so only the vertical component of the velocity can be affected, and it never looses speed.
  3. Consider to test your toy model with a good bunch of initial conditions, so you can discover any artifacts due to the smallness of your model, the values you are using, and so on. (I have modified the initial position of the ball for a random initial position, run the model several times to see how it behaves under different initial conditions).
int dirX = (int)random(1, 3);
int dirY = (int)random(1, 3);
//int x = 20, y = 20;
int middle = 20;

int x = (int)random(20, 180);
int y = (int)random(20, 80);
int x1, x2, y1, y2;

void setup() {
  size(200,200);
  // collision zone limits
  x1 = (width/2 - middle) + 20/2 - 1; // 89
  x2 = (width/2 + middle) - 20/2 + 1; // 111
  y1 = height/2 - 20/2 + 1; // 91
  y2 = height/2 + 20/2 - 1; // 109
}

void draw() {
  background(255);
  ellipse(x, y, 20, 20);
  line(0, height/ 2, width/2 - middle, height/2); // (0, 100, 80, 100)
  line(width/2 + middle, height/2, width, height/2); // (120, 100, 200, 100)
  
  x += dirX;
  y += dirY;

  if (x > width || x < 0)
    dirX *= -1;
  if (y > height || y < 0)
    dirY *= -1;

  if ((x < x1 && y > y1 && y < height/2 && dirY > 0) || // upper left and going down
      (x < x1 && y > height/2 && y < y2 && dirY < 0) || // lower left and going up
      (x > x2 && y > y1 && y < height/2 && dirY > 0) || // upper right and going down
      (x > x2 && y > height/2 && y < y2 && dirY < 0))   // lower right and going up
    dirY *= -1;
}

For a more complex model, you could consider more sophisticated situations as, for example, the backwards collision due to the ends of the lines, the collision of the contour of the ball with the lines, etc.

Upvotes: 1

Maarten Veerman
Maarten Veerman

Reputation: 1621

I'm not going to write code, but I'll tell you how to calculate it, it's not that hard.

Taken a circle, we know the center and the radius.

Taken a line we know the startpoint and endpoint.

  1. The line intersects the circle if the distance from them center to startpoint or endpoint is smaller than radius (e.g. point is inside circle)
  2. A line intersects circle if startpoint X is on the left of center (sX < cX), endpoint X on the right (eX > cX), and the distance between their Y and the center Y is less than radius (cY - sY < r)

Note that this really applies only in your simple case with a horizontal line. Normally is better to really work with vectors calculations to determine distance from center to line for example. That would allow you to work with diagonal lines etc.

Upvotes: 2

mankowitz
mankowitz

Reputation: 2051

One way to do this is to check for collision when the ball passes through the middle, specifically when the ball's velocity would make y pass from < height/2 to > height/2.

Something like this:

if (((y < height/2 && y+dirY > height/2) || (y > height/2 && y+dirY < height/2)) && (x < width/2-middle || x > width/2+middle)){
   dirY = (int) random (1,3);
   dirX = (int) random (1,3);
}

(A more appropriate solution would be to create the collision when the edge of the ball passes the barrier, but I'll leave that up to you)

Upvotes: 3

Related Questions