• 12
• 10
• 10
• 13
• 10

# Finding a rotation matrix for a direction vector

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

## Recommended Posts

Hi, I figure it's probably been too long since I did any calculus/algebra as I've been trying to figure this one out for far too long now [headshake] A little context... I've got a simple 3D arrow model that I want to orientate with the direction of a light source. Simple GUI-type thing to show the user which direction an arbitrary directional light is facing. Obviously a directional light has no position/origin, so I'm just going to cheat and place it on the unit sphere about the world origin. That part is fine, and it moves across the surface of the sphere as expected. The problem is therefore finding a rotation matrix that will see the point of the arrow facing towards the world origin (center of the sphere who's surface it's moving across). I've tried a whole bunch of things I thought would work - flattening onto each 2D plane to try and generate 2 or 3 angles with which to build a matrix, yaw/pitch/roll matrices, black magic... Each of my attempts seems to introduce some sort of numerical instability where the arrow faces correctly for parts of the sphere, but then goes absolutely nuts and starts dancing all over the place for other parts [lol] So, anyone care to put me out of my misery? Constructing the matrix directly is okay, but I'm using Direct3D/D3DX, so just finding X/Y/Z or Yaw/Pitch/Roll or an axis/angle is sufficient... Cheers, Jack

##### Share on other sites
ok, from how I get this you want to rotate your arrow to point at a specific direction.
You can easiely do that by an axis/angle rotation, using the vector perpedicular to both the vector that the untransformed arrow is pointing at, and your final direction vector. The angle between those two would then be the rotational angle.

##### Share on other sites
I'll give you my matrix i use for shadowmapping in my famous renderer :-)

// at entry: dir is direction you want(normalized!) m is 4x4 matrix Vec3d x_dir(0.0,0.0,1.0),y_dir;real64 d=dir.z;if(d>-0.999999999 && d<0.999999999){ // to avoid problems with normalize in special cases		x_dir=x_dir-dir*d;		x_dir.Normalize();		y_dir=CrossProd(dir,x_dir);}else{		x_dir=Vec3d(dir.z,0,-dir.x);		y_dir=Vec3d(0,1,0);};// x_dir and y_dir is orthogonal to dir and to eachother.// so, you can make matrix from x_dir, y_dir, and dir in whatever way you prefer. // What to do depends to what API you use and where arrow model is pointing.// this is matrix i use which may give starting point. // this is for arrow that points in z direction (for arrow that points in x direction you may try swapping dir and x_dir)		m[0][0]=x_dir.x;	m[0][1]=x_dir.y;	m[0][2]=x_dir.z;	m[0][3]=0.0;		m[1][0]=y_dir.x;	m[1][1]=y_dir.y;	m[1][2]=y_dir.z;	m[1][3]=0.0;        m[2][0]=dir.x;	m[2][1]=dir.y;	m[2][2]=dir.z;	m[2][3]=0.0;		m[3][0]=0;	m[3][1]=0;	m[3][2]=0;	m[3][3]=1.0;

edit: and another thing, if you want your arrow to behave bit like billboard (always rotate around axis so one side points to the camera) use
Vec3d x_dir=direction_to_camera,y_dir;
real64 d=dotprod(dir,x_dir);
instead of similar lines in above sources
edit: fixed typo.

##### Share on other sites
Thanks very much for the help - got it fixed now [smile]

Quote:
 You can easiely do that by an axis/angle rotation, using the vector perpedicular to both the vector that the untransformed arrow is pointing at
That does seem painfully obvious now [headshake] My axis/angle rotation was trying to use variations of the direction - completely forgot to try the perpendicular vector...

Dmytry - That code fragment worked a beauty, many many many thanks for posting that. Even with glow-in-the-dark moderator powers I can't rate people above +5, so I'll just have to say "Thanks" instead [smile]

I really need to dust off some old maths textbooks. There was a time when I found this stuff easy [sad]

Cheers,
Jack