Sign in to follow this  

how to compute vector projection matrix

This topic is 4341 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to create a matrix that projects one vector onto another. I already know to accomplish this you do: v' = (v*n)n where v is your original vector and n is the direction you wish to project to. But after projection, I need v' to be the same length as v, which does not happen doing normal projection. I already know how to build the matrix which does the above, but how do you build a matrix that also preserves vector length after the transformation? I want to be able to orient an object on terrain so that it's y-axis points in the direction of the surface normals.

Share this post


Link to post
Share on other sites
You need a rotation matrix R that would rotate v such that R*v would "point" to the same direction as n.

You could construct such a matrix by creating a rotation quaternion and then converting the quaternion to rotation matrix.

Another way is to use Rodrigues' rotation formula, and construct the matrix directly:

R = I + sin(a)*[w] + (1-cos(a))*[w]2,

where:
I - Identity matrix
a - Angle between v and n ( ex: ArcCos( Dot(v, n) ) )
w - Normalize( Cross( v, n ) )
[w] - The cross matrix such that for any vector u: [w]*u = Cross( w, u ).

If both v and u are normalized, the process can be seriously optimized:

R = I + [w] + b*[w]2,

where:
w - Cross( v, n )
b - 1/(1 + Dot( v, n ))


Share this post


Link to post
Share on other sites
I can already construct a matrix that performs the rotation of v to n. What I need is a matrix that preserves the length of v AFTER the rotation.

Plus it does not matter if v and n are already normalized. The projection of v onto n does NOT have a length of 1.

Share this post


Link to post
Share on other sites
Quote:
Original post by oconnellseanm
I can already construct a matrix that performs the rotation of v to n. What I need is a matrix that preserves the length of v AFTER the rotation.
A properly constructed rotation matrix does preserve the length of the vector it operates on, so this shouldn't even be an issue. Are you sure you're building the rotation matrix correctly? If you're not sure, you could post the code for us to look at...

Share this post


Link to post
Share on other sites
Here's my code:


void normalize(float *n)
{
float mag = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
n[0] /= mag;
n[1] /= mag;
n[2] /= mag;
}

float mag(float *n)
{
return sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
}

int _tmain(int argc, _TCHAR* argv[])
{
float v[] = {1, 0, 0};
float n[] = {1, 1, 0};
float m[9];

normalize(n);
m[0] = n[0]*n[0]; m[1] = n[1]; m[2] = n[2];
m[3] = n[0]; m[4] = n[1]*n[1]; m[5] = n[2];
m[6] = n[0]; m[7] = n[1]; m[8] = n[2]*n[2];

float v0[3];

v0[0] = m[0]*v[0] + m[3]*v[1] + m[6]*v[2];
v0[1] = m[1]*v[0] + m[4]*v[1] + m[7]*v[2];
v0[2] = m[2]*v[0] + m[5]*v[1] + m[8]*v[2];

printf("After transform: v={%f,%f,%f} l=%f\n", v0[0], v0[1], v0[2], mag(v0));

normalize(v0);
printf("Rescale: v={%f,%f,%f} l=%f\n", v0[0], v0[1], v0[2], mag(v0));

return 0;
}






I basically given my direction vector n I construct the rotation matrix like so:


m = [ nx*nx ny nz ]
[ nx ny*ny nz ]
[ nx ny nz*nz ]

Share this post


Link to post
Share on other sites
Okay, I figured it out. I was WAY OFF on how to calculate this correctly. Here's the actualy correct solution.



Vector3 v(1, 0, 0);
Vector3 n(1, 1, 0);
n.normalize();

Vector3 axis = crossProduct(v, n);
axis.normalize();
float theta = angle(v, n);

Matrix4 mat;
mat.identity();
mat.setupRotate(axis, theta);

Vector3 v0 = v * mat;
printf("new v = [%f %f %f]\n", v0.x, v0.y, v0.z);



So basically what I finally realized is that you just take the cross product of your vector v and n, then find the angle between the two vectors..........then simply rotate theta radians around the cross product vector. That's it.

Share this post


Link to post
Share on other sites

This topic is 4341 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this