views:

693

answers:

4

I'm using rectangles defined in terms of their x y coordinates and their width and height. I figured out how to rotate them in terms of coordinates (x = cos(deg) * x - sin(deg) * y y = sin(deg) * x + cos(deg) * y) but I'm stuck on the height and width. I'm sure there's an obvious solution that I'm missing. If it matters, I'm using Python.

edit Sorry for the confusing description. My intention is to get the width and height either reversed or negated due to whatever the angle is. For example, in a 90 degree rotation the values would switch. In a 180 degree rotation the width would be negative. Also, I only intend to use multiples of 90 in my script. I could just use if statements, but I assumed there would be a more "elegant" method.

A: 

Just calculate four corners of Your rectangle:

p1 = (x, y)
p2 = (x + w, y)
p3 = (x, y + h)

and rotate each by angle You want:

p1 = rotate(p1, angle)
# and so on...

and transform back to Your rectangle representation:

x, y = p1
w = dist(p1, p2)  # the same as before rotation
h = dist(p1, p3)

where dist calculates distance between two points.

Edit: Why don't You try apply formula You have written to (width, height) pair?

x1 = cos(deg) * x - sin(deg) * y
y2 = sin(deg) * x + cos(deg) * y

It is easy to see that if deg == 90 the values will switch:

x1 = -y
y2 =  x

and if deg == 180 they will be negated:

x1 = -x
y2 = -y

and so on... I think this is what You are looking for.

Edit2:

Here comes fast rotation function:

def rotate_left_by_90(times, x, y):
    return [(x, y), (-y, x), (-x, -y), (y, -x)][times % 4]
Dejw
A: 

The proper way would be to resort to transformation matrices. Also, judging from your question I suppose that you want to rotate with respect to (x=0,y=0), but if not you will need to take this into account and translate your rectangle to the center of the plan first (and then translate it back when the rotation is carried out).

M = Matrix to translate to the center R = Rotation Matrix

Transformation Matrix = M^(-1) * R * M

But to give you an easy answer to your question, just take the two other corners of your rectangle and apply the same transformation on them.

To learn more about transformation matrices : http://en.wikipedia.org/wiki/Transformation_matrix

A: 

Rotation should not change width and height. Your equation is correct if you want to rotate (x,y) about (0,0) by deg, but note that often cos and sin functions expect arguments in radians rather than degrees, so you may need to multiply deg by pi/180 (radians per degree).

If you need to find the locations of other rectangle vertices besides (x,y) after rotating, then you should either store and rotate them along with (x,y) or keep some information about the rectangle's orientation (such as deg) so you can recompute them as e.g. x+width*cos(deg), y+height*sin(deg).

ccmonkey
A: 

From the way you describe only rotating by 90 degrees, and the way you seem to be defining width and height, perhaps you are looking for something like

direction = 1     // counter-clockwise degrees
// or
direction = -1    // clockwise 90 degrees

new_height = width * direction
new_width = -height * direction
width = new_width
height = new_height

Not sure why you want to have negative values for width and height, though .. because otherwise each 90 degree rotation effectively just swaps width and height, regardless which way you rotate.

JustJeff
No particular reason for the negative values, other than it seemed simplest and the library I'm using this with supports that.
jjackson