1
\$\begingroup\$

I created my circle vs. rectangle method based on this algorithm:

https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection

Currently, I have a dynamic ball with velocities c1SpeedX (for X axis) and c1SpeedY (Y axis). The dynamic ball is supposed to bounce off of the static rectangle when a collision occurs.

The boolean method that I use to detect if the intersection happened is the following:

        public boolean intersects (Circle circle, Rectangle rectangle) {
            double dx = Math.abs(circle.getLayoutX() - rectangle.getLayoutX());
            double dy = Math.abs(circle.getLayoutY() - rectangle.getLayoutY());

            if (dx > rectangle.getWidth() / 2 + circle.getRadius()) {
                return false;
            }
            if (dy > rectangle.getHeight() / 2 + circle.getRadius()) {
                return false;
            }

            if (dx <= rectangle.getWidth() / 2) {
                return true;
            }
            if (dy <= rectangle.getHeight() / 2) {
                return true;
            }
            double cornerX = (dx - rectangle.getWidth() / 2) * (dx - rectangle.getWidth() / 2);
            double cornerY = (dy - rectangle.getHeight() / 2) * (dy - rectangle.getHeight() / 2);

            double cornerDistance = cornerX + cornerY;
            double radii = circle.getRadius() * circle.getRadius();

            return cornerDistance <= radii;

        }

Once a collision has happened, my natural response would be to invert the values of X and Y, so the ball bounces off of the rectangle. The problem is that it's incredibly inaccurate, and the ball often goes through the rectangle without detecting a collision.

if (intersects(circle1, rect1)) {
                    c1SpeedX = c1SpeedX * -1;
                    c1SpeedY = c1SpeedY * -1;
                }

So, how do I optimize my code to make the ball always accurately bounce off of the rectangle? Is it a velocity problem, or is something wrong with the intersects method?

Thanks.

\$\endgroup\$
3
\$\begingroup\$

Hi and thanks for your questions.

If your collision is not detected there are 3 obvious problems that could happen.

First your ball is moving to fast or your collision detection time interval is to low. This causes the ball to appear once in front and after behind the rectangle. To solve this simply interpolate over the last translation of your object and check each time for a collision. This is anyway a good point because it improves the precision of your collision detection. More can be read online.

Second your algorithm of collision detection does not work correctly. To prove this you should first give your variables meaningful names this helps you and us to understand your code faster and probably.

static bool rectangleIntersectsCircle(Rectangle rectangle, Circle circle)
{
  Point closestPointToCircle = circle.midPoint();

  if( closestPointToCircle.x() > rectangle.right() ) closestPointToCircle.setX( rectangle.right() );
  else if( closestPointToCircle.x() < rectangle.left() ) closestPointToCircle.setX( rectangle.left() );

  if( closestPointToCircle.y() > rectangle.bottom() ) closestPointToCircle.setY( rectangle.bottom() );
  else if( closestPointToCircle.y() < rectangle.top() ) closestPointToCircle.setY( rectangle.top() );

  return point_distance( closestPointToCircle, circle.midPoint() ) <= circle.radiant();
}

I did not really look for mistakes in code because im not familiar with java and the method naming confused me. Whatever it is important to check each side unless you do not check the relative position of the objects before. Especially the corner test seems wrong to me because you did not test all of them.

The third problem I could think of is that maybe the coordinate system of the objects given to the intersect method are not the same that are used to render them.

The second question about velocity and smoothness is more about detecting the best fitting collision point and calculate the reflecting vector. Anyway this gives you only the direction. Calculating speed and velocity gets more complicated and is based on the physical properties of your objects material. If you explain more what kind of physical reaction you want I can try to explain more, better make a new question because these are 2 different topics.

I hope I could help you. If you have further questions just tell us.

Michael

\$\endgroup\$
  • \$\begingroup\$ As far as I can tell, his variables are named properly - dx and dy mean change in x and y, respectively. Also, it's radius and not radiant. Other than that, welcome to GD.SE! \$\endgroup\$ – Polar Nov 27 '13 at 0:46
  • \$\begingroup\$ Sadly this is not working for me. Can you please give me another source code example in JavaFX? I still +1'd for the kind response, though :) \$\endgroup\$ – Gregg1989 Nov 27 '13 at 16:23
  • \$\begingroup\$ i reworked the algorithm and tested it in qt anyway i am not familiar with any java api, sorry for that. Maybe you can translate it. Pay attention that the coordinate system y-axis is flipped in ui systems. \$\endgroup\$ – NjamNjam Nov 28 '13 at 12:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.