Lars-Erik Svensson
Lars-Erik Svensson

Reputation: 15

Collision detection on rotated rectangle has wrong angle

I'm trying to make balls collide with rotated rectangles using this code snippet:

for(int i = 0; i < barriers.length; i++) {

            Vector2d tempPos = rotate(pos.getX(), 
                                      pos.getY(), 
                                      barriers[i].getAngle(), 
                                      barriers[i].getCenterX(), 
                                      barriers[i].getCenterY());

            if (
                    tempPos.getX() > barriers[i].getBarrier().left &&
                    tempPos.getY() > barriers[i].getBarrier().top &&
                    tempPos.getX() < barriers[i].getBarrier().right &&
                    tempPos.getY() < barriers[i].getBarrier().bottom  )

            {
                dead = true;
            }

        }
    }
}

Vector2d rotate(float x1, float y1, float angle, float x2, float y2)
{
    sinus   = (float)Math.sin(angle);
    cosinus = (float)Math.cos(angle);

    float tempX = x2 - x1;
    float tempY = y2 - y1;
    x1 += ((tempX * cosinus) - (tempY * sinus));
    y1 += ((tempX * sinus)   + (tempY * cosinus));
    Vector2d point  =  new Vector2d(x1, y1);

    return point;
}

For some reason, even though the math should be correct, the collisions happen at a slightly wrong angle.

Here I set the angle to 45 degrees: Rectangles and collision set to 45 degrees

And here it is set to 90 degrees: Rectangles and collision set to 90 degrees

In the 90 degree picture the angle is even more off, and it looks like the collision box is smaller than it should.

The angle is taken from the Barrier class, which holds the Rect for each rectangle, as well as its angle. It is the same angle that is used when drawing the rectangles using canvas.save->rotate->draw->restore.

The Vector2d class just holds two floats, x and y, and pos holds the x and y for the ball. The ball doesn't have a collision box, just its position.

Edit: the angle in my code snippet is in degrees, but even if I set it to radians using Math.toRadians() I get the same problem.

Collision angle set to Math.toRadians(45)

Upvotes: 0

Views: 196

Answers (1)

Lars-Erik Svensson
Lars-Erik Svensson

Reputation: 15

Ok, so after playing around with it a bit I managed to solve it. Here's my changed code:

Vector2d rotate(float x1, float y1, float angle, float x2, float y2)
    {
        sinus   = (float)Math.sin(Math.toRadians(360 - angle));
        cosinus = (float)Math.cos(Math.toRadians(360 - angle));

        float tempX = x2 - x1;
        float tempY = y2 - y1;
        x2 += ((tempX * cosinus) - (tempY * sinus));
        y2 += ((tempX * sinus)   + (tempY * cosinus));
        Vector2d point  =  new Vector2d(x2, y2);

        return point;
    }

It seems I had to get the inverse angle, and apply the math to the rectangle's x and y, instead of the dot's. Then I return the new x and y to be checked for collision... I'm baffled, but it works!

Upvotes: 0

Related Questions