|Re: [eigen] Transform products|
[ Thread Index |
| More lists.tuxfamily.org/eigen Archives
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Transform products
- From: Gael Guennebaud <gael.guennebaud@xxxxxxxxx>
- Date: Thu, 5 Mar 2009 13:06:29 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=jIIkZUfQiHLg1cp8swtpCRiylKOxGzrQi6JLP6yTTQQ=; b=tbmq4ZfFkJNZjGOJgD9+vb6iFBwhe+QDOlScKx93k70rCA5iBO9e6p5oZmUHGorS5M lT0gLZ4YsHm2gGjnpKg48Pyvt9W5z/j3nCyE6JrZ7sroFhdymKkmsdchJAFKkmehJPVB KJornws/TVHdWA084GJGvttgE3hKAwKr2WAwk=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=dthnPSn1lFPrhURFNF3gG00lAnElRLeh6ea46jc5iNcJZDGnw3GHXQ4w0Jo2QRUsxG 0F78y+e3ovrqItwjngYJqvXGEuUf4RuJDGj5odloZKW2klzyKxDnkXUHRpGX++1344bG kuGkd1pvnPh+/NLzVdO+F30qKqTw/A5TykwdQ=
ok, some news of my progress,
so after trying to implement an as clever as possible Transform
product, I gave up, I finally added an Homogeneous expression and
hnormalized() function. Currently the Homogeneous class is not
efficient, but the goal is to overload its operator* with a MatrixBase
and bypass Homogeneous::coeff(). Then, in some very specific cases,
Transform will automatically use this Homogeneous expression to
implement its operator* with MatrixBase.
So to explain the planed logic, let's assume we are working in 3D, A
and P be an affine and projective transformation, m stands for matrix,
v for vector, and ? for any size:
A * v3 => v3 // implicit call to v3.homogeneous()
A * m33 => A // m33 is interpreted as a linear transform
A * m34 => A // m34 is interpreted as an affine transform
A * m44 => P // m44 is interpreted as a projective transform
A * m3? => not allowed (because it is confusing with A * m33/34)
A * m3?.colwise().homogeneous() => m3?
A * m4? => not allowed
m33 * A => A
m34 * A => A
m44 * A => P
P * v3 => v4
P * v4 => v4
P * m33 => P
P * m34 => P
P * m44 => P
P * m3? => not allowed
P * m3?.colwise().homogeneous() => m4?
P * m4? => m4? // only if ?==Dynamic such that
it is clear that it represents a set of v4
m33 * P => P
m34 * P => P
m44 * P => P
is it reasonable to you? are there any other cases that should be handled?
Actually, thanks to the optimized "return-by-value" trick of the other
thread, I managed to handle things like:
v3 = P * v3; // auto homogeneous normalization
v3 = P * v4; // auto homogeneous normalization
v4 = P * v3;
v3 = (P * v3) * 2; // does not compile because P * v3 defaults to a v4
however I'm not 100% sure that's really worth it.
Regarding the 3 different version of Transform (Affine,AffineCompact,
and Projective) I currently added a third template parameter. The
advantage is that Transform<scalar,dim> will still give the same kind
of transformation than it currently does. However, I'm tempted to go
for 3 different classes inheriting the same base class (API-wise I
think it is cleaner), but then we could not keep the name Transform to
represent a "square affine" transformation anymore (well we can have
both Affine and Transform to temporarily keep the compatibility).
On Sun, Feb 22, 2009 at 4:20 PM, Benoit Jacob <jacob.benoit.1@xxxxxxxxx> wrote:
> I have to say that i haven't been thinking about that intensely, and
> that contrary to you and Keir, these days I am not even a user of the
> Transform class (I don't contribute anymore to any user project) so i
> just have general uninformed opinions.
> 2009/2/21 Gael Guennebaud <gael.guennebaud@xxxxxxxxx>:
> > I have to say: I'm puzzled!
> > at least I agree to add homogeneous normalization functions:
> > v.hnormalized();
> > data.colwise().hnormalized();
> > data.rowwise().hnormalized();
> > (for the name feel free to suggest something different)
> The name sounds good to me (I don't remember suggesting that but that
> sounds like a good idea!)
> > and then a "projective transform" * "set of non homogeneous vectors"
> > would not perform an automatic normalization, but return homogeneous
> > vectors. Then it is up to the user to normalize the result.
> Can we make sure we mean the same thing by "homogeneous vectors " and
> "non homogeneous vectors" ?
> homogeneous : size d+1
> non homogeneous: size d
> Then yes, I agree with your suggestion. projective *
> any_vec_homogeneous_or_not returns homogeneous.
> Indeed, normalizing the result is not always possible, only the user
> can know if it's possible, so leave that up to him.
> > I'm not fan of the "as homogeneous" expression because it would
> > require a if inside coeff,
> Good point.
> > but since it might be removed by the
> > compiler, why not...
> Indeed there's a risk it will not always be, depending on storage
> order, in batch operations on a dynamic number of vectors...
> > I think that's better to make Transform good
> > enough so that such an expression would not be needed. And by the way,
> > currently you can do:
> > VectorType v;
> > HVectorType hv;
> > // ... work with v
> > // then you temporally need an homogeneous vector:
> > hv << v, 1;
> > // use hv
> This solution has the other problem that a useless copy of v is performed..
> I think, the best solution then might be to make asHomogeneous()
> return a proxy, not an expression. It would be used just to resolve
> overloading of operator*. I.e. we'd have a Transform*HomogeneousProxy
> that would take the vector inside the proxy and continue with a "1"
> for the last component.
> > About splitting the current Transform into 3 versions... well that
> > would probably be ideal, but this would significantly increase the
> > number of product combinations... I still have to think about it.
> It could end up in more lines of code but that code would also be
> simpler, each class having its own separate meaning, and requiring
> less template logic.
> But if you prefer you might save some LOC's by making it just a single
> class Transform with a template parameter (which then should default
> to "affine transform stored as big matrix" for optimal compatibility).