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

Re: [pygame] API draft for vector type



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 <brian@xxxxxxxxxxxxxxxxxxx> 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 <don@xxxxxxxxxxxxxxxxx> 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.)
>
>

<div><br></div>