
On 9/20/06, Walter Landry <wlandry@ucsd.edu> wrote:
"Olivier Grant" <olivier.grant@gmail.com> wrote:
Hi,
I have written a bit of code to handle geometric vectors in a generic way, abstracting their dimension. The idea behind this code is to be able to apply one operation between two vectors, or a vector and a scalar, whatever their dimension, and writing it in an expandable way without having to modify any manipulation functions if a new geometric vector class is created. The other advantage is that the resulting assembly code is just as fast as if the functions had all been explicitly written.
Does this hold true if the equations get complicated (e.g. products of products)?
Not yet, currently the code was really a test to find a way to allow any type of binary function to be applyed between vectors of different dimensions and/or scalar values.
Right now I have three simple vector classes - ranging from vector2d to
vector4d - that are not templetized since I like the idea of being able to access coordinates directly by their name
vector3d vec; vec.x += 10.0f;
to give you an example of the syntax, here is how you would add two vectors of different dimensions :
vector2d v1(1.0f, 2.0f); vector3d v2(-1.0f, 3.0f, 2.0f); vector4d res;
vector_add(v1, v2, res); /* res now contains (0.0f, 5.0f, 2.0f, 1.0f) */
This is a bit clunky. What about using the operator+() and operator=()?
You could just wrap vector_add in an operator+, but the original intension was to provide not only a generic way of handling any type of binary operation between vectors and/or scalars, but also to have it compile to the most efficient code possible. I also wanted to allow the user to know exactly what he is doing when performing function calls : res = v1 * scalar + v2; I think the following syntax really makes you sure you control what is happening : vector_mul(v1, scalar, v1); vector_add(v1, v2, res); In highly sensitive software that needs to perform very fast, I think developers would prefer this kind of syntax. The other advantage I see is to easily allow developers to use this function as a default implementation eventually replacing it with a architecture specific version if necessary/possible.
the result is determined by the dimension of the third vector passed to
vector_add. v1 is auto-promoted to act like a vector3d.
This seems wrong. If I want to add a vector2d to a vector3d, then I should have to do it manually. Otherwise, it should be a type error.
it depends how you see the problem I suppose. A 2D vector is just a 3D vector with z == 0. A 3D vector is a 4D vector with w == 1. And so on by extension. Since these vector classes are not supposed to be used in a polymorphic way, each argument of a function call is well-known by the user - or at least should be :) - so I would not raise an exception in the case of the use of two vectors with different dimensions.
v2 does not change.
res gets (v1.x + v2.x, v1.y + v2.y, v1.z + v2.z , default_w_value).
I didn't seem to find any information on a lib currently under development that provides geometric vector manipulation in that way - maybe apart from uBLAS - so I thought I would share this if anyone seems to be interested.
What are the advantages of this library over tvmet[1]?
No idea! :) I didn't know of that library's existance but will definitely study it with much interest and give you that answer after if you're still interested. Cheers,
Walter Landry wlandry@ucsd.edu
Thanks for your comments/questions, Olivier.