Re: [eigen] RotationBase times DiagonalMatrix

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


2011/7/27 Hauke Heibel <hauke.heibel@xxxxxxxxxxxxxx>:
> Hi,
>
> the following code does not compile on my system:
>
>  Rotation2D<double>(M_PI/2) * DiagonalMatrix<double,2>(-1.0,1.0)
>
> Adding a)
>
> inline RotationMatrixType operator*(const DiagonalMatrix<Scalar,Dim>& s) const
> { return toRotationMatrix() * s; }
>
> to RotationBase resolves this issue and its basically the same as what
> we do for UniformScaling.

OK for that solution.

> Alternatively, b) is possible too:
>
> inline Transform<Scalar,Dim,AffineCompact> operator*(const
> DiagonalMatrix<Scalar,Dim>& s) const
> { return Transform<Scalar,Dim,AffineCompact>(*this) * s; }

My problem with this solution is that the product of a rotation times
a diagonal matrix is still a linear transformation, so why return a
Transform which is specifically an affine (not linear) transformation?
I'm in favor of using plain matrices everytime that a plain, arbitrary
linear transformation is meant.

>
> I want to add, that I am still not 100% happy with the use patterns of
> such transformations. E.g.
>
> AffineCompact2d a = Rotation2D<double>(M_PI) * Translation2f(x,y);
>
> compiles, whereas
>
> AffineCompact2d a = Rotation2D<double>(M_PI/2) * Scaling(-1.0,1.0);
>
> does not with implementation a) but it does with implementation b).

Ah OK, I see. It doesn't compile with a) because the assignment in the
declaration is interpreted as construction, so it tries to use the
constructor (taking EigenBase) instead of operator= and fails as it's
an explicit constructor.

That's really stupid :-/ C++ is able to convert "T a = b;" into "T
a(b);" only to fail when the constructor here is explicit. But if one
writes T a(b); or T a; a=b;  then the error goes away.

Test program:

struct A{
  A() {}
  explicit A(int i) {}
  void operator=(int  i) {};
};

int main() {
  // works
  A a(0);

  // works
  A b; b = 0;

  // fails
  A c = 0;
}


I'd say that's a problem with C++ itself and I see only two approaches:
 - either live with that and tell Eigen users to use A a(b) instead of
A a  = b when the class A has an explicit constructor
 - or stop making constructors 'explicit', consider that C++ language
feature flawed: it doesn't work nicely with C++'s
convert-assignment-to-construction rule

I'm sure that Gael and Joel would have stuff to say about that ;-)

>
> It is also a little bit strange, that this code works
>
> AffineCompact2d a = Rotation2D<double>(M_PI) * Translation2f(x,y);
>
> and this does not
>
> AffineCompact2d a = Rotation2D<double>(M_PI);
>
> I think I understand the reasoning behind the explicit constructors
> but on the other hand-side I am not sure whether potential temporaries
> hurt more than the kind of awkward usage pattern. I mean these are all
> tiny stack objects, right?

Same problem as above, right?

Cheers,
Benoit



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