## 2d rotation gives unexpected results.

### 2d rotation gives unexpected results.

Hello!
This is my first post, nice to meet you all!
I`m biology student from Russia, trying to learn python to perform some simple simulations.

Here`s my first problem.
I`m trying to perform some simple 2d vector rotations in pygame, in order to learn the basics of linear algebra and 2d transformations. So far i understand matrix multiplication pretty well, and probably all my math is right. Eventually i`m planning to write Poly class, and use it to rotate and translate some simple shapes. But when i try and write it in the program, i get very weird results, like all points of rectangle with coordinates [0,0],[0,100],[100,0],[100,100] start to go spiral and eventually shrink to the center instead of rotating right. Although even Excel calculations with this formulas give me right result.
What is wrong with my code?

Code: Select all
`import pygameimport math as mblack = ( 0, 0, 0)white = ( 255, 255, 255)green = ( 0, 255, 0)red = ( 255, 0, 0)class Poly():    pos = [100,100] #x and y coordinates of a point    rot = m.radians(1) #rotation in degrees    def draw(self): #draw point        pygame.draw.circle(screen,white,self.pos,10,0)    def rotate(self): # rotation method        sin = m.sin(self.rot) #calculationg sin and cos        cos = m.cos(self.rot)        x_rot = int(self.pos[0]*cos-self.pos[1]*sin) #mulpitplicating vector to rotation matrix        y_rot = int(self.pos[0]*sin+self.pos[1]*cos)        self.pos[0] = x_rot #set new coordinates to a point        self.pos[1] = y_rota = Poly() #Some simple sample points giving rectangleb = Poly()c = Poly()d = Poly()b.pos = [0,100]c.pos = [100,0]d.pos = [0,0]pygame.init()size = [700,500]screen = pygame.display.set_mode(size)done = Falseclock = pygame.time.Clock()while done == False:    for event in pygame.event.get():        if event.type == pygame.QUIT:            done = True    a.rotate() #perform rotation    b.rotate()    c.rotate()    d.rotate()    screen.fill(black)        a.draw() #draw point    b.draw()    c.draw()    d.draw()    pygame.display.flip()    clock.tick(30)pygame.quit()`

P.S. I use Python 3.3. Sorry for my english, bit rusty in that department.
Zirgon

Posts: 3
Joined: Tue Jul 23, 2013 11:48 am

### Re: 2d rotation gives unexpected results.

Well, with some help, i did it.
The main problem was with float to integer coordinate conversion in this code:
Code: Select all
`        x_rot = int(self.pos[0]*cos-self.pos[1]*sin) #mulpitplicating vector to rotation matrix        y_rot = int(self.pos[0]*sin+self.pos[1]*cos)`

For each cycle we get more and more error with conversion.
Instead, it should be like this:
Code: Select all
`        x_rot = self.pos[0]*cos-self.pos[1]*sin #mulpitplicating vector to rotation matrix        y_rot = self.pos[0]*sin+self.pos[1]*cos`

And coordinate conversion should happen when point calls a draw method:
Code: Select all
`    def draw(self): #draw point        pygame.draw.circle(screen,white,[int(self.pos[0]),int(self.pos[1])],10,0)`

Hope this helps someone.
Zirgon

Posts: 3
Joined: Tue Jul 23, 2013 11:48 am

### Re: 2d rotation gives unexpected results.

Zirgon wrote:Well, with some help, i did it.
The main problem was with float to integer coordinate conversion in this code.

Lol. I was mid-writing this post when you posted saying you solved it. So I'll say this instead.

You should really properly __init__ your Point class. And you should try to resist the urge to use class wide variables that should be instance specific.
Code: Select all
`import math,sysimport pygameclass Point(object):    def __init__(self,x,y):        self.x,self.y = x,y    def rotate(self,axis,angle):        angle = math.radians(angle)        sin_of_angle = math.sin(angle)        cos_of_angle = math.cos(angle)        adjust_x = self.x-axis[0]        adjust_y = self.y-axis[1]        x_new = adjust_x*cos_of_angle-adjust_y*sin_of_angle        y_new = adjust_x*sin_of_angle+adjust_y*cos_of_angle        self.x = x_new+axis[0]        self.y = y_new+axis[1]    def draw(self,surface):        draw_location = int(self.x),int(self.y)        pygame.draw.circle(surface,(255,255,255),draw_location,10,0)class Control(object):    def __init__(self):        pygame.init()        self.size = [700,500]        self.screen = pygame.display.set_mode(self.size)        self.screen_rect = self.screen.get_rect()        self.done = False        self.clock = pygame.time.Clock()        self.make_some_points()    def make_some_points(self):        rect = pygame.Rect(0,0,100,100)        rect.center = (200,self.screen_rect.centery)        self.points = []        for (x,y) in (rect.topleft,rect.topright,rect.bottomleft,rect.bottomright):            self.points.append(Point(x,y))    def event_loop(self):        for event in pygame.event.get():            if event.type == pygame.QUIT:                self.done = True    def main_loop(self):        while not self.done:            self.event_loop()            self.screen.fill(0)            for point in self.points:                point.rotate(self.screen_rect.center,3)                point.draw(self.screen)            pygame.display.update()            self.clock.tick(60)if __name__ == "__main__":    run_it = Control()    run_it.main_loop()    pygame.quit();sys.exit()`

-Mek
New Users, Read This
• Use code tags when posting code.
• Include any errors with your post (in code tags).
• Describe your problem; not your chosen solution.
• Make examples the minimum length to demonstrate your issue.

Mekire

Posts: 1711
Joined: Thu Feb 07, 2013 11:33 pm
Location: Tucson, Arizona

### Re: 2d rotation gives unexpected results.

It`s helpful example of good structured code, thanks!
Zirgon

Posts: 3
Joined: Tue Jul 23, 2013 11:48 am

Return to Game Development

### Who is online

Users browsing this forum: No registered users and 2 guests