Re: [eigen] Euler-angles and partial reductions API design

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


On Fri, Jul 18, 2008 at 11:10 PM, Benoît Jacob <jacob@xxxxxxxxxxxxxxx> wrote:
> I agree with you that operation on the right should be the default, as it's
> what OpenGL does. Whence the naming used in Eigen1. What I don't understand
> is how this is any issue in Eigen2 and the draft eulerangles API ? I mean,
> when you write rotationX(angleX) * m it's obviously multiplying m on the
> left; in Eigen1 or OpenGL it's more problematic because of the API not using
> natural math notation.

the issue is if we have a class (or function) which build a rotation
directly from 3 angles:

EulerAngles<float>(a0, a1, a2)

there might be 24 interpretations !!

in my second mail, I suggested to create only elementary rotations and
compose them manually such that there is no ambiguity:

rotationX(a0) * rotationY(a1) * rotationX(a2)


> The idea that I like best, among the ones you propose, is static
> MatrixBase::rotation{XYZ} functions. Let's not use functor classes unless
> needed, and I don't see the need here.

I was not referring to functor, but something like that:

template<typename Scalar>
class RotationX : public Matrix<Scalar,3,3> {
public:
 Rotation(Scalar angle) { *this << .....sin, cos,....; }
};

anyway, maybe not very good as it creates new types...

In that case we indeed build matrices, so the composition of several
elementary rotations would not be optimal but:
1 - not too bad, for 3 rotations (i.e., 2 products) we have 54 ops
versus 21 ops...
2 - I don't see any use case where the perf of euler angles is
critical, again for me euler angles are not an optimization,
      they are just a convenient way to setup the orientation of an object.

So, if you think that:

Matrix3f m2 = AngleAxis<float>(a1, Vector3f(1,0,0))
             * AngleAxis<float>(a2, Vector3f(0,1,0))
             * AngleAxis<float>(a3, Vector3f(0,0,1));

is not verbose and as easy to read as the version with RotationX(),
then let's just forget about Euler angles, and we are done.
But I would prefer to propose a shorter and safer path... IMO, writing
the basis vectors manually with Vector3f(0,1,0) is quite error prone
(you know, dyslexia etc.).

So, maybe with two typedef for AngleAxis<float / double>, and more
general shortcuts to write the basis vectors would be a good option as
well:

 Vector3f::UnitX();
 Vector3f::UnitY();
 Vector3f::UnitZ();
 Vector4f::UnitW();
and a generic:
 VectorXf::Unit(i)

 and they could simply return "identity().col(i)".


what do you think ?

gael.


> Indeed a EulerAngles class is needed
> because if rotation{XYZ} returned a matrix then doing
> rotationX(angleX)*rotationY(angleY)*rotationZ(angleZ)
> would be terribly inefficient. So rotation{XYZ} returns a EulerAngles object
> and the actual rotationation matrix is computed in operator= or
> EulerAngles::operator*(vector) (yes this lends itself very well to
> optimization and suddenly I think this could be the most useful use case for
> EulerAngles).
>
> I'm not a fan of the last option with typedefs, because "Xf" means
> dynamic-size-float so at least the naming is misleading (and as I said I
> prefer functions over short functor classes anyway).
>
> There is one thing that needs to be discussed. The whole point of EulerAngles
> is performance -- otherwise we could do as in Eigen1, i.e. do only a generic
> rotation(angle,vector) method. In many cases, the user will use only one
> eulerAngle, i.e.
> Matrix3f::rotationY(pi/12) * vector
> We don't want the EulerAngle::operator* to compute three sin/cos pairs when
> only one is needed! So the EulerAngles class is not so trivial to implement,
> There are up to 7 cases to handle,
> X, Y, Z, XY, YZ, XZ, XYZ,
> it looks a bit tedious. It might be possible to avoid the tediousness at zero
> overhead using template magic, but that is probably even more cumbersome to
> write!
>
> Cheers,
>
> Benoit
>
>
> On Friday 18 July 2008 02:00:15 Gael Guennebaud wrotationatione:
>> I agree Euler angles are somewhat useless (and might even be dangerous
>> for the beginners because of their apparent simplicity). Nevertheless
>> they remain really conveniant to specify/initialize the orientation of
>> an object as a concatenation of elementary rotationationations. In this
> context
>> I think it very important to be able to specify the order, otherwise
>> we completely miss the convenience point. So if we agree this is the
>> only use case, then we can drop the EulerAngles class, and provide and
>> alternative, more explicit and generic API. Actually currently it is
>> possible to mimic the proposed:
>>
>>   Matrix3f m = EulerAngles<float,XYZ>(1,2,3);
>>
>> by
>>
>>   Matrix3f m2 = AngleAxis<float>(1, Vector3f(1,0,0))
>>               * AngleAxis<float>(2, Vector3f(0,1,0))
>>               * AngleAxis<float>(3, Vector3f(0,0,1));
>>
>> that is a bit heavy (though quite often 1 or 2 elementary
> rotationationations
>> are enough to reach the desired orientation).
>> So what we could do is to make easier the creation of elementary
>> rotationationations using either:
>>
>> * static functions of Matrix:
>>   Matrix3f m = Matrix3f::rotationationX(1) * Matrix3f::rotationationY(2) *
> Matrix3f::rotationationZ(3);
>>
>> * super short classes inheriting Matrix<Scalar,3,3> (or global functions)
>>   Matrix3f m = rotationationX<float>(1) * rotationationY<float>(2) *
> rotationationZ<float>(3);
>>
>> * the same with typedef  (or alias):
>>   Matrix3f m = rotationationXf(1) * rotationationYf(2) * rotationationZf(3);
>>
>> I have to say I like this last option, though someones might find the
>> names not explicit enough ? it might also be confusing with
> the "rotationation"
>> vector operator (curl) ?
>>
>> gael.
>>
>> On Thu, Jul 17, 2008 at 8:00 PM, Christian Mayer <mail@xxxxxxxxxxxxxxxxx>
> wrotationatione:
>> > -----BEGIN PGP SIGNED MESSAGE-----
>> > Hash: SHA256
>> >
>> > Gael Guennebaud schrieb:
>> >> Let's start with the EulerAngles class of the geometry module. [...]
>> >
>> > Apart from the fact that EulerAngles are quite useless for real work I
>> > can understand that beginners usually want them to get a quick start...
>> >
>> > Generally it's best to keep the libaray as small and generic as possible.
>> >
>> > So I'd offer only one function that generates the rotationationation
> matrix. This
>> > function should have a fixed order (that's identical to OpenGL -
>> > although I didn't find a gl, glu or glut function that uses euler
>> > angles...).
>> >
>> > If the user wants a left or a right multiplication is totally up to him,
>> > so the library should try to be smarter :)
>> >
>> > CU,
>> > Christian
>> > -----BEGIN PGP SIGNATURE-----
>> > Version: GnuPG v1.4.6 (GNU/Linux)
>> >
>> > iD8DBQFIf4itoWM1JLkHou0RCD8LAJ0fLw/XfnBezR5i43q4Izln9Hy0VgCfZGDr
>> > dXdk5TfQ8eSvSDRjtxzFuWU=
>> > =JZq/
>> > -----END PGP SIGNATURE-----
>
>
>


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