Re: [eigen] Transform products

[ Thread Index | Date Index | More Archives ]

On Thu, Feb 19, 2009 at 11:45 AM, Gael Guennebaud <gael.guennebaud@xxxxxxxxx> wrote:
hm, yes for all kind of projecting mappings. Now of course for such
use cases most of the Transform's features are not very useful. What's
useful is the automatic homogeneous normalization. But I agree, that's
not a common use case, and so I agree to assume an affine
transformation as default, excepted in two cases:

1 - the user provide homogeneous vectors and so we return homogeneous vectors:
   Transform * [d+1 x N] => [d+1 x N]
   (here "t * rhs" is just a shortcut for "t.matrix() * rhs")

2 - when using the future special "projective product":
   t.projectiveTransform( [d x N] )

what do you think ?

btw, recent OpenGL can deal with 3x4 (only with shaders) and/or row
major matrices.

For libmv I need to do projective transforms that look like

x = PX, where P is 3x4, X is 4x1, and x is 3x1. All quantities are homogeneous. Sometimes I need to normalize x by dividing by the last component (to get a 2-vector), and other times I need the explicit scale factor. Often I have X represented as a 3 vector with a implicit 1 on the bottom; right now I stack an extra row of ones before multiplying. Perhaps something like

x = P*X.homogeneous() which extends X with a row of 1s?

Another way is to abandon the whole 'transform' idea and instead leave it up to the user, but add helpers that add rows of 1s or normalize by the last component. For example

x = (P*X).normalized_homogeneous() <--- x becomes a 2 vector, or if X is a 4xN matrix, x becomes 2xN.

Not that this is necessarily better, just a thought.


On Thu, Feb 19, 2009 at 3:20 PM, Benoit Jacob <jacob.benoit.1@xxxxxxxxx> wrote:
> Hi,
> I think the following question needs to be adressed first: couldn't we
> just assume that the last row is 0,...,0,1 ? Is there really any use
> case for non-affine transformations? Thus the last row would be there
> just for seamless interoperability with OpenGL.
> Or do you have a real use case where the last row is not 0,...,0,1 ?
> Cheers,
> Benoit
> 2009/2/19 Gael Guennebaud <gael.guennebaud@xxxxxxxxx>:
>> Hi list,
>> there still remains a few issues with the product: Transform * matrix_expression
>> Let d be the dimension of the ambient space (so that the Transform
>> object actually correspond to a d+1 x d+1 matrix). Currently we allow:
>> 1 - Transform * [d x d] => Transform
>> 2 - Transform * [d+1 x d+1] => trivial product _expression_
>> 3 - Transform * [d+1 x 1] => trivial product _expression_
>> 4 - Transform * [d x 1] => complex [d x 1] _expression_ including the
>> homogeneous normalization
>> Issues:
>> a) the 4-th case is not plenty satisfactory:
>>  a1 - should it returns an homogeneous vector ?
>>  a2 - or automatically does the normalization as it currently does ?
>>  a3 - or should we offer a way to skip the normalization assuming the
>> transformation is affine (last row = [0 ... 0 1]) ?
>> Well, these questions are more complementary and I guess the answer is
>> yes for all, the problem is rather how to expose all these variants ?
>> a proposal:
>> for a3 let's add "t.affine() * v"   where affine() would return  a
>> kind of [d x d+1] proxy with overloaded operator *.
>> for a1 and a2, two options:
>>  p1) keep the default as it because it is safe
>>       and for a1... well I don't know, anyway the user can still
>>       build and homogeneous one for the rhs.
>>  p2) let's return a "homogeneous" object which would
>>      automatically be converted to a [d x 1] vector if needed
>>      (ideally would have to be done in MatrixBase)
>> b) second issue: We want to be able to perform a batch transformation
>> of a set of N vectors. Again two cases:
>>  b1 - Transform * [d+1 x N] => this is trivial, we just have to merge
>> the above cases 1 and 2 into a more generic one. DONE
>>  b2 - Transform * [d x N]  =>  same issues than the ones discussed
>> above excepted that the involved expressions are much more complicated
>> ! For instance the affine case would be:
>>  t.matrix().linear() * [d x N] + t.matrix().translation() *
>> Matrix<Scalar,d,N>::Ones(N);
>> This last example also shows that maybe it would be useful to have a
>> "replicate" _expression_ mapping a vector to a matrix with constant rows
>> or constant columns ? This would be simpler than using a matrix
>> product for that.
>> And of course all the above discussion also holds for the transpose
>> cases, i.e., matrix_expression * Transform.
>> opinion, idea ?
>> thanks,
>> Gael.

Mail converted by MHonArc 2.6.19+