|Re: [eigen] Eigen appears to rock.|
[ Thread Index |
| More lists.tuxfamily.org/eigen Archives
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Eigen appears to rock.
- From: "Gael Guennebaud" <gael.guennebaud@xxxxxxxxx>
- Date: Thu, 21 Aug 2008 11:38:24 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to :subject:in-reply-to:mime-version:content-type :content-transfer-encoding:content-disposition:references; bh=6VazeacsDZG86i0cahCperyTU6NV2BGW9AZFmgS7Iuc=; b=QJpVEo6L9ih3j3kb0FB1xgL8T3Gla1fhVDGQ2WJgVEjBBGfMCxeZ7sZ12F+EstqlAd 6kLWX/5v5B/Ms3uKNG8N/apVPFS+QeqGeas7jETfXUthTmfiLRlzci5WoIrnzUfj4/PE Mmg7X9V3yXFtvI7HEacy9ie8EwBQLc8vSMb3g=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:in-reply-to:mime-version :content-type:content-transfer-encoding:content-disposition :references; b=CpjEwwkLPznT809iHrQZXUy/xNEGe/2KnNGEaCunPrgaS5UoFUHv4n6CFXaTMdtCqs uaesKkHrHHMXNVdeHnTbBodMf4m1pjtqFG0NB4e338a5E2bg1BYe5XwiyLCHum924zlI 057ZNZCS15QQx7de/gzatIq42zLGaXdnrY7Vg=
thanks for your interest in Eigen.
First let me clarify your questions about the product operator of Transform:
"T * p" returns a 3 components vector equal to "T.affine() * p +
"T * h" returns a 4 components vector equal to "T.matrix() * h"
T.matrix() is the internal 4x4 transformation matrix.
T.affine() is the 3x3 affine part of the above 4x4 matrix (it
represents the rotation + scale + shear)
So if you want to transform a vector you can still write "T.affine() *
v" (or, as you suggested, use homogeneous vectors).
Now what about distinguishing Point and Vector types ? I have to say
that I've already used a couple of libraries making such a type
difference, and every time I ended up with spending my time to convert
Point to Vector (remove zero) and Vector to Point (add zero), and I
disliked that a lot.
From a practical point of view the only difference between Points and
Vectors happens when you apply a transformation. Therefore, I prefer
to have these conversions implicit (by using only Vectors) and give
the specific semantic when I apply a transformation.
Moreover, if your vectors represent differential quantities of an
object (gradient, normal, tangents) then you need to transform them by
the Jacobian of your transformation, which is for an affine
transformation matrix the transpose of the inverse, e.g.:
T.affine().inverse().transpose() * normal;
(of course if your affine transformation is a pure rotation then you
can use T.affine() right away).
That means you would not need only 2 different types (Point and
Vector) but also a third one: DifferentialVector. I cannot imagine the
nightmare to use a lib which would do that !!
So really, I think using only Vector is the best way to go, and if you
really want to distinguish Point and Vector, the elegant solution
would be to use homogeneous vectors, but 1) this requires an
additional component 2) this increases computation time 3) this
requires very great care from the user and might yields very hard to
find bugs. So again, IMO, using only Vector is not bad !
Anyway, this let me though Transform could be slightly improved by
adding the following explicit shortcuts:
Vector3 transformPoint(Vector3) const;
Vector3 transformVector(Vector3) const;
Vector3 transformDifferentialVector(Vector3) const;
Matrix3 normalMatrix() const;
I'm not sure about transformDifferentialVector because it is very slow
if you transform more than a single vector.
normalMatrix() would returns the transformation matrix you have to use
to transform your normals.
On Thu, Aug 21, 2008 at 6:22 AM, Thomas Vaughan <tevaughan@xxxxxxxxx> wrote:
> On Wed, Aug 20, 2008 at 9:31 PM, Benoît Jacob <jacob@xxxxxxxxxxxxxxx>
>> Thanks for the kind words!
> You're welcome!
>> For example, Transform3f is actually a 4x4 matrix and can represent
>> any affine transformation on 3-space. You can multiply a Transform3f
>> with a Vector3f.
> Hmm. This seems a bit unfortunate. In my naive imagination, although
> each of a Vector and a Point should have three components internally,
> - Applying a Transform to a Vector should give only a rotation, whereas
> applying the same Transform to a Point should give both a rotation
> and a translation,
> - The binary subtraction operator between two Points should return the
> displacement Vector from one point to the other.
> - The binary addition operator between a Point and a Vector should
> return the Point at the head of the Vector when its tail rests at the
> Point operand.
> - Most ordinary matrix stuff should work for a Vector, but only a few
> things, like those above, and individual coordinate access, should
> work for a Point.
> I've noticed that some nasty bugs can happen in application code because
> there is no proper distinction enforced between a Point and a Vector.
> For example, I've made the mistake of accidentally transforming point
> coordinates as though they were vector components. If a quantity were
> declared as a Point, then it would be nice by C++ typing to have the
> compiler warn the programmer that he is trying to treat something as
> though it were a Vector when it is really a Point. Alternatively it
> would be nice for the compiler just to do the appropriate thing
> automatically in the case of a coordinate transformation.
> Maybe, in the multiplication against the Transform, this would be as
> simple as
> - converting a Vector to a four-dimensional column whose w-component is
> zero but
> - converting a Point to a four-dimensional column whose w-component is
> I notice that operator* for Transform takes either an N-dimensional
> vector or an (N+1)-dimensional homogeneous vector. Does "homogeneous
> vector" imply unit value in the (N+1)-component? What (N+1)-component is
> supplied for the N-dimensional vector in this case?
> Thomas E. Vaughan
> There are only two kinds of people; those who accept dogma and know it,
> and those who accept dogma and don't know it. - G.K. Chesterton