[eigen] Euler-angles and partial reductions API design

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Hi list,

I have a couple of questions regarding function names and API design,
all suggestions are welcome.


Let's start with the EulerAngles class of the geometry module. An
EulerAngles aims to represent a rotation as a sequence for 3
elementary rotations around the X, Y or Z axes. However there exist as
many conventions as orders for the axes: since an axis can be used
twice and 2 consecutive axes must be different then we have a total of
12 possibilities: XYZ, XYX, ZXY, ZXZ, etc...

Moreover, the represented rotation depends on whether we consider the
rotation of an object around fixed axes (left multiply) or whether we
consider the rotation of a local frame (right multiply). Currently the
EulerAngles class supports only the XYZ-left-multiply convention,
however with only little extra code it is possible to handle all
conventions making it much more useful. How to to specify the desired
convention ? Let's first consider the axis order, we can imagine the
following possibilities:

 * define 12 XYZ-like constants:
   EulerAngles<float, ZXZ>(a0, a1, a2);

 * define the three X, Y, and Z constants:
   EulerAngles<float, Z, X, Z>(a0, a1, a2);
   but they might easily conflict

 * simply name the axes 1, 2, 3:
   EulerAngles<float, 3, 1, 3>(a0, a1, a2);

I prefer the first option but maybe someone has a better idea. About
the the right/left multiply choice, I would make it right-multiply by
default for many reasons, one of them being to be consistent with
OpenGL. Maybe we could even only allow this convention ? (otherwise it
would be specified as an additional (and optional) template
parameter).

In the same vein, in order to tackle degree vs radian mistakes, we
could define two very small classes Degree and Radian providing
automatic conversion from one type to the other. So a function which
requires a radian would be declared: void foo(Radian angle) and
called:
foo(Degree(180)) or foo(Radian(3.14)), (and we do the same for the
returned type). This is a really safe solution (I saw that in the
rendering engine Ogre3D), but maybe it is a bit overkill and heavy to
use. So I mention it for the record, but I'm not sure at all to like
it. (btw, in eigen all angles are of course assumed to be in radian
but the confusion is easy as soon as you mix it with OpenGL code).


For the second point I'll try to be more concise ;), so what about the
partial-redux proposal which is on the Todo page, section Array
module:
http://eigen.tuxfamily.org/index.php?title=Todo#Array_module

The idea to make partial-reduction usable by adding .columnWise() and
..rowWise() members to MatrixBase giving access to partial-reduction
shortcuts.
I suggested columnWise/rowWise because I think they are much less
ambiguous than "horizontal/vertical reduction".
Also, the current templated functions verticalRedux/horizontalRedux
would be moved to the generic "PartialRedux proxy", and named "redux":
  m.columnWise().redux(myfunctor());


Even shorter, what about an automatic cast to scalar operator for 1x1
fixed size matrix ? I see 2 use cases:
- you can write: float a = vector1.transpose() * vector2;
- you can write generic multimensionnal algorithms without the the
pain of writing [0] for the 1D case.
In practice the cast operator would be protected by a static assert.


That's it for now,
cheers,
Gael.



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/