[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] fast sqrt? and profiling



Yes, complex numbers are built in and implemented in C, whereas Euclid is not and implemented in python. The downside to using complex is that they cannot be indexed or unpacked for passing into apis that expect sequences for vectors (hence the to_tuple() function).

-Casey

On Jan 22, 2009, at 11:36 PM, Emile Kroeger wrote:

Oh, I guess they are pretty much equivalent, even though Casey seems
to say complex have better performance than euclid.

I just use complex because it's available out of the box with Python
:) (and because I didn't know about Euclid; maybe I'll use it if I do
3D)

On Thu, Jan 22, 2009 at 11:58 PM, Jake b <ninmonkeys@xxxxxxxxx> wrote:
Still confused on the difference between complex and euclid.Vector2 [ doc:
http://www.partiallydisassembled.net/euclid/vector-classes.html ]

On Wed, Jan 21, 2009 at 9:24 PM, Casey Duncan <casey@xxxxxxxxxxx> wrote:

Here's some example code with some commonly used functions. Addition and subtraction are built into the complex type and work as expected (I use the
real part

So far, this looks like euclid.Vector2. Are you doing the same thing, only using 'real as the x component, and 'imag' as y? ( Meaning you are using complex instead of tuple, equivalent to using vector2 instead of tuple ? )

Or, I think i'm missing something. What is the advantage to to use this over
euclid.Vector2? [ more below ]

for x and the imaginary part for y). complex multiply can be used to
rotate vectors:

Does complex multiply behind the scenes do something like this?

   def rad2v(rad,mag=1.): # convert radians to vector with magnitude
       return mag*Vector2(cos(rad), sin(rad))

   def v2rad(v): return atan2(v.y, v.x) # convert vector to radians

   def mod_angle(v,rad): # add radians to vector's orientation
       r = v2rad(v)
       r+=rad
       return rad2v( r, v.magnitude() )

v = rad2v( radians(142.8),2.5)
   # now equals: deg=142.8, mag=2.5, v=Vector2(-1.99, 1.51)
v = mod_angle( v, radians(3.))
   # now equals: deg=145.8, mag=2.5, v=Vector2(-2.07, 1.41)


# 2D vectors using python complex numbers

def radians(vector):
      return atan2(vector.imag, vector.real)

def unit(radians):
      return cmath.exp(radians * 1j)

def normal(vector):
      L = length(vector)
      if L == 0:
              return vector2()
      else:
              return vector / L

def clamp(vector, max_length):
      L = length(vector)
      if L > max_length:
              return vector * (max_length / L)
      else:
              return vector

At first, this code looks the same, except there are new functions:
.radians(v) and unit(r). Radians looks like a 'convert vector to euler
radians angle'.

But whatis .unit()? I'm guessing it's to create a new unit vector in the angle of 'radians.' But calling it with a few values, I'm not getting what I
was expecting.

Is it the equivalent of rad2v(r) for Vector2, but unit(r) does the same for
complex numbers?


def distance(vector1, vector2):
      return length(vector1 - vector2)
This is good if the list may change during iteration. If you do this
repeatedly in a given frame, it might be better to create a custom class (perhaps subclass set) that contains a stable set of the actors. When you add or remove, these are stored in ancillary sets rather than changing the stable set immediately. An update method called at the beginning of each frame adds and removes the items from the ancillary sets to update the stable set. These ancillary sets are then cleared. This mean less memory
allocation/cleanup and work copying the lists

class StableSet(set):

I'll try it out.

@emile: ( continued from above ), I'm trying to understand how/why complex
numbers are used.

Here is my Vector2 equivalent to your code.

It looks like you treat complex same way I treat euclid.Vector2 ? Am I
missing something?

from euclid import Vector2
class Spaceship():
   def __init__(self, pos=Vector2(0,0), max_accel=100):
       self.pos = pos
       self.vel = Vector2(0, 0) # or'speed'. changed named to not be
confused as Scalar
       self.accel = Vector2(0, 1.) # or 'direction'
       self.boosters_on = False
       self.max_accel = max_accel

   def update(self, dt):
       if self.boosters_on:
           self.vel += self.accel * self.max_accel * dt
       self.pos += self.vel * dt
--
Jake