On 23 July 2013 13:34, <en...@yandex.ru> wrote: > 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. Although even Excel calculations with > > this formulas give me right result. > I use Python 3.3 on Windows Xp. > What is wrong with my code? > > [code]import pygame > import math as m >
GAH! Why on earth would you do such a thing? Just "import math", there's no need to obfuscate your code. > black = ( 0, 0, 0) > white = ( 255, 255, 255) > green = ( 0, 255, 0) > red = ( 255, 0, 0) > It's probably better to do: black = pygame.Color("Black") white = pygame.Color("white") green = pygame.Color("green") red = pygame.Color("red") > class Poly(): > pos = [100,100] #x and y coordinates of a point rot = m.radians(1) #rotation in degrees > *Do not do this* This is because classes have shared values -- these "pos" and "rot" values are shared within the class. >>> class P: ... n = [] ... def more_n(self): ... self.n.append(len(self.n)) ... ... ... >>> one_P = P() >>> two_P = P() >>> >>> one_P.more_n() >>> one_P.more_n() >>> one_P.more_n() >>> >>> two_P.n [0, 1, 2] Normally you want to set these at initialisation: class Poly(): def __init__(self, pos=None, rot=math.radians(1)): self.pos = [100, 100] if pos is None else pos self.rot = rot super().__init__(self) > def draw(self): #draw point > pygame.draw.circle(screen,white,self.pos,10,0) > Add some spaces, dude. I was going to say: > Also, use keyword arguments instead of throwing around "10" and "0" with no context: > def draw(self): > pygame.draw.circle(screen, white, self.pos, radius=10, width=0) > Pygame-ists will know that "width" means border_width, by now. Pygame isn't known for it's clean design ;). But pygame, being brilliant (not) decided that it won't let you. 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_rot > A lot of your comments are ridiculous. This one is particularly so: #mulpitplicating vector to rotation matrix. Don't add comments that talk about lines. Here is a quick guide for when to use comments: 1) API usage, when docstrings aren't usable 2) When something funny or unexpected occurs in the code, such as: # Goes down to 0 (does not include end-point) for i in range(foo, -1, -1): ... 3) To explain large-scale methodologies and algorithms Other than this, are you trying to obfuscate this line? HINT: ADD SPACES ;). A big problem here (this solves your problem) is your int(...) conversions. Do *not* store important information less accurately than it deserves. This is one very important instance. Only convert to int when you need to. Another thing: "sin = m.sin(self.rot)"??? Really? Write "sin_1deg = ..." instead, at least. > a = Poly() #Some simple sample points giving rectangle > b = Poly() > c = Poly() > d = Poly() > > b.pos = [0,100] > c.pos = [100,0] > d.pos = [0,0] > Use: a = Poly() b = Poly([0, 100]) c = Poly([100, 0]) d = Poly([0, 0]) pygame.init() > size = [700,500] > screen = pygame.display.set_mode(size) > done = False > clock = pygame.time.Clock() > while done == False: > "while not done" Also, just use "while True" and a "break". I know some C-people or what not think this is "evil" or something, but they're wrong. Personally, I actually like using: while "rotating the squares": ... instead of "while True". It's no slower and it's free documentation. > 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()[/code] > You don't need pygame.quit(). You *only* want pygame.quit() if you're quitting Pygame *before* the program is finished.
-- http://mail.python.org/mailman/listinfo/python-list