rotating a direction vector floating point error

Started by
3 comments, last by Jonathan2006 3 years, 8 months ago

code in OpenGL using GLM

im trying to rotate a direction vector (look) by either 90 degrees or 180 degrees expecting a unit vector pointing at the axis.

here is a sample.
A look vector pointing at positive Z axis, rotated in Y axis by 180 degrees should be pointing at -Z axis now, but result is {x=-6.18172393e-08 y=0.000000000 z=-0.707106769 ...} instead of (0,0,-1).

glm::vec3 look = glm::vec3(0, 0, 1);
glm::mat4 matRotY = glm::mat4(1.0f);
matRotY = glm::rotate(matRotY, glm::radians(180.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::vec4 transformdLook = glm::normalize(matRotY * glm::vec4(look, 1.0f));

glm::vec3 newlook = glm::vec3(transformdLook.x, transformdLook.y, transformdLook.z);

tried the same thing with 90 degrees and the result is newlook = {x=0.707106769 y=0.000000000 z=-3.09086197e-08 ...} instead of (1,0,0).
Why is this? Im using a look vector to calculate angle to rotate my character on a new direction.
but since the resulting direction vector is not nearly 1, it returns a wrong angle.
In bellow code, target is the new target position to go,

glm::vec3 dir_vec_world = targ - curr;

glm::vec3 dir1 = newlook;  // the look computed above
glm::vec3 dir2 = glm::normalize(dir_vec_world);

float dot = glm::dot(dir1, dir2);
float angle = glm::acos(dot);

at this iteration for example. current position is at 0,0,0 and target is moving to 0,0,-10).
the character is moving towards -z access, and look should be at (0,0-1) due to rotation above, therefore target direction vector should also be at (0,0,-1) giving a 0 angle. but since the returning vector after rotation is {x=0.707106769 y=0.000000000 z=-3.09086197e-08 ...} instead of (1,0,0) the angle returns at 45 degrees/0.785398 rad instead, which messes everything up as the character needs to rotate at 45 (along with its look) and the target direction vector is still at (0,0,-1) which rotation being applied every iteration.

do you guys have any suggestion for fixing this?

Advertisement

@cebugdev2 Well I will try to answer this as best I can (I have used glm in C unfortunately not C++). One problem may be you want to translate with the angle then get the vector from that. So in old OpenGL terms it would look like:

matrix = rotateMatrix(matrix, radians(180), 0, 1, 0);
matrix = translateMatrix(matrix, look.x, look.y, look.z);
newLook = normalizeVector(getTranslation(matrix));

@Jonathan2006 it worked, thanks man., trying to figure out why it works, can you spare a little explanation and why my approach of transforming the vector by multipilcation of vector to matrix did not work? ?

@cebugdev2 Btw I was having a similar problem again (I haven't used matrices much recently) so you got me at the right time. Note I am using a row based matrix. Whenever you are dealing with a matrix in an array you should always go from left to right top to bottom. So this is what you are doing in the matrix (I am using a 4x4 matrix but just showing the relevant parts:

x = [matrix[0]*look.x, matrix[4]*look.y, matrix[8]*look.z, matrix[12]*1]
y = [matrix[1]*look.x, matrix[5]*look.y, matrix[9]*look.z, matrix[13]*1]
z = [matrix[2]*look.x, matrix[6]*look.y, matrix[10]*look.z, matrix[14]*1]

With translation it uses an entire matrix not just a vector so it looks like this:

[1,0,0,0]
[0,1,0,0]
[0,0,1,0]
[look.x, look.y look.z, 1]

Now that you have the translate matrix you multiply it by the rotation matrix. Multiplying matrices is way beyond what I can explain here but you can search for it in your favorite search engine.

After multiplying matrices and crunching numbers you get the translate vector:

x = matrix[12];
y = matrix[13];
z = matrix[14];

So the real difference is that vectors are usually 3 variables and matrices are usually 16 variables. Essentially you are just sending in and pulling out the same matrix elements (12,13,14) for translate but the rotation matrix is rotating the translate elements in the matrix.

Hope this helps!

This topic is closed to new replies.

Advertisement