Re: Beginner. 2d rotation gives unexpected results.

2013-07-24 Thread Joshua Landau
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


Re: Beginner. 2d rotation gives unexpected results.

2013-07-24 Thread Terry Reedy

On 7/24/2013 5:17 PM, Joshua Landau wrote:


import math as m


GAH!

Why on earth would you do such a thing?


for the same reason people do 'import tkinter as tk': to minimize typing 
and maximize clarity. In this case,

  from math import sin, cos, radians
also works well

--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: Beginner. 2d rotation gives unexpected results.

2013-07-23 Thread Nobody
On Tue, 23 Jul 2013 15:11:43 +0200, Peter Otten wrote:

 The conversion to int introduces a rounding error that accumulates over 
 time.

Most floating point calculations introduce a rounding error. If the
calculations are iterated, the error will accumulate.

In general, you want to avoid accumulating entire transformations. E.g. if
you want a spinning object, maintain the cumulative rotation angle and
rotate the original points each frame.

If you must accumulate transformations, you need to actively work to
maintain any desired invariants. E.g. if a transformation is supposed to
be orthonormal (all axes perpendicular and of unit length), you should
renormalise it periodically, otherwise the lengths and angles will change
over time.

-- 
http://mail.python.org/mailman/listinfo/python-list


Beginner. 2d rotation gives unexpected results.

2013-07-23 Thread enmce
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

black = ( 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_rot

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]

pygame.init()
size = [700,500]
screen = pygame.display.set_mode(size)
done = False
clock = 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()[/code]

P.S. Sorry for my english, bit rusty in that department.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Beginner. 2d rotation gives unexpected results.

2013-07-23 Thread David Hutto
haven't used pygame that much, but it sounds like you drew Z. You have
[0,0],[0,100],[100,0],[100,
100]
0,0 is the top left, if I recall 0, 100 would be the lower left, then you
move to100, 0 which would go diagonal to the top right, and then 100,100 to
the lower right, this is assuming 0,0 is the upper left. for a square you
would go,[0,0],[0,100],[100,100],[100,0]then back to [0,0] to complete the
square. This is assuming that 0,0 is the upper left, the coords are x,y in
the brackets, and the increase in x takes you the right, and the increase
in y takes you down.

If that doesn't work,I'll download it later, and try it out.


On Tue, Jul 23, 2013 at 8:34 AM, 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

 black = ( 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_rot

 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]

 pygame.init()
 size = [700,500]
 screen = pygame.display.set_mode(size)
 done = False
 clock = 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()[/code]

 P.S. Sorry for my english, bit rusty in that department.
 --
 http://mail.python.org/mailman/listinfo/python-list




-- 
Best Regards,
David Hutto
*CEO:* *http://www.hitwebdevelopment.com*
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Beginner. 2d rotation gives unexpected results.

2013-07-23 Thread Peter Otten
en...@yandex.ru wrote:

 This is my first post, nice to meet you all!

Welcome!

 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?

 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

The conversion to int introduces a rounding error that accumulates over 
time.

 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

One way to keep the error low is to keep the float values in self.pos and do 
the rounding on the fly when you display the point:

class Poly():
def __init__(self, color, pos, rot=m.radians(1)):
self.color = color
self.pos = pos
self.rot = rot
def draw(self):
x, y = self.pos
pygame.draw.circle(screen, self.color, [350+int(x), 250+int(y)], 10, 
0)
def rotate(self):
sin = m.sin(self.rot)
cos = m.cos(self.rot)
x_rot = self.pos[0]*cos-self.pos[1]*sin
y_rot = self.pos[0]*sin+self.pos[1]*cos

self.pos = [x_rot, y_rot]

a = Poly(white, [100, 100])
b = Poly(green, [0, 100])
c = Poly(blue, [100, 0])
d = Poly(red, [0, 0])



-- 
http://mail.python.org/mailman/listinfo/python-list