Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #51082 > unrolled thread
| Started by | enmce@yandex.ru |
|---|---|
| First post | 2013-07-23 05:34 -0700 |
| Last post | 2013-07-24 19:55 -0400 |
| Articles | 6 — 6 participants |
Back to article view | Back to comp.lang.python
Beginner. 2d rotation gives unexpected results. enmce@yandex.ru - 2013-07-23 05:34 -0700
Re: Beginner. 2d rotation gives unexpected results. Peter Otten <__peter__@web.de> - 2013-07-23 15:11 +0200
Re: Beginner. 2d rotation gives unexpected results. Nobody <nobody@nowhere.com> - 2013-07-23 16:20 +0100
Re: Beginner. 2d rotation gives unexpected results. David Hutto <dwightdhutto@gmail.com> - 2013-07-23 09:04 -0400
Re: Beginner. 2d rotation gives unexpected results. Joshua Landau <joshua@landau.ws> - 2013-07-24 22:17 +0100
Re: Beginner. 2d rotation gives unexpected results. Terry Reedy <tjreedy@udel.edu> - 2013-07-24 19:55 -0400
| From | enmce@yandex.ru |
|---|---|
| Date | 2013-07-23 05:34 -0700 |
| Subject | Beginner. 2d rotation gives unexpected results. |
| Message-ID | <0a905ff1-199c-4900-81e6-d9b7bb63bb44@googlegroups.com> |
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.
[toc] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2013-07-23 15:11 +0200 |
| Message-ID | <mailman.5004.1374585095.3114.python-list@python.org> |
| In reply to | #51082 |
enmce@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])
[toc] | [prev] | [next] | [standalone]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2013-07-23 16:20 +0100 |
| Message-ID | <pan.2013.07.23.15.20.35.67000@nowhere.com> |
| In reply to | #51084 |
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.
[toc] | [prev] | [next] | [standalone]
| From | David Hutto <dwightdhutto@gmail.com> |
|---|---|
| Date | 2013-07-23 09:04 -0400 |
| Message-ID | <mailman.5003.1374585070.3114.python-list@python.org> |
| In reply to | #51082 |
[Multipart message — attachments visible in raw view] — view raw
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, <enmce@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*
[toc] | [prev] | [next] | [standalone]
| From | Joshua Landau <joshua@landau.ws> |
|---|---|
| Date | 2013-07-24 22:17 +0100 |
| Message-ID | <mailman.5066.1374700684.3114.python-list@python.org> |
| In reply to | #51082 |
[Multipart message — attachments visible in raw view] — view raw
On 23 July 2013 13:34, <enmce@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.
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2013-07-24 19:55 -0400 |
| Message-ID | <mailman.5073.1374710157.3114.python-list@python.org> |
| In reply to | #51082 |
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
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web