Similarity transform

Started by
5 comments, last by TWilliams 18 years ago
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]
We have youth, how about a fountain of smart.e4 e5 f4 d5
Advertisement
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).
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 planetrMatrix33d 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));
We have youth, how about a fountain of smart.e4 e5 f4 d5
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.).
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]
We have youth, how about a fountain of smart.e4 e5 f4 d5
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.
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? ;)

This topic is closed to new replies.

Advertisement