Re: [eigen] RotationBase times DiagonalMatrix |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] RotationBase times DiagonalMatrix
- From: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
- Date: Tue, 9 Aug 2011 01:25:28 -0400
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; bh=5ZUNN8QBtEQIzd6yLaCy0TXhN4yT3OKu7J5YUv7w4kU=; b=YyC7oxPJ4wZtXOCj/WBlcCkjrAOGLaKk3mIv4/VTQZfyJViJp4hIW4GfBg+DDBebGM JdhN4rS6OJN5uKJfiorAtxHVM4tZDzP1EDQyx5bFYw8X761cy79btQ0z1dOKicGkLgAc kGizS9cyVXRo5unWBAwmAHAbaBZ2LmnYMiYkA=
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