Collision Detection with Rotated Rectangles

隐身守侯 提交于 2019-12-04 16:53:26

Maybe this is an old question, but I think to have the solution for anyone else that will read this post:

/** Rectangle To Point. */
boolean testRectangleToPoint(double rectWidth, double rectHeight, double rectRotation, double rectCenterX, double rectCenterY, double pointX, double pointY) {
    if(rectRotation == 0)   // Higher Efficiency for Rectangles with 0 rotation.
        return Math.abs(rectCenterX-pointX) < rectWidth/2 && Math.abs(rectCenterY-pointY) < rectHeight/2;

    double tx = Math.cos(rectRotation)*pointX - Math.sin(rectRotation)*pointY;
    double ty = Math.cos(rectRotation)*pointY + Math.sin(rectRotation)*pointX;

    double cx = Math.cos(rectRotation)*rectCenterX - Math.sin(rectRotation)*rectCenterY;
    double cy = Math.cos(rectRotation)*rectCenterY + Math.sin(rectRotation)*rectCenterX;

    return Math.abs(cx-tx) < rectWidth/2 && Math.abs(cy-ty) < rectHeight/2;
}

/** Circle To Segment. */
boolean testCircleToSegment(double circleCenterX, double circleCenterY, double circleRadius, double lineAX, double lineAY, double lineBX, double lineBY) {
    double lineSize = Math.sqrt(Math.pow(lineAX-lineBX, 2) + Math.pow(lineAY-lineBY, 2));
    double distance;

    if (lineSize == 0) {
        distance = Math.sqrt(Math.pow(circleCenterX-lineAX, 2) + Math.pow(circleCenterY-lineAY, 2));
        return distance < circleRadius;
    }

    double u = ((circleCenterX - lineAX) * (lineBX - lineAX) + (circleCenterY - lineAY) * (lineBY - lineAY)) / (lineSize * lineSize);

    if (u < 0) {
        distance = Math.sqrt(Math.pow(circleCenterX-lineAX, 2) + Math.pow(circleCenterY-lineAY, 2));
    } else if (u > 1) {
        distance = Math.sqrt(Math.pow(circleCenterX-lineBX, 2) + Math.pow(circleCenterY-lineBY, 2));
    } else {
        double ix = lineAX + u * (lineBX - lineAX);
        double iy = lineAY + u * (lineBY - lineAY);
        distance = Math.sqrt(Math.pow(circleCenterX-ix, 2) + Math.pow(circleCenterY-iy, 2));
    }

    return distance < circleRadius;
}

/** Rectangle To Circle. */
boolean testRectangleToCircle(double rectWidth, double rectHeight, double rectRotation, double rectCenterX, double rectCenterY, double circleCenterX, double circleCenterY, double circleRadius) {
    double tx, ty, cx, cy;

    if(rectRotation == 0) { // Higher Efficiency for Rectangles with 0 rotation.
        tx = circleCenterX;
        ty = circleCenterY;

        cx = rectCenterX;
        cy = rectCenterY;
    } else {
        tx = Math.cos(rectRotation)*circleCenterX - Math.sin(rectRotation)*circleCenterY;
        ty = Math.cos(rectRotation)*circleCenterY + Math.sin(rectRotation)*circleCenterX;

        cx = Math.cos(rectRotation)*rectCenterX - Math.sin(rectRotation)*rectCenterY;
        cy = Math.cos(rectRotation)*rectCenterY + Math.sin(rectRotation)*rectCenterX;
    }

    return testRectangleToPoint(rectWidth, rectHeight, rectRotation, rectCenterX, rectCenterY, circleCenterX, circleCenterY) ||
            testCircleToSegment(tx, ty, circleRadius, cx-rectWidth/2, cy+rectHeight/2, cx+rectWidth/2, cy+rectHeight/2) ||
            testCircleToSegment(tx, ty, circleRadius, cx+rectWidth/2, cy+rectHeight/2, cx+rectWidth/2, cy-rectHeight/2) ||
            testCircleToSegment(tx, ty, circleRadius, cx+rectWidth/2, cy-rectHeight/2, cx-rectWidth/2, cy-rectHeight/2) ||
            testCircleToSegment(tx, ty, circleRadius, cx-rectWidth/2, cy-rectHeight/2, cx-rectWidth/2, cy+rectHeight/2);
}

This is the code to test Collisions between a circle (The Ball) and a rectangle (That can rotate).

Claudiu

The reason the intersect method doesn't work is because you aren't actually rotating the Rectangle2D. You are telling the graphics context to rotate such that anything it does draw (such as an unrotated Rectangle2D) is drawn rotated, but the actual Rectangle2D instance isn't modified.

Maybe you can use Polyon for the paddles, instead of Rectangle2D, and rotate them as in this answer. That way the actual instance will be rotated (so you won't need to rotate your Graphics2D instance) and collision detection should work properly.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!