hi again,

a slightly related point... consider that pygame already works with big
multidimensional vectors of a limited amount of types - this is Surface.

However it is limited to 1, 2, 3, and 4 uint8 multi dimensional vectors.
For these limited cases it is fairly fast.

It should be possible to make some sorts of really basic particle systems
with Surface I guess.

Having one image for positions, one for direction vectors, one for lifetime
etc.

To update the movement each frame, you'd use:
   position_surf.blit(directions_surf, (0,0), special_flags=BLEND_ADD)

Would still need a fast way to draw each particle based on the pixels in
each surface.  If pygames functions/methods took more arrays it could be
possible...  eg.  a Surface.blit_multi which took a buffer of destination
rects.




On Tue, Apr 28, 2009 at 3:06 PM, Casey Duncan <ca...@pandora.com> wrote:

> I have found this to be generally true as well, and storing a large number
> of individual vector objects to be operated on in a batch performs poorly
> regardless of implementation language. As an example, for Lepton I coded a
> controller object which looped over a large number of particles to update
> their velocities. Under the covers the particles are stored as a simple
> array of C structs, but you can iterate them and access the individual
> vectors for position, velocity, etc. from python.
>
> To make a long story short, the python version of the code that iterated
> and updated the velocities by manipulating vector objects was about 1600x
> slower than the equivalent C code that did the same using inline vector
> functions. psyco sped up the python code almost 5x, but it still was no
> contest.
>
> This is definitely an extreme case, but one relevant to game coding at
> least 8^)
>
> -Casey
>
>
> On Apr 27, 2009, at 7:24 PM, Daniel Jo wrote:
>
>  I've pretty much abandoned the idea of vector classes in Python.  I've
>> tested various implementations: pure python classes (with and without
>> __slots__), C++ exposed through Pyrex/Cython, tuples manipulated
>> through add/mul/div/etc functions. . .  Of these, C++ turned out to be
>> the fastest, but faster by far than that was simply not using any
>> structure at all.  Store the components in tuples for convenience, but
>> extract them and manipulated them individually for complex equations.
>> Vector classes work well for convenience and code readability, but
>> from a performance standpoint they aren't very useful.
>>
>> On Mon, Apr 27, 2009 at 4:28 PM, Brian Fisher <br...@hamsterrepublic.com>
>> wrote:
>>
>>> I don't see a 3 element vector type being useful from a pygame
>>> perspective.
>>> What pygame api anywhere even takes 3 element lists aside from colors?
>>> (which already have a special struct type thing)
>>>
>>> I'm not saying 3 element vectors don't have their uses - just that the
>>> seem
>>> to me to be a pretty random thing to have added to pygame, which is
>>> exclusively 2d in every interesting respect. It seems like the sort of
>>> thing
>>> to add that would add much more to the maintenance and testing cost of
>>> the
>>> pygame library than it would bring to the users as a whole. To put
>>> another
>>> way, there is no synergy between a 3 element vector class and pygame. Why
>>> would a 3 element vector class be better as part of pygame than not? what
>>> existing element of pygame is better or easier to use with a 3 element
>>> vector also being part of pygame?
>>>
>>> ...now a 2 element vector being part of pygame... rect could be better by
>>> making use of it, it could be used as an argument to the various
>>> functions
>>> that take 2 element lists, etc. etc....
>>>
>>> ... and a 3 element vector (and quaternions and matrices) being part of
>>> pyOpenGL, that sounds great too...
>>>
>>>
>>>
>>> On Mon, Apr 27, 2009 at 2:59 PM, Lorenz Quack <d...@amberfisharts.com>
>>> wrote:
>>>
>>>>
>>>> Hello,
>>>>
>>>> I am interested in the inclusion of a vector and matrix types into
>>>> pygame
>>>> as suggested here [4]. In this email I want to propose a API for a
>>>> vector
>>>> module.
>>>>
>>>> I will for brevity only present the API for the types in three
>>>> dimensions.
>>>> The APIs for two or four dimensions should look analog.
>>>>
>>>> Also I enumerated every API for easier reference in discussions.
>>>> Alternatives are denoted by lexical items (e.g. a) or b))
>>>> At the end I put together a small comparison to existing
>>>> implementations.
>>>>
>>>> This is only a suggestion to spark discussion and provoke feedback. So
>>>> throw
>>>> in your 2 cents.
>>>>
>>>> sincerely yours
>>>> //Lorenz
>>>>
>>>>
>>>> PS: If this turns out to be of any value I will put something similar
>>>> together for matrix types and quaternions.
>>>>
>>>>
>>>>
>>>>
>>>> ******************
>>>> * API draft v1.0 *
>>>> ******************
>>>>
>>>> In the following I will use the notation:
>>>>  v, v1, v2, ... are vectors
>>>>  s, s1, s2, ... are objects implementing the sequences
>>>>                 protocol (list, tuple, the proposed vector)
>>>>  a, a1, a2, ... are scalars (int, float)
>>>>
>>>>
>>>> § 1 Vector type
>>>> ################
>>>>
>>>> 1.1 Class name and constructor
>>>> ==============================
>>>> 1.1.1  a) Vector3
>>>>      b) Vector3d
>>>> 1.1.2  V(a1, a2, a3)# initialize x, y and z with a1, a2 and a3
>>>> respectivly
>>>> 1.1.3  V(s)         # initialize x, y and z with s[0], s[1] and s[2]
>>>> respectivly
>>>> 1.1.4  V()          # initialize x, y and z with zeros
>>>>
>>>>
>>>> 1.2 numerical behavior
>>>> ======================
>>>> 1.2.1.1  v1 + s -> v3
>>>> 1.2.1.2  s + v1 -> v3
>>>> 1.2.1.3  v += s
>>>> 1.2.2.1  v1 - s -> v3
>>>> 1.2.2.2  s - v1 -> v3
>>>> 1.2.2.3  v -= s
>>>> 1.2.3.1  v1 * a -> v3
>>>> 1.2.3.2  a * v1 -> v3
>>>> 1.2.3.3  v *= a
>>>> 1.2.4.1  v1 / a -> v3
>>>> 1.2.4.2  v /= a
>>>> 1.2.5.1  v1 // a -> v3
>>>> 1.2.5.2  v //= a
>>>> 1.2.6.1  v1 % a -> v3
>>>> 1.2.6.2  v %= a
>>>>
>>>> 1.2.7.1  v * s -> a      # dot/scalar/inner product
>>>> 1.2.7.2  s * v -> a      # dot/scalar/inner product
>>>>
>>>> 1.2.8.1  +v1 -> v2       # returns a new vector
>>>> 1.2.8.2  -v1 -> v2
>>>>
>>>>
>>>> 1.3 sequence behavior
>>>> =====================
>>>> 1.3.1    len(v) -> 3       # fixed length
>>>> 1.3.2.1  v[0] -> a         # 0-based indexing
>>>> 1.3.2.2  v[0] = a
>>>>
>>>>
>>>> 1.4 attributes
>>>> ==============
>>>> 1.4.0    "x", "y", "z" (and "w" for 4th dimension)
>>>>        "_epsilon" for comparison operations
>>>> 1.4.1.1  v.x -> a
>>>> 1.4.1.2  v.x = a
>>>>
>>>>
>>>> 1.5 methods
>>>> ===========
>>>> 1.5.1    v.dot(s) -> a     # dot/scalar/inner product
>>>> 1.5.2    v.cross(s) -> v   # cross/vector product
>>>>        # in 2 dimensions this returns v.x * s[1] - v.y * s[0]
>>>>        # this is not defined in 4 dimensions
>>>> 1.5.3    v.outer(s) -> m   # outer product yielding a matrix
>>>> 1.5.4.1  v.isNormalized() -> bool
>>>> 1.5.4.2  v.normalize() -> None    # normalizes inplace
>>>> 1.5.4.3  v1.normalized() -> v2    # returns normalized vector
>>>> 1.5.5.1  v1.rotate(s1[, a]) -> None
>>>>        # rotates around s1 by angle a. if a isn't given it
>>>>        # rotates around s1 by the magnitude of s1
>>>>        # this is an inplace operation
>>>> 1.5.5.2  v1.rotated(s1[, a]) -> v2
>>>>        # same as 1.5.6 but returns a new vector and leaves v1 untouched
>>>> 1.5.6.1  v1.rotateX(a) -> None
>>>>        # rotates v1 around the x-axis by the angle a
>>>> 1.5.6.2  v1.rotatedX(a) -> v2
>>>>        # same as 1.5.6.1 but returns a new vector and leaves v1
>>>> untouched
>>>> 1.5.6.3  # implement 1.5.6.1 and 2 also for Y and Z
>>>> 1.5.7    v1.reflect(s) -> v2
>>>>        # reflects the vector of a surface with surface normal s
>>>> 1.5.8    a) v1.interpolate(s, a) -> generator of vectors
>>>>        b) v1.slerp(s, a) -> generator of vectors
>>>>        # the distance between "v1" and "s" divided in "a" steps
>>>> 1.5.9    v.getAngleTo(s) -> a
>>>>        # returns the angle between v and s
>>>> 1.5.10.1 v.getDistanceTo(s) -> a
>>>>        # returns the distance between v and s
>>>> 1.5.10.2 v.getDistance2To(s) -> a
>>>>        # returns the squared distance between v and s
>>>>
>>>>
>>>> 1.6 properties
>>>> ==============
>>>> 1.6.1.1  v.length -> a # gets the magnitude/length of the vector
>>>> 1.6.1.2  v.length = a
>>>>        # sets the length of the vector while preserving its direction
>>>> 1.6.2.1  a) v.lengthSquared -> a
>>>>        b) v.length2 -> a
>>>>        # gets the squared length of the vector. same as v.dot(v) or v *
>>>> v
>>>> 1.6.2.1  a) v.lengthSquared = a
>>>>        b) v.length2 = a
>>>>        # sets the squared length of the vector. preserving its direction
>>>> # the following only have meaning in 3 dimensions
>>>> 1.6.3.1  v.r -> a  # returns the "r" coordiante of sherical coordinates
>>>>                  # this is the same as the "length" property
>>>> 1.6.3.2  v.r = a
>>>> 1.6.4.1  v.phi -> a # returns the "phi" coordiante of spherical
>>>> coordiantes
>>>> 1.6.4.2  v.phi = a
>>>> 1.6.5.1  v.theta -> a # returns the "theta" coordiante of spherical
>>>> coordiantes
>>>> 1.6.5.2  v.theta = a
>>>>
>>>>
>>>> 1.7 comparison operations
>>>> =========================
>>>> 1.7.0    the "==" and "!=" and "bool" operater compare the differences
>>>> against
>>>>        the attribute v._epsilon. this way the user can adjust the
>>>> accuracy.
>>>> 1.7.1.1  v == s -> bool
>>>>        # true if all component differ at most by v._epsilon
>>>> 1.7.1.2  s == v -> bool
>>>> 1.7.2.1  v != s -> bool
>>>>        # true unless all component differ at most by v._epsilon
>>>> 1.7.2.2  s != v -> bool
>>>> 1.7.3    bool(v) -> bool
>>>>        # returns true if any component is larger than v._epsilon
>>>>        # formerly known as v.__nonzero__
>>>>
>>>>
>>>> 1.8 misc
>>>> ======================
>>>> 1.8.1  support iter protocol
>>>> 1.8.2  str(v) -> "[x, y, z]"
>>>> 1.8.3  repr(v) -> "Vec<x, y, z>"
>>>> 1.8.4  support pickle protocol
>>>>
>>>>
>>>> 1.10 open questions (in no particular order)
>>>> ============================================
>>>> 1.10.1  a) use radians for all angles
>>>>       b) use degrees for all angles
>>>> 1.10.2  what about slicing?
>>>> 1.10.3  what about swizzling?
>>>> 1.10.4  do we need int or complex vectors?
>>>> 1.10.5  what about negative indices in the sequence protocol?
>>>> 1.10.6  is there need for explicit row- and column-vectors?
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Contrast to existing implementations
>>>> ####################################
>>>>
>>>> There are of course already existing implementations of vector types.
>>>>  In
>>>> particular I want to take a look at pyeuclid [1], vectypes [2] and
>>>> 3DVectorClass [3].  In this chapter I want to compare them and point out
>>>> their similarities and differences.  This isn't a full review but I
>>>> tried
>>>> to
>>>> find out and describe the most important differences.  If your favorite
>>>> implementation is missing from this comparison feel free to contribute
>>>> your
>>>> own analysis.  Disclaimer: I never used any of these.
>>>>
>>>> numerical behaviour:
>>>>  * __add__ and __sub__:
>>>>  vectypes doesn't interact with other sequence types.
>>>>    e.g. "vec2() + [3, 4]" would not work.
>>>>  * __mul__ with other vectors
>>>>  pyeuclid doesn't support multiplication with anything but numbers
>>>>    e.g. "Vector2() * Vector2()" would not work
>>>>  vectypes and 3DVectorClass do elementwise multiplication
>>>>    e.g. "vec2(1,2) * vec2(3,4) == vec(1*3, 2*4)"
>>>>  this proposal preforms a dot product
>>>>    e.g. "V(1,2) * V(3,4) == 1*3 + 2*4"
>>>>  * __div__
>>>>  pyeuclid and this proposal only support division by (int, long, float)
>>>>  vectypes and 3DVectorClass also do implicit elementwise division
>>>>  same for __floordiv__ and __mod__
>>>>  * __abs__
>>>>  pyeuclid returns the magnitude.
>>>>  3DVectorType returns vec3d(abs(x), abs(y), abs(z))
>>>>  vectypes and this proposal don't implement __abs__ to avoid confusion
>>>>
>>>> other differences:
>>>>  * from the mentioned packages only pyeuclid optionally supports
>>>> swizzleing
>>>>  * pyeuclid has a method "magnitude" instead of "length"
>>>>  * vectypes uses functions at a module level rather than instance
>>>> methods.
>>>>  * vectypes has a method refract
>>>>  * pyeuclid has seperate geometry classes like "point", "line", "ray"
>>>> and
>>>>  "lineSegment"
>>>>  * only 3DVectorClass and this proposal have built-in methods of
>>>>  the "rotate"-family
>>>>
>>>>
>>>> #################################################
>>>> [1] http://partiallydisassembled.net/euclid.html
>>>> [2] http://code.google.com/p/vectypes/
>>>> [3] http://pygame.org/wiki/3DVectorClass
>>>> [4]
>>>>
>>>> http://pygame.org/wiki/gsoc2009ideas#Math%20for%20pygame%20(vectors,%20matrix,%20etc<http://pygame.org/wiki/gsoc2009ideas#Math%20for%20pygame%20%28vectors,%20matrix,%20etc>
>>>> .)
>>>>
>>>
>>>
>>>
>> <div><br></div>
>>
>
>

Reply via email to