Get bounding box of rotated rectangle.

So, I have a rectangle with a known x, y, width and height.

http://s28.postimg.org/98vuq1cdl/rectangle.png

The top left corner is the x:y coordinate where x is increasing while moving right and y while moving down.

I then rotate it with a known value(the rectangle is rotated around its center point):

http://s28.postimg.org/qng2yb9ih/rotated_rectangle.png

I want to calculate the position of the red dot as well as the new width and height.

Care to elaborate?

  • Jev

Assuming that you know all the vertices, the red dot would be at (min x, min y) (Assuming y-down orientation like you have it). The width would be max x - min x, and the height would be max y - min y.

What are the vertices? I don’t think I have them.

If you construct rotated rectangles with my code, you construct a rectangle with topleft coordinates, dimensions, and rotation angle. Then to get each point you use the functions like x1() and y1(). You can change the angle with angle(float angleInRadians) :slight_smile: To get your minimum/maximum values with my code, do:

float minx = Math.min(Math.min(region.x1(), region.x2()), Math.min(region.x3(), region.x4())); // region is your rotating region object
float miny = Math.min(Math.min(region.y1(), region.y2()), Math.min(region.y3(), region.y4())); // region is your rotating region object
float maxx = Math.max(Math.max(region.x1(), region.x2()), Math.max(region.x3(), region.x4())); // region is your rotating region object
float maxy= Math.max(Math.max(region.y1(), region.y2()), Math.max(region.y3(), region.y4())); // region is your rotating region object
package game.util;

import java.awt.geom.Line2D;

import static org.lwjgl.opengl.GL11.*;

public class RotatingRegion extends Shape {
	
	private Line2D.Float[] lines = new Line2D.Float[4];
	
	public float cx, cy, originalCX, originalCY;
	private float angle;
	private float x, y, width, height;
	
	public RotatingRegion(float x, float y, float width, float height) {
		this(x, y, width, height, 0);
	}
	public RotatingRegion(float x, float y, float width, float height, float angle) {
		cx = x + (width / 2);
		cy = y + (height / 2);
		originalCX = cx;
		originalCY = cy;
		this.angle = angle;
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		build();
		for (Line2D.Float line : lines) {
			addPoint(line.x1, line.y1);
		}
		create();
	}
	
	public float x1() {
		return lines[0].x1;
	}
	public float x2() {
		return lines[1].x1;
	}
	public float x3() {
		return lines[2].x1;
	}
	public float x4() {
		return lines[3].x1;
	}
	
	public float y1() {
		return lines[0].y1;
	}
	public float y2() {
		return lines[1].y1;
	}
	public float y3() {
		return lines[2].y1;
	}
	public float y4() {
		return lines[3].y1;
	}
	
	public float angle() {
		return (float)Math.toDegrees(angle);
	}
	
	public void setCenter(float cx, float cy) {
		this.cx = cx;
		this.cy = cy;
		x = cx - (width / 2);
		y = cy - (height / 2);
		build();
	}
	
	public void angle(float angle) {
		this.angle = angle;
		build();
	}
	
	public void build() {
		float[] point1 = rotateAroundCenter(x, y, angle);
		float[] point2 = rotateAroundCenter(x + width, y, angle);
		float[] point3 = rotateAroundCenter(x + width, y + height, angle);
		float[] point4 = rotateAroundCenter(x, y + height, angle);
		lines[0] = new Line2D.Float(point1[0], point1[1], point2[0], point2[1]);
		lines[1] = new Line2D.Float(point2[0], point2[1], point3[0], point3[1]);
		lines[2] = new Line2D.Float(point3[0], point3[1], point4[0], point4[1]);
		lines[3] = new Line2D.Float(point4[0], point4[1], point1[0], point1[1]);
	}
	
	public float[] rotateAroundCenter(float x, float y, float angle) {
		float dx = x - cx;
		float dy = y - cy;
		float distance = (float) Math.sqrt(dx * dx + dy * dy);
		float originalAngle = getAngle(cx, cy, x, y);
		float newangle = originalAngle + angle;
		float ndx = distance * (float)Math.sin(newangle);
		float ndy = distance * (float)Math.cos(newangle);
		float nx = cx + ndx;
		float ny = cy + ndy;
		return new float[]{ nx, ny };
	}
	
	public boolean intersects(float x, float y) {
		for (int index = 0; index < lines.length; index++) {
			if (lines[index].contains(x, y)) {
				return true;
			}
		}
		return false;
	}
	
	public boolean contains(float x, float y) {
		int intersections = 0;
		Line2D.Float test = new Line2D.Float(x - 1000, y - 1000, x, y);
		for (int index = 0; index < lines.length; index++) {
			if (lines[index].intersectsLine(test)) {
				intersections++;
			}
		}
		return intersections > 0 && intersections % 2 == 1;
	}
	
	public boolean contains(RotatingRegion region) {
		for (int index1 = 0; index1 < region.lines.length; index1++) {
			for (int index = 0; index < lines.length; index++) {
				if (lines[index].intersectsLine(region.lines[index1])) {
					return true;
				}
			}
		}		
		return false;
	}
	
	public static float getAngle(float mousex, float mousey, float playerx, float playery) {
		float deltax = mousex - playerx;
		float deltay = mousey - playery;
		double rawangle = Math.atan2(deltay, deltax);
		float degrees = (float) Math.toDegrees(rawangle);
		degrees += 90.0f; // add 90 so opengl can use it
		if (degrees < 0) {
			degrees += 360.0f; // fix all angles less than 0
		}
		if (degrees > 360.0f) {
			degrees -= 360.0f; // fix all angles more than 360
		}
		degrees %= 360.0f;
		if (degrees > 180.0f) {
			degrees -= 360.0f;
		}
		return (float) Math.toRadians(degrees);
	}

}

Hope this helps :slight_smile:

CopyableCougar4