local vs world coordinates

Started by
12 comments, last by Ljilekor 19 years, 2 months ago
I understand matrix transformations but I can't make them work. I cant mix rotations and translations. How do I calculate the Loc coords(relative to object B) of object A(given in Wld coords). I have no problem finding the Loc rotations so I leave them out. objA relative to objB (WORLD->LOCAL) Given: ObjA Wpos = (wxA, wyA, wzA) ObjB Wpos = (wxB, wyB, wzB) ObjB Wrot = (whB, wpB, wbB) (h=heading, p=pitch, b=bank) Q: ObjA Lpos relative to ObjB = (lxA, lyA, lzA) (rotation is not needed) I'm creating 2 4x4 matrices with the given coords, one for each object. I multiply MatrixObjA with the inverse of MarixObjB. Should work but I get strange results as soon as I start moving ObjA away from Wpos (0,0,0). The problem is that I find too much information about this issue. I can't filter what I need and what I don't... Where can I find some clean code / function / explanation for this simple problem. Thanx in advance.
Advertisement
Do I have to separate translation and rotation in order to inverse them?

If I do, is this how I inverse the translation of MatrixObjB:
inverse of
| 1 0 0 wxB|
| 0 1 0 wyB|
| 0 0 1 wzB|
| 0 0 0 1 |
=
| 1 0 0 -wxB|
| 0 1 0 -wyB|
| 0 0 1 -wzB|
| 0 0 0 -1 | or | 0 0 0 1 | (???)
I tested all possibilities.

Using separate Translation/Rotation Matrices.
Inverting The one/the other.
...

Pfff, I know the sollution is very simple but I can't get there...

Help me out of this pit of doom...
THX

[Edited by - Ljilekor on February 13, 2005 9:58:29 AM]
A function relativeTo() would take care of all parenting issues by using only vectors as arguments.

relativeTo(vec3d LPosResult, vec3d LRotResult, vec3d WPosObjB, vec3d WRotObjB, vec3d WPosObjA, vec3d WRotObjA)

Resulting in LPosResult and LRotResult containing the Local coords and orientation of ObjB relative to ObjA.

Could somebody show me how to code such a function, please.
(Nobody is answering... Is it because it's too basic/simple or ...)
Let say you have a root (in this case parent), and a child inheriting this transform. Now as the root defines what is world coordinates you need to apply this transform to the child to get the childs world coordinates.
This transform is done as follows:

worldtrans.scale_	= root.scale_		* scale_;worldtrans.rotation_	= root.rotation_	* rotation_;worldtrans.translation_	= root.translation_	+ root.scale_ * (root.rotation_ * translation_);



Then you have your worldtransform, which actually gives you the modelview matrix directly:
       scale*rotation[0][0], rotation[1][0], rotation[2][0], 0.0f,        rotation[0][1], scale*rotation[1][1],rotation[2][1], 0.0f,        rotation[0][2],rotation[1][2], scale*rotation[2][2], 0.0f,        translate.x_,	translate.y_,	translate.z_,			 1.0f


Note that this is actually the transpose of the modelview matrix (some opengl code).

Regards
Quote:(Nobody is answering... Is it because it's too basic/simple or ...)


No, it's not too basic or simple. Well, it is 'basic' as far as 3D math goes, but it's not simple. Transformations and rotations, coordinate systems, inverses, etc. can be pretty hard to get your head around, and there are many opportunities for error to be introduced.

If I understand correctly, you're trying to express the vertices of object A in the local space of object B. Let's assume that each has a 4x4 transformation matrix. First you need to get the verts from A's local space into world space, for which you should be able to use its matrix directly. Then, you need to get those world-space coordinates into B's local space, for which you should be able to use B's inverted matrix. By multiplying A's matrix with B's inverted matrix, you should get a matrix that transforms points from A's local space to B's local space. Perhaps you already know all this.

In any case, there are a lot of places where things can go wrong. Row- or column-major, order of multiplication, and so on. So I can't really tell you why you're having problems.

One thing I will mention is that for general transformations you don't really need a 4x4 matrix. Some libraries I've seen (and this is my preferred method) have a Transform or CoordinateSystem class that has a 3x3 rotation matrix and a translation vector. If you know that your transformations are limited to rotations and translations, the inverse can be computed more cheaply than in the general case. Also, formulating the problem in this way can make it easier to understand.

Anyway, sorry I can't offer any more specific help...
It is very easy and trivial and there is no reason for anything to go wrong. You just need to write the equations and do some algebraic manipulations.

Say the Ma is the transformation matrix of object A, and Mb in the transformation matrix of Object B.
a point in the local space of object A can be transformed to global space by the following expression

Pw = Pa * Ma

Where:
Pw is the point in global space,
Pa is the same point in the local space of objecA
Ma in the transformation matrix of object A
* is the operator the Multiply a vector time a matrix

Similarly the same point in world space can be calculate by the expression

Pw = Pb * Mb

Now since Pw is the same point, then the two expressions can be equated

Pa * Ma = Pb * Mb

From here you can factor Pa by multiplying by the inverse matrix of Ma in both side

Pa * Ma * Ma’ = Pb * Mb * Ma’
Pa = Pb * (Mb * Ma’)

Now you have a formula that can take vectors from the local space of one object tyo the local space of another object, It is just multiplying the vector by the Matrix Mb * Ma’
Where Mb’ in the inverse matrix of Matrix A

The AP's solution is the same as I gave - if you can implement that, you should get the results you're looking for. However:
Quote:It is very easy and trivial and there is no reason for anything to go wrong.
Ideally, yes. But due to the different conventions involved (row or columns vectors and so on), one person applying code or equations given by another often gives the wrong results. So there are some subtleties that I think should not be taken for granted.
No ideally and no subtleties, and not conventions.
The solution is the same regardless of implementation detain
For a system were the vectors and matrices are transposed the solution should be the same. Just formulate the equation in a transposed representation
For example

Trans (Pw) = tras(Pa* Ma) = Trans (Ma) * Trans (Pa)
Pwt = Mat * Pat
The rest is the same and it should arrive to

Pbt = (Mat’ * Mbt) * Pbt

Notice that the transpose of the last expression produces the exact same vector. This should work with any math library, and with any graphics API
Quote:Pbt = (Mat’ * Mbt) * Pbt
Did you mean Pat = (Mat' * Mbt)?
Quote:No ideally and no subtleties, and not conventions.
Ok. It's not my intention to argue with you, and I'm always open to correction as that is the way to learn. So let me try to explain what I mean, and feel free to point out any errors.

If m is a matrix, the expression m1 = m2 * m3 may have different results in one math library than in another. Similarly, in some libraries a vector transform may be represented as v' = v * m, whereas in others it would be v' = m * v.

Obviously you understand those distinctions, but not everyone does - if they did, we probably wouldn't be answering the OP's question in the first place. Often when people ask these kinds of questions, others give the answer in the convention with which they are accustomed to working. When the person asking the question plugs those equations into their code, they don't work.

But, you might say, if I give v' = v * m, but their library uses column vectors, then v' = v * m shouldn't even compile, right? Well, I've seen several libraries that implement both pre- and post-multiplication for vectors, so that one is actually multiplication by the transpose (I don't know if this is a good idea or not). So the equation might compile just fine, but give the wrong results.

Maybe I'm wrong about this, and I welcome corrections.

This topic is closed to new replies.

Advertisement