Transform from Local to World Space

Started by
3 comments, last by RedShft 12 years ago
I'm having a problem correctly displaying rotation when applying a matrix that transforms from local to world space in two dimensions.I have an actors heading and side vector, which represent local space, it's, vertices in local space and it's position in the world. So far I can successfully transform it's vertices from local space to world space but adding in rotation gives unexpected results with the actor not holding it's shape.

I started by creating an identity matrix, then creating a rotation matrix, multiplying those, then creating a translation matrix, and getting the resulting matrix.

The rotation matrix is where I get confused and where the problem is. The way it's setup now is that the heading is a vector from the actor's position that represents it's x-axis in local space, and the side vector represents it's y-axis in local space. I then took the x and y components of these vectors to create the rotation matrix like this:


{ heading.x, heading.y, 0,
side.x, side.y, 0,
0, 0, 1 }


I'm sure this is entirely wrong, and I would appreciate any help anyone could give me to clear this up.
Advertisement
The rotation matrix is where I get confused and where the problem is. The way it's setup now is that the heading is a vector from the actor's position that represents it's x-axis in local space, and the side vector represents it's y-axis in local space
Isn't that a bit counter-intuitive? I would expect [font=courier new,courier,monospace]side [/font]to be worldspace x and [font=courier new,courier,monospace]heading [/font]to be worldspace y.

[font=courier new,courier,monospace]heading [/font]is a vector... from actor's position... representing its x-axis in local space.
That's nonsense. X axis in local (model?) space is {1,0,0}. That's it. It has to be transformed in worldspace... and how you do that? By replacing it with a proper worldspace-x axis, which is [font=courier new,courier,monospace]side[/font]... no wait, it is [font=courier new,courier,monospace]heading [/font](for some reason).
What's the deal with actor's position? I don't understand your intent here; it does not look like anything I would consider a rotation matrix.

So ok, [font=courier new,courier,monospace]heading [/font]is worldspace-x somehow... or at least it should be to produce a correct rotation. This is independent from actor's position. Actor's position affects translation only.

Previously "Krohm"

Ok, well, I'm a bit confused as well. As you might have noticed. hah. I'm following a book on AI, reviewing the functions in his source code, taking it apart and attempting to understand it. This is mainly an exercise at linear algebra and getting into lua, since i'm converting these functions from C++ to Lua.

He uses a function, which is supposed to create a rotation matrix from the heading and side vector of an actor. Heading is fixed to the actors velocity, and side is simply perpendicular to it.

This is the original code in C++, if this helps at all clear this up:

//The rotation matrix

inline void C2DMatrix::Rotate(const Vector2D &fwd, const Vector2D &side)
{
C2DMatrix::Matrix mat;

mat._11 = fwd.x; mat._12 = fwd.y; mat._13 = 0;

mat._21 = side.x; mat._22 = side.y; mat._23 = 0;

mat._31 = 0; mat._32 = 0;mat._33 = 1;

//and multiply
MatrixMultiply(mat);
}


//World transform


//--------------------------- WorldTransform -----------------------------
//
// given a std::vector of 2D vectors, a position, orientation and scale,
// this function transforms the 2D vectors into the object's world space
//------------------------------------------------------------------------
inline std::vector<Vector2D> WorldTransform(std::vector<Vector2D> &points,
const Vector2D &pos,
const Vector2D &forward,
const Vector2D &side,
const Vector2D &scale)
{
//copy the original vertices into the buffer about to be transformed
std::vector<Vector2D> TranVector2Ds = points;

//create a transformation matrix
C2DMatrix matTransform;

//scale
if ( (scale.x != 1.0) || (scale.y != 1.0) )
{
matTransform.Scale(scale.x, scale.y);
}
//rotate, forward == heading
matTransform.Rotate(forward, side);
//and translate
matTransform.Translate(pos.x, pos.y);

//now transform the object's vertices
matTransform.TransformVector2Ds(TranVector2Ds);
return TranVector2Ds;
}


//Setting the heading

//Set the heading to velocity of unit length

if (m_vVelocity.LengthSq() > 0.00000001)
{
m_vHeading = Vec2DNormalize(m_vVelocity);

m_vSide = m_vHeading.Perp();
}

Hi.

I don't have the same concerns as Krohm here. Except some term confusions with "local space" when in fact, you mean they represent the orientation of an "given actor" in "world space", I have the feeling that you're almost visualizing things right.
For the part about speaking of the actor's position when describing its heading, I guess you also have it right, deep inside a more-visual-than-analytic kind of brain, which, I bet, you proudly own just as I do. Keep in mind, though, that a vector is just a direction (well, and a scale...), and it "makes no sense" for a more analytic person to describe it with a starting point, despite its representation if you drew it on paper.

I'm also not too troubled with your choice of the heading as X, side as Y, etc. Those are arbitrary choices anyway.

So, I unfortunately don't have any on-the-shelf solution for you, but here are some parts that may go wrong, maybe double check them :
a) Choice of heading and side as X (resp. Y) is yours, but check that it indeed matches with other referentials in your system.
b) Choice of which is a row, which is a column in the rotation matrix has an effect, depending on how the multiplication was implemented.
c) Also depending on how the multiplication was implemented, is the ordering of successive transformations (scale, rotate, translate) that way, or the other way around. Did you try to only apply the rotation without the others (scale and translation), and see if the results are a little better ? If so, try to rearrange the transformations in another order.

Follow NeREIDS development on my blog : fa-nacht.rmyzen.net/

TiPiou, thank you for your reply, I am going to have to investigate this further.

The order of the transformations is effectively, scale - rotate - translate right now, I tried reversing the order and applying rotate only, this didn't clear the unexpected results when rotating. So, I would guess my rotate matrix is inadequate. I feel I'm going to have to keep reading about math and physics in game programming to really understand where my mistake is. I reading "Mathematics and Physics for Programmers" by Kodicek, and really enjoying the book. I'm sure he covers a section about proper rotation matrices, and all this good stuff, so when I get there I'll come back and fix this.

This topic is closed to new replies.

Advertisement