Search code examples
javatrigonometryatan2

Using atan2() to find the intersection point of objects in a Brick Breaker game


I am looking at a source code of a brick breaker game created by r3ticuli(an user of GitHub). The below method checks whether two objects intersect each other or not, and if they do, the method checks and returns which part of the main object is touched by the other.

The method is part of GameObject class (paddle, brick, and ball are all sub-classes of this class) The class object's x and y coordinates start at the object's upper left corner. The programmer, who made this code, only calls this method with paddle or brick and passes ball as an argument in main method.

I spent two days to understand how this logic works. I understand that the variable theta calculates the angle of vector between two objects' centers. However, I can not understand what is the purpose of the variable, diagTheta, and how the method determines which part of the object is interconnected to the other.

Thank you for your support. *If my question has a problem, I'll fix it.

/**
 * Compute whether two GameObjects intersect.
 * 
 * @param other
 *            The other game object to test for intersection with.
 * @return NONE if the objects do not intersect. Otherwise, a direction
 *         (relative to <code>this</code>) which points towards the other
 *         object.
 */
public Intersection intersects(GameObject other) {
    if (       other.x > x + width
            || other.y > y + height
            || other.x + other.width  < x
            || other.y + other.height < y)
        return Intersection.NONE;

    // compute the vector from the center of this object to the center of
    // the other
    double dx = other.x + other.width /2 - (x + width /2);
    double dy = other.y + other.height/2 - (y + height/2);

    double theta = Math.atan2(dy, dx); // In here, theta means the angle between objects. from original to the other object (center to center).
    double diagTheta = Math.atan2(height, width); // This is angle from (x,y) to its opposite tip side of the shape. 

  if ( -diagTheta <= theta && theta <= diagTheta )
        return Intersection.RIGHT;
    if ( diagTheta <= theta && theta <= Math.PI - diagTheta )
        return Intersection.DOWN;
    if ( Math.PI - diagTheta <= theta || theta <= diagTheta - Math.PI )
        return Intersection.LEFT;
    // if ( diagTheta - Math.PI <= theta && theta <= diagTheta)
    return Intersection.UP;
}

Solution

  • In this picture, (dx dy) is the RED arrow and it points from this to the other. And (width, height) is the blue arrow, which is the diagonal of this. The atan2 function will return the angle of the arrow, from -pi to +pi, where zero is pointing right, positive up, negative down.

    In the picture you can see that the blue arrow is more positive that the red arrow, i.e it is closer to pi. Therefore diagTheta is about 2.9 and theta is about 2.5. Does that make sense?

    When you run through the logic, you can see it returns UP, which is to say that other box is above this box.

    As you move the other box to different locations, the RED arrow will change, and you get different theta values. Try out several possibilities and confirm for yourself that the logic returns the correct result.

    atan2