Matt Walker
Matt Walker

Reputation: 47

Java 2D Polygon - Polygon Collision Detection

Recently I have been using the Polygon class to create asteroids as well as bullets and a spaceship. I am currently trying to create the collision detection for the program however it appears that the collision detection only works around 1/5 of the time (no pattern appears as to why it works).

Here's the code.. Creating the Polygon:

void renderPoly() {   
    int j;
    int s = sides;
    double r, angle;
    int x, y;

    for (j = 0; j < s; j++) {
        angle = 2 * Math.PI / s * j;
        r = MIN_ROCK_SIZE + (int) (Math.random() * (MAX_ROCK_SIZE - MIN_ROCK_SIZE));
        x = (int) (r * Math.cos(angle));
        y = (int) (r * -Math.sin(angle));

        cOM[0] += x;
        cOM[1] += y;
        pointData[j][0] = x;
        pointData[j][1] = y;
    }

    cOM[0] /= asteroidShape.npoints;
    cOM[1] /= asteroidShape.npoints;

    for (int i = 0; i < asteroidShape.npoints; i++) {
        pointData[i][0] += cOM[0];
        pointData[i][1] += cOM[1];
    }    
}

rotating and moving the polygon:

void move() {    
    int x, y, i;
    //change rotation
    theta += rotVel;

    //change x
    asteroidData[0] += deltaX;

    //change y
    asteroidData[1] += deltaY;

    for (i = 0; i < asteroidShape.npoints; i++) {

        x = (int) (pointData[i][0] * Math.cos(theta) - pointData[i][1] * Math.sin(theta) );
        y = (int) (pointData[i][0] * Math.sin(theta) + pointData[i][1] * Math.cos(theta) );

        asteroidShape.xpoints[i] = x + asteroidData[0];
        asteroidShape.ypoints[i] = y + asteroidData[1];

        asteroidShape.invalidate();
    }
}

check if touching bullet:

    boolean hitBullet(Bullet b) {
    this.asteroidShape.invalidate();
    for (int i = 0; i < b.bulletShape.npoints; i++) 
        if (this.asteroidShape.contains(b.bulletShape.xpoints[i], b.bulletShape.ypoints[i]) )
            return true;

    for (int j = 0; j < this.asteroidShape.npoints; j++)
        if (b.bulletShape.contains(this.asteroidShape.xpoints[j], this.asteroidShape.ypoints[j]) )
            return true;

    return false;

}

(the ship method is the same except the constructor requires a ship object)

as well as the loop that calls it in the 'game' class:

    for (int i = 0; i < aArray.length-1; i++) {
    if (aArray[i] != null) {

        for (int j = 0; j < bArray.length-1; j++) {
            if (bArray[j] != null) {

                if (aArray[i].hitBullet(bArray[j])) {
                    aArray[i] = null;
                    bArray[j] = null;
                    i = aArray.length-1;
                    j = bArray.length-1;
                }

            }
            else {
                i = aArray.length-1;
                j = bArray.length-1;
            }
        }

    }
    else {
        i = aArray.length-1;
    }
}

I have been looking around at alternative solutions such as the Separating Axis Theorem however I do have convex polygons at times and since this method (.contains()) already exists I would like to use it.

Any help would be appreciated, thanks!

Upvotes: 1

Views: 1700

Answers (1)

ControlAltDel
ControlAltDel

Reputation: 35096

The easy way to solve this that I've found is to convert Shapes (in your case Polygon(2D?)) into Areas. You can use Area.intersect(Area) to see if two Areas have collided

Upvotes: 2

Related Questions