MeesterTeem - 1 year ago 71
Python Question

# Rotate a rectangle consisting of 4 tuples to left or right

I'm working on a program to manipulate GIS data, but for this precise problem, I'm trying to rotate a rectangle of 4 points around the bottom left corner. I've got 1 tuple describing the bottom left corner:

`x, y=40000,40000`

I've also got a length x, and a length y,
`x_displacement`
, and
`y_displacement`
. I've got an angle,
`theta`
, in degrees. I want to rotate the rectangle by up to 90 degrees left or right, so theta can be -89 to 89 degrees. Negative angles should rotate the corners to the left; positive angles to the right.I've represented the rectangle as such:
http://i.imgur.com/pp3hFyA.jpg

``````    x_displacement=100
y_displacement=100
x = 40000
y = 40000
x1 = x
y1 = y + a.y_displacement
x2 = x + a.x_displacement
y2 = y + a.y_displacement
x3 = x + a.x_displacement
y3 = y
#describes the other 4 corners of the rectangle
``````

Coord is a class that holds an x and a y value.
`coords`
is a list of Coord class items.

``````    c = Coord(x, y)
coords.append(c)
c = Coord(x1, y1)
coords.append(c)
c = Coord(x2, y2)
coords.append(c)
c = Coord(x3, y3)
coords.append(c)
#Adds each corner to the list of coordinates
newcoords = []
for c in coords:
newcoords.append(Coord((c.x * math.cos(theta) - c.y * math.sin(theta)),
(c.x * math.sin(theta) + c.y * math.cos(theta))))
coords=newcoords
``````

I suspect that there's something relatively trivial that I'm doing wrong, but I've been stuck on this problem for quite some time.
This code produces a new rectangle that is either misshapen, or has negative corners, rather than slightly left-rotated corners as wanted.
I've seen many posts on here about rotating rectangles, but none seem to be a direct duplicate, because they do not handle negative angles. I'd appreciate any pointers!

As a few commenters mentioned, you are rotating around the (0, 0) point, rather than the lower left point. As we are constructing the coordinates we can:

• First construct the shape at the (0, 0) point
• Rotate it
• Translate it out to where it needs to be

The below gives an example using plain lists rather than your Coord object, but I'm sure it makes the point.

``````import math

def rotate(xy, theta):
# https://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions
cos_theta, sin_theta = math.cos(theta), math.sin(theta)

return (
xy[0] * cos_theta - xy[1] * sin_theta,
xy[0] * sin_theta + xy[1] * cos_theta
)

def translate(xy, offset):
return xy[0] + offset[0], xy[1] + offset[1]

if __name__ == '__main__':
# Create the square relative to (0, 0)
w, h = 100, 100

points = [
(0, 0),
(0, h),
(w, h),
(w, 0)
]

offset = (40000, 50000)
degrees = 90