
Find four points of rotated rectangle
Hello. Been searching for this, but the amount of rectangle related questions make it hard to find the answer I'm looking for.
Anyway, I would like to draw 4 lines making a rectangle based on a given width, height, center point, and rotation.
So if I give the program say a 0,0 center point, a width and height of 5, and a rotation of 0, then it would draw four lines like so:
2,2 > 2,2
2,2 > 2,2
2,2 > 2,2
2,2 > 2,2
(think that's right!)
But yea, hope you get the basic idea. For me it gets real complicated once you add in rotation and such. For my program I will need all 4 points of the rectangle as I have a collision detection that is based colliding with lines...so four lines for each rectangle.
Thanks!

to define the points generally given rotation, you transform the local coordinates you've defined (would be 2.5 in your example though!):
Code:
transformedX = x * cos( theta )  y * sin( theta )
transformedY = x * sin( theta ) + y * cos( theta )
where theta is your rotation in radians (radians = degrees * pi / 180). you can do a search for "2d rotation matrix" to get a background on the math.
so, if you had a method for getting the top left point of the rectangle only, it would look like this:
Code:
function getTopLeft( width:Number, height:Number, theta:Number ) : Point
{
//half width and height directed appropriately (for top left)
var hw:Number = width / 2;
var hh:Number = height / 2;
var cos:Number = Math.cos( theta );
var sin:Number = Math.sin( theta );
return new Point( hw * cos  hh * sin, hw * sin + hh * cos );
}
This is obviously very specific and you probably want to handle the problem generally instead, but i thought this would illustrate the solution to the purely mathematical end of it the algorithm's design should be application specific.

Hey, thanks for the response! Math is not my strong point (although I code actionscript daily!) so I'm not completely following your solution...
I started trying to punch this into my program, then realized I still couldn't plot the points for my rectangle.
I see how you use a transformedX and Y, but don't understand how to work that into the code. The function you have (getTopLeft) does not ask for an x or y coordinate so I'm not exactly sure how the point it returns relates to where my rectangle x and y is. I'm sure transformedX/Y works in here somewhere but I don't know how to put the two together......I mean I could do a transformX on my coordinates and I could run a similar function that returns a point, but I don't know how to put the two together .
I think I might be able to calculate theta on my own though .

the 2 don't go together the transformedX etc. is just pseudocode for transforming a point rotationally. getTopLeft just defines the point in the rectangle's local space first then transforms it. hw in that algorithm is synonymous with x in the pseudocode.
to add your rectangle's position and get your points (in global coordinates), you literally add the position of the rectangle to the transformed point. because you're defining the points by a width and a height, they exist in the "rectangle's space". when you rotate the rectangle, its vertices don't rotate relative to itself... only to a different coordinate space.
define the rectangle's 4 points locally:
top left = w/2, h/2
top right = w/2, h/2
bottom right = w/2, h/2
bottom left = w/2, h/2
if there is no rotation, it's easy to see where these points lie globally. let's say your rectangle's width is 10 and it's located at an x position of 100 the left edge will be at 95 and the right edge will be at 105. all you're doing is adding the point to the rectangle's translation.
now when rotating, you first have to transform the point according to the rotation of the rectangle. after that it's the same step adding the global translation of the rectangle.
Last edited by newblack; 08212008 at 12:24 AM.

Thanks alot man! I think I've got it. Here is some code I have so far based on what I have learned...it needs some fine tuning and compression for performance, but as is:
code:
private function createBlock(xPos:int,yPos:int,widthSent:int,height Sent:int,angle:int):void {
var theta:Number =angle*(Math.PI/180);
var transformedX:Number = xPos * Math.cos( theta )  yPos * Math.sin( theta );
var transformedY:Number = xPos * Math.sin( theta ) + yPos * Math.cos( theta );
var transformedPoint=new Point(transformedX,transformedY);
var topLeftPoint:Point=getTopLeft( widthSent, heightSent, angle ).add(transformedPoint);
var topRightPoint:Point=getTopRight( widthSent, heightSent, angle ).add(transformedPoint);
var bottomLeftPoint:Point=getBottomLeft( widthSent, heightSent, angle ).add(transformedPoint);
var bottomRightPoint:Point=getBottomRight( widthSent, heightSent, angle ).add(transformedPoint);
newWalls.push({from: topRightPoint,to:topLeftPoint});
newWalls.push({from: topLeftPoint,to:bottomLeftPoint});
newWalls.push({from: bottomLeftPoint,to:bottomRightPoint});
newWalls.push({from: bottomRightPoint,to:topRightPoint});
}
private function getTopLeft( widthSent:int, heightSent:int, theta:Number ):Point {
var hw:Number = widthSent / 2;
var hh:Number = heightSent / 2;
var cos:Number = Math.cos( theta );
var sin:Number = Math.sin( theta );
return new Point(hw * cos  hh * sin,hw * sin + hh * cos);
}
private function getTopRight( widthSent:int, heightSent:int, theta ):Point {
var hw:Number = widthSent / 2;
var hh:Number = heightSent / 2;
var cos:Number = Math.cos( theta );
var sin:Number = Math.sin( theta );
return new Point(hw * cos  hh * sin,hw * sin + hh * cos);
}
private function getBottomLeft( widthSent:int, heightSent:int, theta ):Point {
var hw:Number = widthSent / 2;
var hh:Number = heightSent / 2;
var cos:Number = Math.cos( theta );
var sin:Number = Math.sin( theta );
return new Point(hw * cos  hh * sin,hw * sin + hh * cos);
}
private function getBottomRight( widthSent:int, heightSent:int, theta ):Point {
var hw:Number = widthSent / 2;
var hh:Number = heightSent / 2;
var cos:Number = Math.cos( theta );
var sin:Number = Math.sin( theta );
return new Point(hw * cos  hh * sin,hw * sin + hh * cos);
}
newWalls is just an array I hold all collision walls of my game in before creation. I can use this new code to create blocks like so:
code:
createBlock(400,300,300,300,0);
totalWalls=newWalls.length1;
for (count=0; count<=totalWalls; count++) {
var currentN=new Point(newWalls[count].from.ynewWalls[count].to.y,newWalls[count].to.xnewWalls[count].from.x);
currentN.normalize(1);
var currentV= new Point(newWalls[count].to.xnewWalls[count].from.x,newWalls[count].to.ynewWalls[count].from.y);
var currentX=newWalls[count].from.x;
var currentY=newWalls[count].from.y;
walls.push({x: currentX, y: currentY,v: currentV,n: currentN});
}
this.graphics.lineStyle(1,000000);
for (count=0; count<=totalWalls; count++) {
this.graphics.moveTo(walls[count].x,walls[count].y);
this.graphics.lineTo(walls[count].x+walls[count].v.x, walls[count].y+walls[count].v.y);
}
putting all that extra stuff in the walls array is for my collision detection code. Which, honestly I barely understand some of the math behind that either, just been putting this frankenstien game together from stuff I learn here and there . Thanks again for the help...

Ehhh..spoke to soon. Getting close, but when I try it with an angle the block ends up rotating to another location and not around it's center....Well at this point hopefully I can tweak away until I figure it out. Definetally very close .

Viral tick
Code:
function getRotatedRectPoint( angle:Number, point:Point, rotationPoint:Point = null):Point
{
var ix:Number = (rotationPoint) ? rotationPoint.x : 0;
var iy:Number = (rotationPoint) ? rotationPoint.y : 0;
var m:Matrix = new Matrix( 1,0,0,1, point.x  ix, point.y  iy);
m.rotate(angle);
return new Point( m.tx + ix, m.ty + iy);
}
Use matrices, it makes it a lot faster and easier.
angle is in radians
point the corner's position you are finding.
rotationPoint  position in the rectangle when not rotated to be rotating around... if you don't include a rotationPoint and leave it null, it rotates around (0,0), or the upperleft corner.
so for instance a rectangle rotated around (0,0) with width = 100, and height = 50, and rotated 90 degrees:
Code:
var upperRight:Point = getRotatedRectPoint( Math.PI / 2, new Point(100,0));
var lowerRight:Point = getRoatedRectPoint(Math.PI / 2, new Point(100,50));
var lowerLeft:Point = getRotatedRectPoint(Math.PI / 2, new Point(0,50));
Last edited by lordofduct; 08212008 at 07:10 PM.

Thanks for the matrix tip man. I had to move on to programming something else for a bit, but will try this out when I get a chance and let you know.

Originally Posted by lordofduct
Code:
function getRotatedRectPoint( angle:Number, point:Point, rotationPoint:Point = null):Point
{
var ix:Number = (rotationPoint) ? rotationPoint.x : 0;
var iy:Number = (rotationPoint) ? rotationPoint.y : 0;
var m:Matrix = new Matrix( 1,0,0,1, point.x  ix, point.y  iy);
m.rotate(angle);
return new Point( m.tx + ix, m.ty + iy);
}
Use matrices, it makes it a lot faster and easier.
angle is in radians
point the corner's position you are finding.
rotationPoint  position in the rectangle when not rotated to be rotating around... if you don't include a rotationPoint and leave it null, it rotates around (0,0), or the upperleft corner.
so for instance a rectangle rotated around (0,0) with width = 100, and height = 50, and rotated 90 degrees:
Code:
var upperRight:Point = getRotatedRectPoint( Math.PI / 2, new Point(100,0));
var lowerRight:Point = getRoatedRectPoint(Math.PI / 2, new Point(100,50));
var lowerLeft:Point = getRotatedRectPoint(Math.PI / 2, new Point(0,50));
I just got a typo:
getRoatedRectPoint will be getRotatedRectPoint.
Thanks
nice one.

Can you please post a sample application.
Please.
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules

Click Here to Expand Forum to Full Width
