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

Re: [pygame] Re: removing 'experimental' notice from pygame.math



I've done a much larger review and testing.
Comparing it to different vector implementations,
and looking at how it inter-operates with pygame and OpenGL APIs.

TLDR; these things need to be fixed:
- scalar construction is buggy.
- One naming improvement I'd like help with is .elementwise() ? I think it's too long.
- float('NaN') and float('inf') behaviour is not tested.
- Construction from Color, and Rect needs to be defined.

There's other useful functionality that could be added later I think.

I'll finish off the narrative documentation and example program,
and then await feedback before the Experimental notice is lifted.
This process has already uncovered a bunch of things that
are missing, so I expect more to pop up.

IMHO, it's already one of the best vector2/vector3 implementations in python.
And I like that people will be able to use their knowledge of this API with GLSL (a bit).



A) GLSL shadling language vectors
    https://en.wikibooks.org/wiki/GLSL_Programming/Vector_and_Matrix_Operations#Components
    https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf

Here's what I've found missing/different.

1) Single scalar constructor should
    Vector2(1) == Vector2(1, 1)
   # currently it makes Vector2(1, 0)

2) Lower dimensional to higher dimension contructors should work:
    Vector3(1, Vector2(2, 3)) == Vector3(1, 2, 3)

3) the GLSL documentation uses "component wise", whereas we use elementwise()
  Additionally, I think elementwise() is quite long, and should probably be a property.
  A shorter name here would be nice.


4) Missing functions:
    abs
        abs(Vector2(2,-1).elementwise()) works.
    sign
    floor
    trunc
    round
    roundEven
    ceil
    fract
    mod
    modf
    min
    max
    clamp
    mix
    step
    smoothstep

    faceForward are missing
    ... more


Section 8.3, Common Functions
    https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.30.pdf

The functions operate component wise.
Vector2(1, 3).min(Vector2(4, -2)) == Vector2(1, -2)

We have min() and max() in python, but unfortunately they use some weird magic, and not a dunder magic method.

"Classes that act like numbers"
http://www.diveintopython3.net/special-method-names.html#acts-like-number
  __floor__
  __ceil__
  __trunc__

5) swizzling only there with xyzw

Seems like rgba, and stpq should be available.

{x, y, z, w}
Useful when accessing vectors that represent points or normals
{r, g, b, a} Useful when accessing vectors that represent colors

{s, t, p, q}
Useful when accessing vectors that represent texture coordinates

Perhaps vec3.rgb would return a pygame.Color




B) Compared to the CookBook 2d vector class...
https://www.pygame.org/wiki/2DVectorClass


missing:
    get_angle()
    perpendicular
        http://mathworld.wolfram.com/PerpendicularVector.html
    perpendicular_normal
    projection (not in here, but the inverse is the rejection)
        https://en.wikipedia.org/wiki/Vector_projection


C) Compred to box2d vec2

https://github.com/pybox2d/pypybox2d/blob/master/pypybox2d/src/vec2module.c

missing:
    contains() isn't there, but you can do:
      2 in v2
    clamp
    min
    max



D) pyeuclid

    rotate_around(axis, theta)
        https://github.com/ezag/pyeuclid/blob/master/euclid.py#L565
    copy()
        Rect, and Surface have this in pygame too
        Vector2(Vector2(1,2)) work however.


E) planar

https://pythonhosted.org/planar/vectorref.html
    almost_equals
        https://pythonhosted.org/planar/vectorref.html#planar.Vec2.almost_equals
        Should be called isclose like python3.5+ math.isclose
            https://docs.python.org/3/library/math.html#math.isclose
    scaled_to
        https://pythonhosted.org/planar/vectorref.html#planar.Vec2.scaled_to
    perpendicular
    clamped



Extras

Additional functionality not done is the buffer stuff. Which is commented out in math.c
I guess the purpose is to allow a Vector2/3 to act with it's storage coming in
an array. This would be super useful if you allocated a big array and wanted
to act on one element easily. Again, I think this could come later without harming
backwards compatibility.

There is partial support in the code for a Vector4.
There's nothing done for 2x2, 3x3 or 4x4 matrix.
Which are all quite useful in games (and in GLSL).
These can all come later without harming backwards compatibility.

Existing pygame APIs.

There are some differences between Vector3 and Rect and Color types.

Vectors allow some niceties which people might come to expect from Rect and Color.
    v2[:] = (3,4)
    v2.xy = (3,4)
    Vector3(0) -> Vector3(0, 0, 0)

Also, Rect has methods like copy() which are missing in Vector3.

Passing a color into pygame gives a very strange result.
    >>> Vector2(pygame.Color(2,3,4, 111))
    <Vector2(3.37522e+07, 0)>

I think Vector3(Color('red')) should work to give you Vector(1, 0, 0).
And Vector3(Color(255, 255, 255)) should give you Vector3(1, 1, 1).

Or maybe not. Maybe it should raise an error because Color is 4 elements.

Vector3().rgb = Color(255, 255, 255) makes a lot more sense to be Vector3(1, 1, 1).


Should a rect be able to to be used to construct a Vector2?
Especially when people have been using rects for the position of things.

    >>> Vector2(pygame.Rect(2,3,4,111))
    ValueError: Vector2 must be initialized with 2 real numbers or a sequence of 2 real numbers

It should use the x, and y parts of a rect. IMHO.
    >>> Vector2(pygame.Rect(2,3,4,111))
    Vector2(2, 3)




OpenGL API interactions.

    Converting in another direction would be useful.
    Where OpenGL has y at the bottom left.
    Getting OpenGL compat coords would be nice.
    Requires knowledge of screen height/axis dimensions.
   
pymunk intergration.

    pymunk already has some pygame utils which do swapping of Y coordinates.
    Would be good to consider that.




On Tue, Feb 27, 2018 at 11:43 AM, René Dudfield <renesd@xxxxxxxxx> wrote:
I won't move pygame.math.Vector2/3 into pygame or pygame.locals namespace for now.
That's potentially breaking things which already have their own Vector2/3.
This type of API change will wait for pygame 2.

Narrative documentation is missing, and I'm working on that now.