Sign in to follow this  
Tang of the Mountain

Similarity transform

Recommended Posts

Im trying to create a function that does what this function does(NxFindRotationMatrix). Moreover, im trying to understand how it does it. I have been looking for algorithms on similarity transforms, but to no avail. I have two vectors and I want to create a rotation matrix from these. Which s what the function above does. I was given this. Which does not work. My question, how do you go about creating a rot matrix from two vectors as far as the math goes? and 2: why doesnt this code work assuming row major
trMatrix33d enMissionFunctionMgr::FindRotMatrix(trVector3d &from, trVector3d &to)
{

	from.Normalize();
	to.Normalize();

	trVector3d vs = Cross(from, to);

	trVector3d v(vs);
	v.Normalize();

	double ca = from.Dot(to);

	trVector3d vt(v*(1.0 - ca));

	trMatrix33d rotM;
	rotM.Set(0, vt.x * v.x + ca);
	rotM.Set(4, vt.y * v.y + ca);
	rotM.Set(8, vt.z * v.z + ca);

	vt.x *= v.y;
	vt.z *= v.x;
	vt.y *= v.z;
	
	rotM.Set(1, vt.x - vs.z);
	rotM.Set(2, vt.z + vs.y);
	rotM.Set(3, vt.x + vs.z);
	rotM.Set(5, vt.y - vs.x);
	rotM.Set(6, vt.z - vs.y);
	rotM.Set(7, vt.y + vs.x);

	return rotM;
}



side note: How do you make code appear in their own box, it would make for less ugly posts on my part [Edited by - Tang of the Mountain on April 3, 2006 1:36:13 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Tang of the Mountain
rotM.Set(1, vt.x - v.z);
rotM.Set(2, vt.z + v.y);
rotM.Set(3, vt.x + v.z);
rotM.Set(5, vt.y - v.x);
rotM.Set(6, vt.z - v.z);
rotM.Set(7, vt.y + v.x);

return rotM;
}
There may be other errors in the code as well, but all of the v's in the above snippit should probably be vs. Also, the source tags are [ source ][ /source ] (without the spaces).

Share this post


Link to post
Share on other sites
i should probably include how im using this function...

this absolutely works with the novadex function, so the problem can not be here:


trVector3d PolyNorm = trVector3d(normalX, normalY, normalZ);

trMatrix33d currMatZ;
currMatZ.RotationZ(-entityYaw);

//create orientation of terrain contact plane
trMatrix33d orient;
PolyNorm = currMatZ * PolyNorm;
orient = FindRotMatrix(trVector3d(0.0, 0.0, 1.0), PolyNorm);

entityPitch = asin(orient(0,2));
entityRoll = atan2( orient(1,2), orient(2,2));


Share this post


Link to post
Share on other sites
For animation/simulation, creating a quaternion then slerping results in smooth motion (when orienting a projectile/player, etc. to point toward a target):


// Optimized version from Stan Melax (GPG):
inline Quat4 rotationArcMelax(const Vec3 & a,const Vec3 & b) {
Vec3 c = a.cross(b);
flt ss = (1.f+a.dot(b))*2.f;
flt rs = sqrtInverse(ss);
flt s = ss*rs; // s = sqrt(ss).
return Quat4(c.x*rs,c.y*rs,c.z*rs,s*.5f);
} // rotationArcMelax



Using the above method followed by conversion to a matrix should be around the same speed as directly computing the 3x3 matrix (axis-angle method).

More info here,
and here. See also Game Programming Gems I, page 214 for Stan Melax's derivation (why it works, why it's stable, etc.).

Share this post


Link to post
Share on other sites
ok, i tried the above code for finding the quaternion.
converted it to a 4X4 Matrix

then applied the same

entityPitch = asin(orient(0,2));
entityRoll = atan2( orient(1,2), orient(2,2));

that i was before.

It looks like it works, but the roll is off. In fact, it looks like its exactly the reverse of what I need.

i tried playing with it but i cant get it facing right?

Am i using improper trig? or should the lines above be different now that im using a 4x4 instead of a 3x3


[EDIT]
I ended up with this...which, negating it seems a bit haxor...but it works, although sometimes the vehicle a bit just after coming over a hill, but it might just be the terrain.

entityPitch = -atan2(orient(0,2), sqrt((orient(0,0) * orient(0,0))+(orient(0,1) * orient(0,1))));


thanks for everyones help, if you find a better way to calculate the angles from the matrix id be delighted to know.

[Edited by - Tang of the Mountain on April 3, 2006 2:56:16 PM]

Share this post


Link to post
Share on other sites
Proper Euler angle extraction (source code at bottom of page).

I highly recommend that you drop the Euler angles for player orientation and use either quaternions or matrices. To help undertstand how matrices work for orientation/graphics, draw the basis vectors of the player orientation matrix on screen (draw the vectors that make up either the rows or columns (implementation dependent) of the 3x3 matrix). This will help to understand what a 3x3 rotation matrix is (really just three vectors that interpolate a 3-vector in 3-space through dot products). Once you can visualize the matrix basis vectors, it should become clear how to construct arbitrary matrices from vectors, help debug orientation issues, etc.

Share this post


Link to post
Share on other sites
Quote:
I highly recommend that you drop the Euler angles for player orientation and use either quaternions or matrices.



I agree. Tang, convert the entire baseline by Saturday, will ya? ;)

Share this post


Link to post
Share on other sites

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