Re: [pygame] State of the math branch
Hi, a quick update. as of rev. 2701 all build bots successfully build and test again (1). In addition to the fixes that were required to make py3k work I removed the iterator version of slerp/lerp and replaced it with a parameterized version as suggested by Patrick Mullen and Casey Duncan. I also fixed the potential memory leaks that were pointed out by Casey. The only new feature is support for extended slicing. I didn't incorporate any performance fixes that were suggested on this list. This is mainly due to lack of time and the time I have went into appeasing the build bots. I also have very little time in the next few month so don't expect much news from me in this time but I'll be back with matrices and quaternions once things settle around here. that's it for now. sincerely yours //Lorenz (1) The exception is "MacOSX_py31" build bot which seems to not work at all.
Re: [pygame] State of the math branch
On Nov 16, 2009, at 1:15 PM, Lorenz Quack wrote: The reason I allocated the memory dynamically is that I didn't want to waste the 2*sizeof(double) on Vector2 instances. but maybe we don't have to be that cheep in this day and age. especially if we can gain some speed. Another consideration is that this way we can *maybe* reuse vectors as views on rows or columns of matrices. I'm not convinced that thats a good idea or feasible but it is a thought to keep in mind. Bear in mind that there is some overhead to the allocation itself, plus many implementations allocate memory in minimum-sized, aligned chunks, so I suspect it would not save any memory allocating it separately, in fact it may use more, though it's largely a wash. In any case I'd say the best reasons not to do it are: 1. Less memory management means less bugs. And memory mgmt bugs are never very nice 8^) 2. Allocation can be relatively expensive. For small objects like this which can be created as a side effect of certain operators in expressions, it can be a measurable win to do it less. 3. It will improve the friendliness of the data structure to the processor cache. Indirection is your enemy in this regard. I like Rene's suggestion of having a pointer that normally points to a static array in the structure, but can be pointed somewhere else to retain that flexibility. That will still allow you to remove the memory management. In fact you can't use that pointer to index another data structure currently because the implementation assumes that it owns the memory it points to. With Rene's suggestion the pointer is just opaque and the vector code doesn't have to worry about releasing it. -Casey
Re: [pygame] State of the math branch
Hi, Casey Duncan wrote: I agree, I think an iterator api is not flexible enough alone, and if provided, should be in addition to one that takes an arbitrary t. -Casey On Nov 14, 2009, at 3:59 PM, Patrick Mullen wrote: I think there are many cases where one might want, say, the halfway rotated quat between two, or due to varying framerates with things like network code, (or even just for animation purposes) you might want to have varying rates, or skip to a different t value. I don't see how an iterator would be useful in these cases. You would have to do a 2 step rotation once to get the midway rotation, iterating an iterator once is pretty unintuitive; and for varying speeds during a rotation, you would need to recalculate a new iterator every frame. I haven't looked at it, but intuitively it seems to be trying to wedge one concept into a very different one. If there were only one implementation, I would much prefer the t version. Yea, Patrick made a great point. the iterator version is only useful when you draw in fixed time intervals which usually isn't the case. That's to bad as I was quite fond of the iterator idea. But well... as it stands I'll probably replace it with a t-version soon. *sniff* yours //Lorenz
Re: [pygame] State of the math branch
Hi, first of all thanks for the feedback. second I just merged the branch with the trunk. I hope I didn't mess anything up (my merging experience is *very* limited). I also implemented the generic math function René suggested. René Dudfield wrote: On Mon, Nov 16, 2009 at 6:10 PM, Casey Duncan wrote: To start with, it is great to see follow-through on this, it will be a great, long overdue, addition to the pygame api. One thing I notice is that the main vector data structure contains a pointer to the actual coordinates. Other structures just contain the coordinates in an inline array up to the max dimension. IMO the main vector data structure should have the coordinates inline as well. This will cut in half the number of heap allocations to create a vector object. I suspect that it may be common for vector objects to be created as intermediate results in calculations and immediately discarded, and eliminating the extra memory management would be a helpful optimization, and simplify the code (less memory management is always a good thing). I think the only use-case for having the pointer would be for proxying an array of vector coordinates that you could operate on en masse (ala numpy). Having the vector be a proxy for other data is big use case though. How about... There could be a double[4] inline, and have the pointer point to that data for 2,3,4 sized vectors. If it's bigger than this, it can be (py)malloc'd, and it can also refer to data via the buffer protocol. The pointer would still be where the data is, but it could be refer to the inline data if needed. The reason I allocated the memory dynamically is that I didn't want to waste the 2*sizeof(double) on Vector2 instances. but maybe we don't have to be that cheep in this day and age. especially if we can gain some speed. Another consideration is that this way we can *maybe* reuse vectors as views on rows or columns of matrices. I'm not convinced that thats a good idea or feasible but it is a thought to keep in mind. A further optimization to consider would be an instance pool for vectors. If I'm right, and vectors are created and destroyed a lot in certain applications, having a pool of unused instances lying around could be a real win. This is how Python optimizes tuple object creation. +1 pygame could use this technique all over. I think using pymalloc can give us this automatically... or close to automatically. There's some notes here about performance here of pymalloc Vs free lists(python terminology for memory pools): http://bugs.python.org/issue2039 Probably not as fast as a specific memory pool... but maybe pymalloc would come close. Yes. but before I totally agree I would like to see some benchmarks. But this is an implementation detail. Until now I didn't focus on performance. My main concern was a nice API. But that doesn't mean you shouldn't keep posting suggestions on how to improve all aspects! I didn't check thoroughly for this, but you need to be careful with code like this (in vector_elementwiseproxy_pow): for (i = 0; i < dim; i++) { base = PyFloat_FromDouble(bases[i]); expo = PyFloat_FromDouble(expos[i]); result = PyNumber_Power(base, expo, Py_None); if (!result) return NULL; ret->coords[i] = PyFloat_AsDouble(result); Py_DECREF(result); Py_DECREF(expo); Py_DECREF(base); } For one, PyFloat_FromDouble can return NULL, and I'm not sure what PyNumber_Power will do when passed a NULL arg. Assuming it doesn't crash and returns NULL, you may be leaking references to base or expo. It's probably safer to assume PyNumber_Power will crash however, which is very bad since it will mask the memory problem with a segfault. All of this conversion back and forth from Python floats seems unnecessary, however. Can't you just use the libc pow() function directly instead, saving all the PyFloat business? good idea Well, I looked at the pow implementation of float objects in python-trunk and they were catching some corner-cases and platform quirks. I wanted to take advantage of their work. of course we could decide that performance is paramount and people will have to live with whatever quirks their libc might have. Note that the python math module did take this route which simply interfaces the libc functions. On the bad error handling and potential memory leaks you are 100% right! I'm also curious what the use-case is for enabling and disabling swizzling? I know I've seen other libraries that have this switch (Euclid?), but why not just leave it on all of the time? Too error prone? Well I for one had never heard of swizzling before I looked at euclid. And I imagine I would have been deeply confused if vec.xyz = (1,2,3) wouldn't add a new attribute. That's why I disabled swizzling per default. More or less personal preference. again, thanks for the feedback! yours //Lorenz
Re: [pygame] State of the math branch
On Mon, Nov 16, 2009 at 6:10 PM, Casey Duncan wrote: > To start with, it is great to see follow-through on this, it will be a > great, long overdue, addition to the pygame api. > > One thing I notice is that the main vector data structure contains a pointer > to the actual coordinates. Other structures just contain the coordinates in > an inline array up to the max dimension. IMO the main vector data structure > should have the coordinates inline as well. This will cut in half the number > of heap allocations to create a vector object. I suspect that it may be > common for vector objects to be created as intermediate results in > calculations and immediately discarded, and eliminating the extra memory > management would be a helpful optimization, and simplify the code (less > memory management is always a good thing). I think the only use-case for > having the pointer would be for proxying an array of vector coordinates that > you could operate on en masse (ala numpy). > Having the vector be a proxy for other data is big use case though. How about... There could be a double[4] inline, and have the pointer point to that data for 2,3,4 sized vectors. If it's bigger than this, it can be (py)malloc'd, and it can also refer to data via the buffer protocol. The pointer would still be where the data is, but it could be refer to the inline data if needed. > A further optimization to consider would be an instance pool for vectors. If > I'm right, and vectors are created and destroyed a lot in certain > applications, having a pool of unused instances lying around could be a real > win. This is how Python optimizes tuple object creation. > +1 pygame could use this technique all over. I think using pymalloc can give us this automatically... or close to automatically. There's some notes here about performance here of pymalloc Vs free lists(python terminology for memory pools): http://bugs.python.org/issue2039 Probably not as fast as a specific memory pool... but maybe pymalloc would come close. > I didn't check thoroughly for this, but you need to be careful with code > like this (in vector_elementwiseproxy_pow): > > for (i = 0; i < dim; i++) { > base = PyFloat_FromDouble(bases[i]); > expo = PyFloat_FromDouble(expos[i]); > result = PyNumber_Power(base, expo, Py_None); > if (!result) > return NULL; > ret->coords[i] = PyFloat_AsDouble(result); > Py_DECREF(result); > Py_DECREF(expo); > Py_DECREF(base); > } > > For one, PyFloat_FromDouble can return NULL, and I'm not sure what > PyNumber_Power will do when passed a NULL arg. Assuming it doesn't crash and > returns NULL, you may be leaking references to base or expo. It's probably > safer to assume PyNumber_Power will crash however, which is very bad since > it will mask the memory problem with a segfault. All of this conversion back > and forth from Python floats seems unnecessary, however. > Can't you just use > the libc pow() function directly instead, saving all the PyFloat business? > good idea > I'm also curious what the use-case is for enabling and disabling swizzling? > I know I've seen other libraries that have this switch (Euclid?), but why > not just leave it on all of the time? Too error prone? > > -Casey >
Re: [pygame] State of the math branch
I agree, I think an iterator api is not flexible enough alone, and if provided, should be in addition to one that takes an arbitrary t. -Casey On Nov 14, 2009, at 3:59 PM, Patrick Mullen wrote: I think there are many cases where one might want, say, the halfway rotated quat between two, or due to varying framerates with things like network code, (or even just for animation purposes) you might want to have varying rates, or skip to a different t value. I don't see how an iterator would be useful in these cases. You would have to do a 2 step rotation once to get the midway rotation, iterating an iterator once is pretty unintuitive; and for varying speeds during a rotation, you would need to recalculate a new iterator every frame. I haven't looked at it, but intuitively it seems to be trying to wedge one concept into a very different one. If there were only one implementation, I would much prefer the t version. On Sat, Nov 14, 2009 at 11:06 AM, Lorenz Quack wrote: Hi René, René Dudfield wrote: Feel free to merge it into the trunk. It'll be easier for other people to try it out(binaries, and other things hooked up with trunk), and you can also use the build bot to check for errors on other platforms(like compilation/testing). Ok. I'll see if I can make it this weekend. The (s)lerp idea with the iterator seems a good one. I've been thinking about doing something like that with line drawing functions... that instead of drawing return the (x,y) coords of where it would draw pixels. I wonder if it still might be useful to let people supply a t argument, just because people are used to it... My hope is that the iterator is intuitive enough so nobody will miss the t-version. also my version should perform better because it only calculates a rotation-matrix once while otherwise you would have to recalculate it on every call for the new t-value. So for now I would stay with: "There should be one-- and preferably only one --obvious way to do it." and wait and see if there is strong demand for a t-argument version. However, they could just supply one step. unfortunately I don't think it's that easy to convert from the iterator interface to the t-arg interface. you would have to something like this: def slerp_t(start_vec, end_vec, t): idx, steps = t.as_integer_ratio() # new in python 2.6 return list(start_vec.slerp(end_vec, steps))[idx] which is pretty ugly. I guess there is going to be a 4 element quaternion? What about a Vector4? Which matrix sizes are you thinking of doing? I guess 3x3, 3x4 and 4x4? Or just 4x4? I was planing on implementing quaternions and only square matrices. Is there a use for Vector4? Implementing it would be quite easy but do we need it? Also, what would be a use case for non-square matrices? I noticed one commit log said there was trouble with the buffer interface? Is this part still a trouble? Yea. I didn't really understand which parts of the buffer protocol belong to the 2.x protocol and which belong to 3.x and what should be supported. In general I found this topic a bit confusing and the docs didn't help. I have to look into that some other time when I've got the nerve for it. Functions like vector_elementwiseproxy_mul, vector_elementwiseproxy_sub etc, could probably share a lot of code, and then for the different part use a switch statement to do the different function. Something like this: static PyObject * vector_elementwiseproxy_mul(PyObject *o1, PyObject *o2) { return vector_elementwiseproxy_generic(o1, o2, VECT_OPS_MUL); } Where the vector_elementwiseproxy_generic function would have the switch statement on the various flags passed in. I'll take a look at it. thanks for the feedback. looking forward to more of it :) yours //Lorenz On Thu, Nov 12, 2009 at 10:31 AM, wrote: Hi List, I just wanted to give you a short summery of the development in the math branch. The goal of the math branch is the inclusion of several math related types like vectors, matrices and quaternions. Right now I consider the implementation of vectors in 2 and 3 dimensions as feature complete. What this means is that I can't think of more functionality that I want to implement and all methods pass their unit tests. I encourage everyone interested to take a look and make suggestions if they find functionality missing. The current version is not written for maximum performance. For example Vector2 and Vector3 share many functions so no dimension specific optimizations are implemented. So the current implementation should be considered a baseline for future optimizations. To gauge future improvements I intend to write a rudimentary performance benchmark. I don't consider the API to be set in stone. Especially concerning mutability. Currently vectors are mutable. If however it turns out that there is no significant performance hit in making them immutable I tend to do so. Obviously this wil
Re: [pygame] State of the math branch
To start with, it is great to see follow-through on this, it will be a great, long overdue, addition to the pygame api. One thing I notice is that the main vector data structure contains a pointer to the actual coordinates. Other structures just contain the coordinates in an inline array up to the max dimension. IMO the main vector data structure should have the coordinates inline as well. This will cut in half the number of heap allocations to create a vector object. I suspect that it may be common for vector objects to be created as intermediate results in calculations and immediately discarded, and eliminating the extra memory management would be a helpful optimization, and simplify the code (less memory management is always a good thing). I think the only use-case for having the pointer would be for proxying an array of vector coordinates that you could operate on en masse (ala numpy). A further optimization to consider would be an instance pool for vectors. If I'm right, and vectors are created and destroyed a lot in certain applications, having a pool of unused instances lying around could be a real win. This is how Python optimizes tuple object creation. I didn't check thoroughly for this, but you need to be careful with code like this (in vector_elementwiseproxy_pow): for (i = 0; i < dim; i++) { base = PyFloat_FromDouble(bases[i]); expo = PyFloat_FromDouble(expos[i]); result = PyNumber_Power(base, expo, Py_None); if (!result) return NULL; ret->coords[i] = PyFloat_AsDouble(result); Py_DECREF(result); Py_DECREF(expo); Py_DECREF(base); } For one, PyFloat_FromDouble can return NULL, and I'm not sure what PyNumber_Power will do when passed a NULL arg. Assuming it doesn't crash and returns NULL, you may be leaking references to base or expo. It's probably safer to assume PyNumber_Power will crash however, which is very bad since it will mask the memory problem with a segfault. All of this conversion back and forth from Python floats seems unnecessary, however. Can't you just use the libc pow() function directly instead, saving all the PyFloat business? I'm also curious what the use-case is for enabling and disabling swizzling? I know I've seen other libraries that have this switch (Euclid?), but why not just leave it on all of the time? Too error prone? -Casey On Nov 14, 2009, at 4:45 AM, René Dudfield wrote: Hi, sweet :) Nice work. Feel free to merge it into the trunk. It'll be easier for other people to try it out(binaries, and other things hooked up with trunk), and you can also use the build bot to check for errors on other platforms(like compilation/testing). Sorry, I haven't had a chance to review it much. Hopefully will get a chance to have a play, and a read of the code later this weekend some time. ps, here's the svn link for anyone else who would like to read over it http://www.seul.org/viewcvs/viewcvs.cgi/branches/math_module/?root=PyGame&sortby=date The (s)lerp idea with the iterator seems a good one. I've been thinking about doing something like that with line drawing functions... that instead of drawing return the (x,y) coords of where it would draw pixels. I wonder if it still might be useful to let people supply a t argument, just because people are used to it... However, they could just supply one step. Having them share implementations is probably a good thing to reduce the complexity of the code. I guess there is going to be a 4 element quaternion? What about a Vector4? Which matrix sizes are you thinking of doing? I guess 3x3, 3x4 and 4x4? Or just 4x4? I noticed one commit log said there was trouble with the buffer interface? Is this part still a trouble? Functions like vector_elementwiseproxy_mul, vector_elementwiseproxy_sub etc, could probably share a lot of code, and then for the different part use a switch statement to do the different function. Something like this: static PyObject * vector_elementwiseproxy_mul(PyObject *o1, PyObject *o2) { return vector_elementwiseproxy_generic(o1, o2, VECT_OPS_MUL); } Where the vector_elementwiseproxy_generic function would have the switch statement on the various flags passed in. cheers, On Thu, Nov 12, 2009 at 10:31 AM, wrote: Hi List, I just wanted to give you a short summery of the development in the math branch. The goal of the math branch is the inclusion of several math related types like vectors, matrices and quaternions. Right now I consider the implementation of vectors in 2 and 3 dimensions as feature complete. What this means is that I can't think of more functionality that I want to implement and all methods pass their unit tests. I encourage everyone interested to take a look and make suggestions if they find functionality missing. The current version is not written for maximum performance. For example Vector2 and Vector3 sha
Re: [pygame] State of the math branch
Lorenz Quack wrote: Also, what would be a use case for non-square matrices? Mapping coordinates in R^3 to coordinates in R^2 can be readily accomplished with a 2x3 matrix. To generalize, an m x n matrix can be used to linearly transform R^n --> R^m. Jeff Cagle
Re: [pygame] State of the math branch
I think there are many cases where one might want, say, the halfway rotated quat between two, or due to varying framerates with things like network code, (or even just for animation purposes) you might want to have varying rates, or skip to a different t value. I don't see how an iterator would be useful in these cases. You would have to do a 2 step rotation once to get the midway rotation, iterating an iterator once is pretty unintuitive; and for varying speeds during a rotation, you would need to recalculate a new iterator every frame. I haven't looked at it, but intuitively it seems to be trying to wedge one concept into a very different one. If there were only one implementation, I would much prefer the t version. On Sat, Nov 14, 2009 at 11:06 AM, Lorenz Quack wrote: > Hi René, > > René Dudfield wrote: >> >> Feel free to merge it into the trunk. It'll be easier for other >> people to try it out(binaries, and other things hooked up with trunk), >> and you can also use the build bot to check for errors on other >> platforms(like compilation/testing). > > Ok. I'll see if I can make it this weekend. > >> The (s)lerp idea with the iterator seems a good one. I've been >> thinking about doing something like that with line drawing >> functions... that instead of drawing return the (x,y) coords of where >> it would draw pixels. I wonder if it still might be useful to let >> people supply a t argument, just because people are used to it... > > My hope is that the iterator is intuitive enough so nobody will miss the > t-version. also my version should perform better because it only > calculates a rotation-matrix once while otherwise you would have to > recalculate it on every call for the new t-value. > So for now I would stay with: > "There should be one-- and preferably only one --obvious way to do it." > and wait and see if there is strong demand for a t-argument version. > >> However, they could just supply one step. > > unfortunately I don't think it's that easy to convert from the iterator > interface to the t-arg interface. you would have to something like this: > > def slerp_t(start_vec, end_vec, t): > idx, steps = t.as_integer_ratio() # new in python 2.6 > return list(start_vec.slerp(end_vec, steps))[idx] > > which is pretty ugly. > >> I guess there is going to be a 4 element quaternion? What about a >> Vector4? Which matrix sizes are you thinking of doing? I guess 3x3, >> 3x4 and 4x4? Or just 4x4? > > I was planing on implementing quaternions and only square matrices. > Is there a use for Vector4? Implementing it would be quite easy but > do we need it? > Also, what would be a use case for non-square matrices? > >> I noticed one commit log said there was trouble with the buffer >> interface? Is this part still a trouble? > > Yea. I didn't really understand which parts of the buffer protocol belong > to the 2.x protocol and which belong to 3.x and what should be supported. > In general I found this topic a bit confusing and the docs didn't help. > I have to look into that some other time when I've got the nerve for it. > >> Functions like vector_elementwiseproxy_mul, >> vector_elementwiseproxy_sub etc, could probably share a lot of code, >> and then for the different part use a switch statement to do the >> different function. Something like this: >> >> static PyObject * >> vector_elementwiseproxy_mul(PyObject *o1, PyObject *o2) { >> return vector_elementwiseproxy_generic(o1, o2, VECT_OPS_MUL); >> } >> >> Where the vector_elementwiseproxy_generic function would have the >> switch statement on the various flags passed in. > > I'll take a look at it. > > thanks for the feedback. looking forward to more of it :) > > yours > //Lorenz > >> >> On Thu, Nov 12, 2009 at 10:31 AM, wrote: >>> >>> Hi List, >>> >>> I just wanted to give you a short summery of the development in the math >>> branch. >>> The goal of the math branch is the inclusion of several math related >>> types >>> like vectors, matrices and quaternions. >>> >>> Right now I consider the implementation of vectors in 2 and 3 dimensions >>> as >>> feature complete. >>> What this means is that I can't think of more functionality that I want >>> to >>> implement and all methods pass their unit tests. >>> I encourage everyone interested to take a look and make suggestions if >>> they >>> find functionality missing. >>> >>> The current version is not written for maximum performance. >>> For example Vector2 and Vector3 share many functions so no dimension >>> specific >>> optimizations are implemented. So the current implementation should be >>> considered a baseline for future optimizations. >>> To gauge future improvements I intend to write a rudimentary performance >>> benchmark. >>> >>> I don't consider the API to be set in stone. Especially concerning >>> mutability. Currently vectors are mutable. >>> If however it turns out that there is no significant performance hit in >>> making them immutable I tend to do so. >>> Obviously
Re: [pygame] State of the math branch
Hi René, René Dudfield wrote: Feel free to merge it into the trunk. It'll be easier for other people to try it out(binaries, and other things hooked up with trunk), and you can also use the build bot to check for errors on other platforms(like compilation/testing). Ok. I'll see if I can make it this weekend. The (s)lerp idea with the iterator seems a good one. I've been thinking about doing something like that with line drawing functions... that instead of drawing return the (x,y) coords of where it would draw pixels. I wonder if it still might be useful to let people supply a t argument, just because people are used to it... My hope is that the iterator is intuitive enough so nobody will miss the t-version. also my version should perform better because it only calculates a rotation-matrix once while otherwise you would have to recalculate it on every call for the new t-value. So for now I would stay with: "There should be one-- and preferably only one --obvious way to do it." and wait and see if there is strong demand for a t-argument version. However, they could just supply one step. unfortunately I don't think it's that easy to convert from the iterator interface to the t-arg interface. you would have to something like this: def slerp_t(start_vec, end_vec, t): idx, steps = t.as_integer_ratio() # new in python 2.6 return list(start_vec.slerp(end_vec, steps))[idx] which is pretty ugly. I guess there is going to be a 4 element quaternion? What about a Vector4? Which matrix sizes are you thinking of doing? I guess 3x3, 3x4 and 4x4? Or just 4x4? I was planing on implementing quaternions and only square matrices. Is there a use for Vector4? Implementing it would be quite easy but do we need it? Also, what would be a use case for non-square matrices? I noticed one commit log said there was trouble with the buffer interface? Is this part still a trouble? Yea. I didn't really understand which parts of the buffer protocol belong to the 2.x protocol and which belong to 3.x and what should be supported. In general I found this topic a bit confusing and the docs didn't help. I have to look into that some other time when I've got the nerve for it. Functions like vector_elementwiseproxy_mul, vector_elementwiseproxy_sub etc, could probably share a lot of code, and then for the different part use a switch statement to do the different function. Something like this: static PyObject * vector_elementwiseproxy_mul(PyObject *o1, PyObject *o2) { return vector_elementwiseproxy_generic(o1, o2, VECT_OPS_MUL); } Where the vector_elementwiseproxy_generic function would have the switch statement on the various flags passed in. I'll take a look at it. thanks for the feedback. looking forward to more of it :) yours //Lorenz On Thu, Nov 12, 2009 at 10:31 AM, wrote: Hi List, I just wanted to give you a short summery of the development in the math branch. The goal of the math branch is the inclusion of several math related types like vectors, matrices and quaternions. Right now I consider the implementation of vectors in 2 and 3 dimensions as feature complete. What this means is that I can't think of more functionality that I want to implement and all methods pass their unit tests. I encourage everyone interested to take a look and make suggestions if they find functionality missing. The current version is not written for maximum performance. For example Vector2 and Vector3 share many functions so no dimension specific optimizations are implemented. So the current implementation should be considered a baseline for future optimizations. To gauge future improvements I intend to write a rudimentary performance benchmark. I don't consider the API to be set in stone. Especially concerning mutability. Currently vectors are mutable. If however it turns out that there is no significant performance hit in making them immutable I tend to do so. Obviously this will only happen once I have some performance results. After that Matrices will be up next. thanks for your time and suggestions. //Lorenz PS: I feel that I should briefly comment on the slerp() method. I did not follow the default implementation that seems to be prevalent on the Internet. There you repeatedly call the slerp method with a varying parameter t. I felt this is unpythonic. In my implementation you pass the number of steps you want into the method which then returns an iterator yielding the interpolating vectors. Same applies to the lerp() method. Also the algorithm for slerp() is a bit different as to support interpolation to a vector of different length.
Re: [pygame] State of the math branch
Hi, sweet :) Nice work. Feel free to merge it into the trunk. It'll be easier for other people to try it out(binaries, and other things hooked up with trunk), and you can also use the build bot to check for errors on other platforms(like compilation/testing). Sorry, I haven't had a chance to review it much. Hopefully will get a chance to have a play, and a read of the code later this weekend some time. ps, here's the svn link for anyone else who would like to read over it http://www.seul.org/viewcvs/viewcvs.cgi/branches/math_module/?root=PyGame&sortby=date The (s)lerp idea with the iterator seems a good one. I've been thinking about doing something like that with line drawing functions... that instead of drawing return the (x,y) coords of where it would draw pixels. I wonder if it still might be useful to let people supply a t argument, just because people are used to it... However, they could just supply one step. Having them share implementations is probably a good thing to reduce the complexity of the code. I guess there is going to be a 4 element quaternion? What about a Vector4? Which matrix sizes are you thinking of doing? I guess 3x3, 3x4 and 4x4? Or just 4x4? I noticed one commit log said there was trouble with the buffer interface? Is this part still a trouble? Functions like vector_elementwiseproxy_mul, vector_elementwiseproxy_sub etc, could probably share a lot of code, and then for the different part use a switch statement to do the different function. Something like this: static PyObject * vector_elementwiseproxy_mul(PyObject *o1, PyObject *o2) { return vector_elementwiseproxy_generic(o1, o2, VECT_OPS_MUL); } Where the vector_elementwiseproxy_generic function would have the switch statement on the various flags passed in. cheers, On Thu, Nov 12, 2009 at 10:31 AM, wrote: > > Hi List, > > I just wanted to give you a short summery of the development in the math > branch. > The goal of the math branch is the inclusion of several math related types > like vectors, matrices and quaternions. > > Right now I consider the implementation of vectors in 2 and 3 dimensions as > feature complete. > What this means is that I can't think of more functionality that I want to > implement and all methods pass their unit tests. > I encourage everyone interested to take a look and make suggestions if they > find functionality missing. > > The current version is not written for maximum performance. > For example Vector2 and Vector3 share many functions so no dimension specific > optimizations are implemented. So the current implementation should be > considered a baseline for future optimizations. > To gauge future improvements I intend to write a rudimentary performance > benchmark. > > I don't consider the API to be set in stone. Especially concerning > mutability. Currently vectors are mutable. > If however it turns out that there is no significant performance hit in > making them immutable I tend to do so. > Obviously this will only happen once I have some performance results. > > After that Matrices will be up next. > > > thanks for your time and suggestions. > > //Lorenz > > > PS: I feel that I should briefly comment on the slerp() method. > I did not follow the default implementation that seems to be prevalent on > the Internet. There you repeatedly call the slerp method with a varying > parameter t. I felt this is unpythonic. In my implementation you pass the > number of steps you want into the method which then returns an iterator > yielding the interpolating vectors. Same applies to the lerp() method. > Also the algorithm for slerp() is a bit different as to support > interpolation to a vector of different length. > > >
[pygame] State of the math branch
Hi List, I just wanted to give you a short summery of the development in the math branch. The goal of the math branch is the inclusion of several math related types like vectors, matrices and quaternions. Right now I consider the implementation of vectors in 2 and 3 dimensions as feature complete. What this means is that I can't think of more functionality that I want to implement and all methods pass their unit tests. I encourage everyone interested to take a look and make suggestions if they find functionality missing. The current version is not written for maximum performance. For example Vector2 and Vector3 share many functions so no dimension specific optimizations are implemented. So the current implementation should be considered a baseline for future optimizations. To gauge future improvements I intend to write a rudimentary performance benchmark. I don't consider the API to be set in stone. Especially concerning mutability. Currently vectors are mutable. If however it turns out that there is no significant performance hit in making them immutable I tend to do so. Obviously this will only happen once I have some performance results. After that Matrices will be up next. thanks for your time and suggestions. //Lorenz PS: I feel that I should briefly comment on the slerp() method. I did not follow the default implementation that seems to be prevalent on the Internet. There you repeatedly call the slerp method with a varying parameter t. I felt this is unpythonic. In my implementation you pass the number of steps you want into the method which then returns an iterator yielding the interpolating vectors. Same applies to the lerp() method. Also the algorithm for slerp() is a bit different as to support interpolation to a vector of different length.