Boost logo

Boost :

From: Andy Little (andy_at_[hidden])
Date: 2006-03-23 09:18:54


"Janek Kozicki" wrote
> Andy Little said: (by the date of Tue, 21 Mar 2006 02:00:43 -0000)
>
>> > sorry that this post got so incredibly long ;)
>>
>> No problem. I will try to reply to the other parts of your post in more
>> detail
>> soon. Overall I can see a good deal of divergence between your aims and
>> mine.
>> (That is not necessarily a bad thing of course as we would presumably be
>> aiming
>> for the most widespread use). Your applications require very good raw speed
>> performance, which I havent paid enough attention to, but I can see now why
>> you
>> will be obsessed with that from looking at YADE.
>
> I've reconsidered my "raw-speed" attitude, because from experience I've
> learnt that speed comes often uninvited along with good design. So think
> about design first, speed comes later :)
>
> My elaborate explanations about anonymous union simply demonstrate that
> full opengl compatibility comes at huge price - it forces internal data
> structure. A huge no-no in good OO design. Therefore degree of
> compatibility with opengl should be a design decision/rationale of
> this library.

Yes. I havent actually used OpenGL, but my understanding is that it is very low
level and it is possible to apply some higher level OOP above the level of the
low-level OpenGL functions, while keeping in mind the performance issue. The
C++ facilities such as inlining and namespaces and templates can be used to good
effect to simplify the use of the OpenGL API functions as well of course without
(theoretically) loss in performance. For example the OpenGL shading language
specification lists various types in section 4.1 of the shading language manual
e.g (among others)

vec2 a two component floating-point vector
vec3 a three component floating-point vector
vec4 a four component floating-point vector
bvec2 a two component Boolean vector
bvec3 a three component Boolean vector
bvec4 a four component Boolean vector
ivec2 a two component integer vector
ivec3 a three component integer vector
ivec4 a four component integer vector

With C++ templates one could represent all those in one class template

namespace gl_wrap{
     template<typename T, int Dimension,>
     struct vec;
}

Secondly, the OpenGL?vec? family above is used IIRC as a standard container for
different purposes, such as a vertex, or a color, but IMO it would be
more 'user friendly' to create a color type and a vertex type and only convert
them to their low level OpenGL ?vec? equivalents for output,

namespace gl_wrap{
template <typename ValueType>
rgb_color : gl_wrap::vec<3,Value_type> {/*...*/};

template <typename ValueType>
vertex3 : gl_wrap::vec<3,Value_type> {/*...*/};
}

Note: those two are only very naive examples and certainly not intended to be
representative
of a particular design but rather indicating that the OpenGL API doesnt need to
be followed religiously, but ideally without losing performance of course,
which can only be discovered by testing I guess.

The general thrust of the above is that I would prefer to end up with a User
Orientated design as opposed to a design which provides low level primitives of
indeterminate meaning (eg using the same vector type to hold a vertex and a
color as raw Open GL does).
The downside of using higher level Concepts is that One may end up with a
lot of structurally similar looking entities. The upside may be that what we
are really discussing is Concepts which might correspond with the SoCalled
Generic Programming approach. A simple example of the difference.

Say we have some output function.

Using the "structurally everythings equivalent approach so lets just use a
vect3" we might use a vect3 for volor and vertices:

    set Mode(RGB_COLOR) ( eg vector following is meant to be a Color)
    out << vect3(R,G,B);
    setMode(VERTEX3); ( eg vector following is meant to be a Vertex)
    out << vect3(x,y,z);

OTOH In the Concept approach vertices and colors are separate types :

    out << rgb_color(r,g,b) << vertex3(x,y,z); // Fact that compiler can
                                        //distinguish these two types is very
powerful

NB The above is probably Incredibly Obvious but I thought I'd say it anyway as
designing around Concepts is very much not a feature of raw OpenGL that I can
see.

> Fast disply in yade is much less important than geometrical computations
> themselves - related to physics of the system, not to the graphics.
>
>> Overall I have been looking at
>> ease of use. I am currently interested in integrating geometry /vectors with
>> pqs
>> library, but that would increase complexity of the implementation over just
>> using float types as you may see in my current geometry offering and will
>> also
>> affect compile times, so may be a burden giving you no benefit.
>
> I see a big potential here, if I want to use physical units, having them
> built-in inside the geometry would be pretty useful.

OK. I guess that rather than geometry what we are discussing may actually be
a library for modelling physical processes in (usually 3d but possibly 2d) space
, and time? I dont think theres a problem with
that ... except to note that geometry is a math subset of the wider physical
problem and the geometry principles do apply there.

>> That
>> difference of quaternions v matrices is interesting also. The generic nature
>> of
>> matrix transforms is at the expense of speed. It should be possible to
>> combine
>> both matrix and quaternions transforms somehow of course and I will have to
>> read
>> up on using quaternion.
>
> In fact quaternion stores rotation data in more compact form than
> matrix.

Ok. I have heard of that, but dont know the details.

> If quaternion is 'messed up' a bit, then rotation angle is just
> a bit different - hard to notice the difference. If matrix is 'messed
> up' a bit - it losts symmetry and rotation is iffy. Moreover everytime a
> vector3d is rotated by quaternion, a 3x3 matrix is built from quaternion
> (using only operations + - *). And to be honest I haven't benchamrked if
> quaterions are faster. Many people claim this, but I realized that I
> shouldn't claim it until I'll make relevant benchmarks.

I think the clue to speed is that quaternion uses a 3x3 matrix whereas a
transform matrix to do same job would be 4x4 (which is a lot more calcs many
redundant!), though 4x4 matrix can hold
information about perspective and translation which a quaternion cant AFAIK.
Also 1 matrix can hold an arbitarily complex transform by concatenating
(multiplying) a series of
matrices of simpler transforms. e.g any sequence of rotations, translations,
scalings, perspective transformations, mirror etc.

I take the point about the cleaner math involved in quaternions too though I
have to confess that I will have to work to understand the quaternion
math. Again it might be helpfull to talk about the general Concepts that a
transform entity offers, such as it can rotate , it can scale, it can translate
etc or not. It may even be possible to choose a particular coordinate
transformer at compile time by selecting the minimal /most efficient one that
fulfills the given input parameters. Keeping it simple of course !

NB You seem to be using quaternion to model a physical state, rather than as a
transform so I may have that wrong.

>> It strikes me that perhaps more detailed discussion
>> about the goals and rationale of such a library is needed too.
>
> yes, certainly. At first we should decide what entities should appear,
> how to name them, and how to sort them into namespaces, to begin with,
> that's my library:
>
> - vector2 +
> - vector3 +
> - vector4 +
> - matrix2 +
> - matrix3 +
> - matrix4 +
> - quaternion +
> - se3 +

OK. That seems like a good initial set. It would probably clarify to provide
some more description. eg purpose of and some useful operations on each entity.

In the library sketched out in the Math -Geometry director in the Vault, my idea
was to group by whether a particular entitity makes sense only in a
2D or 3D space (Which requires the emphasis on higher level Conceptual rather
than lower level general purpose entities, and two_d/ three_d namespaces) .I
tried to create primitives with more specific meanings or useage and put them in
2D/3D namespaces: e.g ( adding some other entities)

2D namespace{
// " a point in 2d space"
vertex {x,y}

// " a direction in 2d space"
vector {x,y}
// NB the issues of addition of vertices (or points) meant that a vector may
serve for both in practise. (OTOH just allow addition of vertices)

// " a 2d vertex normalised for multiplication by a homogeneous matrix"
homogeneous_vertex {x,y,h}

// not sure what this would be used for though but it would be
/ equivalent to the 3x3 matrix in the 3D namespace
//(maybe used by complex as 3D one is by quaternion?
matrix // 2 x 2

// Transform matrix. concatenate and multiply by homogeneous vector
homogeneous_matrix //(3 x 3 )

// fits here because its 2d version of quaternion AFAIK.?
 std::complex

// also some sort of physical entity with position and direction I think similar
to the "se3"
// I have called it l it a field element ?
field_element { vertex, vector}
//OR
field_element (vertex, complex}

} // ~ 2D namespace

3D namespace{

// " a point in 3D spac"
vertex // {x,y,z}

// for representing 3d vector quantities force etc
// " a direction in 3d space"
vector

// for holding 3d homogeneous coordinates
// convertible to from ordinary vertex
// Used for compatibility with 3d transform matrix
homogeneous_vertex // {x,y,z,w}

// 3 x 3 matrix Used by quaternion?
// but note a different 3x3 matrix in both 2D and
//3D namespace
matrix

// 4 x 4 transform matrix
homogeneous_matrix

 // for representing a direction? Naturally I think this makes sense in a 3D
space only?
quaternion

// physical entity with position and direction similar to the "se3"
// I have called it l it a field element ?
field_element { vertex, vector}
//OR
field_element (vertex, quaternion}

} // ~ 3D namespace

Not everything fits in 2D/ 3D of course e.g colours have nothing to do with do
with 2D or
3D (Maybe they dont in a geometry library either!)... but no problem ...give
them
their own grouping

namespace colours{
   rgb {r,g,b}
    rgba {r,g,b,a}
}

> Other readers of this list are welcome to add more components and "vote"
> by placing '+' next to it. Of course class names are subject to another
> discussion :)
>
> If you are wondering, se3 is a position/orientation combo - small class
> which contains only vector3 and a quaternion. It is used to fully
> describe a placement of an object in 3d space. I'm still not sure whether
> getting rid of it would make things simpler or not.

Right I have in mind a similarish entity but I used a position- vector (vector3)
for the
position and another using the relevant quantity ( flux_density/ circulation
etc) for the direction/magnitude ( <--- quaternion fits there? ). Called it
'field_element' I think. I guess
its also a basis for attaching spheres and boxes etc?

>> As to quanternion...is boost::quanternion not suitable for your applications
>> as
>> it stands?
>
> unfortunately not. yesterday I have examined it again, and I see that
> the author has started working in that direction (quote at bottom of
> quaternion docs webpage: "Use uBlas for the link with rotations (and
> move from the example implementation to an efficient one).").
>
> In his example I can see those familiar formulas used to build rotation
> matrix out of quaternion (in file HSO3.hpp)
>
> Perhaps he got discouraged by the fact that ublas is not a good choice
> for small vectors.

Unfortunately the documentation .
http://www.boost.org/libs/math/quaternion/TQE.pdf
iss way out of my depth:-(

 Hopefully theres a more earthy definition of quaternions somewhere !

Apologies that the above is somewhat sketchy and hope it makes some sort of
sense.

regards
Andy Little.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk