Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

math behind transformed points and vectors into local/world space

Started by BlackWind Jan 31, 2012 at 2:13 AM 10 replies 10.7k views
Original Post
BlackWind
BlackWind
Hi,

I understand the differrence between points and vectors, and each one in local and world space.
I also thought i had all the math. But i have a some situations where i dont really understand the results.

Lets say we have an object in (5,0,0) (world position). Lets name it "Player"

And we have another one in (10,5,2) (world position). Lets name it "Enemy".

And we want to transform Enemy into its respective points and vectors of world and local/object space of Player.

No rotation and no scale.

So its easy, and we get this results:
Local Point ( 5, 5, 2)
Global Point (15, 5 , 2)

Local Vector (10, 5, 2)
global ( 10, 5, 2 ).


I think so far no problems. I understand the logic.


Now we rotate our player 90 degrees around Y-axis. And want to get the same.
So, the rotation of 90 degrees gives us (0,0,-5). (player * rotationAroundYmatrix) and (2,5,-10) (enemy * rotAroundYMatrix)

So now we get something like this:
Local Point ( -2,5,5)
Global Point ( 7,5,-10)

Local Vector (-2, 5, 10 )
Global Vector (2,5, -10)


My question is. Why?

1.- How do we decide the signs? For example, I now that (10,5,2) becomes (2,5,-10) when rotate by 90 degrees.
So we use that numbers to get the results.
For example, we can use ( 2,5,-10) + (5,0,0) to get the global point (7,5,-10).
I can get the combinations needed to get the results. What i dont understand is.. Why?
For example, i think that for getting the Local Point we use(-2,5,10) - (0,0,-5) to get (-2,5,5). But i really dont understand why.

Whats the math for getting those results an why?
A little help would be appreciated.

thank you!!
alvaro
alvaro

I don't understand what your problem is, probably because you are not using the correct language. This is normal: Getting the language right is more than half of the problem in Linear Algebra.

You have a player and an enemy. There is a reference we call "world" under which their positions have certain coordinates. I was with you so far.


And we want to transform Enemy into its respective points and vectors of world and local/object space of Player.

Now you totally lost me. And your "Global

Point (15, 5 , 2)" confused me even further: I can't see anything in this situation that would have those coordinates. [To any admins out there: I can't seem to get this paragraph to not break. WTF?]




[color=#282828][font=helvetica, arial, verdana, tahoma, sans-serif]So perhaps you can back up a bit and try to describe better what you are trying to do.[/font]

BlackWind
BlackWind
Hi Alvaro,

What i meant with local and global is:

Local: Transform a point or vector (in this case, enemy) from world space to others object local space (in this case, player).
Meaning, the enemy point (or vector) relative to the players local space.

In plain words, "which is the enemy point relative to the player local space"?
So for the first example, when the player is at (5,0,0) and enemy is at (10,5,2), the enemy point relative to the players local point is (5,5,2).


Global: Transform a point or vector (in this case, enemy) from other object space (player), to world space.
In plain words it could be:
"Where is the point 'enemy' of player, in world space" ? So the point enemy (10,5,2) transformed to players space, would be equivalent to (15,5,2) in world space (since player is already in (5,0,0) )

The same for directions.

Hope i make my question clear.


EDIT: I edited a bit my explation to hopefully make it clearer.
alvaro
alvaro
In order to describe coordinates, it is not enough to have a point: You need a reference. A reference is formed by a point (called origin) and a basis of the vector space underlying the affine space. You can express the transformation between coordinates given in a reference to coordinates in another reference by using a matrix that looks like that of an affine transformation (a 4x4 matrix with a last row that is (0 0 0 1)).

Your description of "global" doesn't make sense to me. In your description the coordinates (15,5,2) seem to be the sum of (10,5,2) and (5,0,0). The sum of the coordinates of two points is an operation that depends on the choice of origin, so it can't possibly mean anything geometrically.
BlackWind
BlackWind
Hi Alvaro,


In order to describe coordinates, it is not enough to have a point: You need a reference. A reference is formed by a point (called origin) and a basis of the vector space underlying the affine space. You can express the transformation between coordinates given in a reference to coordinates in another reference by using a matrix that looks like that of an affine transformation (a 4x4 matrix with a last row that is (0 0 0 1)).

Your description of "global" doesn't make sense to me. In your description the coordinates (15,5,2) seem to be the sum of (10,5,2) and (5,0,0). The sum of the coordinates of two points is an operation that depends on the choice of origin, so it can't possibly mean anything geometrically.


Hi, i didnt mention but every object i have is formed by their 4x4 transformation matrix. Defined by each one of ther "direction" axis (X,Y,Z).
So for example, an object in the origin, with no transformation, could be defined by:
x (1,0,0,0)
y (0,1,0,0)
z(0,0,1,0)
w(0,0,0,1)

The initial position i mention (5,0,0) is the world space position representation by a "Vector3" of the player.
So if i rotate it 90 degrees around Y, is the "classic" multiplications of the vector times the rotationAroundYmatrix:

(1, 0, 0, 0)
(0, cos, -sin ,0 )
(0, sin, cos, 0 )
(0,0,0,1)

The reference for transformations between world and object space is there (which would be the player).
I also have the world origin which is (0,0,0).


Maybe a practical example would be better.

First for the "local point".
Imagine a different example, where the player is at (0,0,5).
And we want to see if the player is in front of the camera (assuming the Z positive is forward/front)
Now we have our object called "camera".
In code it would look something like this

Point3 cameraRelativePoint = camera.TransformWorldToLocalPoint( player.position ); // convert the players point to the camera local space
if ( cameraRelativePoint.z > 0 )
print ("the player is in front");


Now, for the "global point"

Imagine we want to create an object to the right of the player.
Point3 position = player.TransformLocalToWorldPoint ( 1,0,0); // transforms the point (1,0,0) of the player to world space. So if player is at //(5,0,0), its (1,0,0) would be (6,0,0).
CreateNewObject ( newObject, position); // create new object at "position" --which would be to the right of the player


Hope this make sense to you.
Ripiz
Ripiz
Personally visual representation helped me to understand this. This is the only image I found on Google so please ignore text. When you turn something around Z axis, coordinate change only in XY plane, if you refer to image, you'll see 90 degree turn will convert X axis into Y axis. If you think what happens to old Y axis, following same rotation direction it becomes negative X axis, therefore -X becomes -Y, and -Y becomes +X. Any other angle is just something inbetween (part of one axis + part of other axis).

figures.006.jpg
BlackWind
BlackWind
Hi Ripiz,

I do understand that.

my first question, is why (in the first example i posted, when we rotate 90 degrees around Y),
if we transform the enemy point of players object space, to world space, we use the (2,5,-10) point to make the sum (the rotated 90deg around "Y" of (10,5,2)) . And not the original (10,5,2) ? (since for the other part of the sum we use the original (5,0,0) of the player).
In other words, we use:
(5,0,0) + (2,5,-10) .
My first question would be:
Why not (0,0,-5) + (2,5,-10)

For the local it makes a little more sense to me, since we use both rotated points (0,0,-5) of player, and (-2,5,10) of enemy.
But why the negative sign in (-2,5,10). Why not (2,5,-10) ??
In other words. We have to do this:
(-2,5,-10 ) - (0,0,-5).

My second question would be:
Why not (2,5,-10) - (0,0,-5)

Why for localToWorld we use the orignal player position and the rotated enemy position? (instead of using both originals).
And for the worldToLocal we use the negated enemyRotated position instead of the original rotated Enemy position.

Whats the logic behind that?
BlackWind
BlackWind
Hi,

Afters many hours of analyzing and proving, i finally i got the formula and logic behind.
I consulted many books but the only one i found it talks explicity about this is "3d math primer" , but even they do not explain the whole process.

First, for transforming from object space relative to anothers world space.

The direction is simple, we just multiply the current direction times the rotationMatrix. Since direction is not affected by position or scale, we only need that multiplication.
Direction = ObjectVector*RotMatrix

Points do get affected by scaling. So we need to keep in mind that. In my case, i dont scale never, so i didnt "solve" the problem for scaled points.
So after doing the vector*RotMatrix, we add the translation needed to be relative to the reference objects world space.
We dont need to rotate the orignal referencePoint, since if we rotate it and then add, we would be moving in some sort of object space. But we want world space.
So the "formula" (without scaling) would be like this:

NewWorldPoint = ReferencePoint + (ObjectPoint * RotMatrix)

My guess is that if we use scaling, the formula would be something like this:
NewWorldPoint = ReferencePoint + ((ObjectPoint * RotMatrix)*ScalingMatrix)

But i'm not really sure, since i didnt make a test.


Now, for the inverse operation, transforming from world space to be relative to anothers objects object space, its only the opposite procedure.
For example, if we moved to the right and up for transforming to world space, now we have to move to the left and down for transforming to object space.

So for direction, its almost the same process, except that we use the transpose of the rotationMatrix.

localDirection = objectDir * (RotMatrix^T) (where ^T denotes the transpose of the matrix tongue.png )

Finally, for the point (without scaling)
NewLocalPoint = (ReferencePoint*(RotMatrix^T) - (ObjectPoint * (RotMatrix^T))

Here we use both rotated because we want object space. So we need the points in object space. The transpose is needed because it would be the "opposite" operation (or equivalent to rotate counterclockwise by the same amount).
We do a substraction instead of addition, because its the opposite.

I tested for all the possibilities (withouth scaling) and it seems to be working perfect. Also now it makes a lot of sense to me all these operations. Problem solved
BlackWind
BlackWind
Reading a bit more on the subject,

i found that this operations is called "change of base".

However, in most books it only comes the mathematical expression, which is enough if you are only dealing with vectors (directions). But when dealing with points it needs a little extra works (since we need to keep in mind scaling and new position)

Also i must add that the real formula uses the Inverse of the matrix (V* M^-1 )
In my case, the transpose will always work, because rotational matrices are orthogonal. And the inverse of the orthogonal matrix is its transpose. This operation seems to be called Orthogonal coordinate system change!
synthetix
synthetix

First, for transforming from object space relative to anothers world space.

The direction is simple, we just multiply the current direction times the rotationMatrix. Since direction is not affected by position or scale, we only need that multiplication.
Direction = ObjectVector*RotMatrix


How do you calculate RotMatrix? Do you just use the rotation values of the reference object (the object around which you want to manipulate the world)? I can multiply my reference object's matrix by its own rotation matrix (created from negative versions of its rotation values), which sets its orientation to 0,0,0. This works great for the reference object but if I try to multiply other objects' matrices using this matrix, the resulting rotation does not take into account the distance the object moves so it's not correct. Could you elaborate on the rotation step?
haegarr
haegarr
If you have a matrix that is intended to transform from the model space into the local space, then actually:

1. You have a space w.r.t. which the co-ordinates of your model are given. This is called the model space or model local space or local space for short, also it is not an exact term.
2. Those transformation matrix is usually applies as v[sub]L[/sub] * M =: v[sub]G[/sub] (using row vectors here). If you apply those to the standard vectors like so
( 0 0 0 1 ) * M = [sup]t[/sup]M
( 1 0 0 0 ) * M = [sup]rx[/sup]M
( 0 1 0 0 ) * M = [sup]ry[/sup]M
( 0 0 1 0 ) * M = [sup]rz[/sup]M
you can see that the matrix contains the local origin and basis vectors but w.r.t. the targeted space.

3. Your said transformation is usually composed from a series of elementar transformations. In principle you change the space with each particular transformation. Regardless how many particular forward transformations you apply to a model, the space that is current after all forward transformations are applied is named the global space or world space.

You can relate 2 models if and only if they are given w.r.t. the same space. This need not be the world space. Using the correspondence
v[sub]L[/sub] * M = v[sub]G[/sub] <=> v[sub]L[/sub] * M * M[sup]-1[/sup] = v[sub]G[/sub] * M[sup]-1[/sup] <=> v[sub]L[/sub]= v[sub]G[/sub] * M[sup]-1[/sup]
one can use the inverse of a model-to-global matrix to transform from the global into a local space. Hence, to come from local space 1 and going to local space 2, you first go into a common space (conveniently but not necessarily the global one) and then into the targeted space like so:
v[sub]L1[/sub] * M[sub]1[/sub] = v[sub]G1[/sub]
v[sub]G1[/sub] * M[sub]2[/sub][sup]-1[/sup] = v[sub]L2[/sub]
=> v[sub]L1[/sub] * M[sub]1[/sub] * M[sub]2[/sub][sup]-1[/sup] =[sup] [/sup]v[sub]L2[/sub]

Don't forget that ( M[sub]1[/sub] * M[sub]2[/sub] )[sup]-1[/sup] = M[sub]2[/sub][sup]-1[/sup] * M[sub]1[/sub][sup]-1[/sup] if you apply an inversion not to the composed matrix but the composition series.
EvilMortal
EvilMortal
Hey, I got this code



trans := gameObject.Transform()

s,r,p := trans.Scale,trans.Rotation,trans.Position

trans.matrix.Reset()
mat := trans.matrix

mat.Scale(s.X, s.Y, s.Z)
mat.Rotate(r.X, 1, 0 ,0)
mat.Rotate(r.Y, 0, 1, 0)
mat.Rotate(r.Z, 0, 0, 1)

mat.Translate(p.X, p.Y, p.Z)

if trans.parent != nil {
mat.Mul(*trans.parent.matrix)
}



any idea how do I fix the problem?
I got two gameObjects, A at 100,200 and the child of it B at 100,0 the following code results in A being at 100,200 and B at 10100,200 [color=#000000][font=Arial,]instead [/font]of 200,200
The scale and rotation working correctly, but the position is not.

I know the problem is here
mat.Translate(p.X, p.Y, p.Z)
but I dont know how to find the right values

ahh sorry, thats actually the correct way
Scale is changing position too.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.