Get translation and rotation based on a triangle

I have a model with some special triangles which marks the left and right hands.
I know the position of the vertices of the triangle given a frame of the animation . What I want to do is to place a weapon on his hand, based on this special triangle , with all the rotations and translations needed .
The translation it’s not a problem (I believe). For the rotatoin I tried to used two pairs of vertices and calculate Math.atan2 , but it does not work quite right .

What is the usual approach and required Math for doing it ?

Thanks !

Is this in 2D or 3D?

3d .

If you calculate the triangle normal and two perpendicular vectors in the triangle plane you have a complete coordinate system. You then construct a standard 4x4 rotation/translation matrix where the upper 3x3 part is set to the three NORMALIZED coordinate system vectors and the “translation” part of the matrix is the center of the triangle (or wherever you want it to be).

Here is also a short function to do this with three vectors (right, up, forward) and a position with the resulting Matrix4f, which is part of LWJGL:


	public Matrix4f getTransformationMatrix() {
		Matrix4f result = new Matrix4f();
		// The right vector is the X-axis
		result.m00 = (float) right.x;
		result.m01 = (float) right.y;
		result.m02 = (float) right.z;
		result.m03 = 0.0f;

		// // The up vector is the Y-axis
		result.m10 = (float) up.x;
		result.m11 = (float) up.y;
		result.m12 = (float) up.z;
		result.m13 = 0.0f;

		// // The forward vector is the Z-axis
		result.m20 = (float) forward.x;
		result.m21 = (float) forward.y;
		result.m22 = (float) forward.z;
		result.m23 = 0.0f;

		// Finally, the position
		result.m30 = (float) position.x;
		result.m31 = (float) position.y;
		result.m32 = (float) position.z;
		result.m33 = 1.0f;

		return result;
	}



My thoughts are along the same lines as krasse’s. Gory details as follows.

Say the vertices of the triangle have positions A, B and C initially, and A’, B’ and C’ in a frame of the animated model.

First make some vectors:
b = B - A
c = C - A
b’ = B’ - A’
c’ = C’ - A’
Then make two 3x3 matrices:
M = [ b | c | (b^c) ]
M’ = [ b’ | c’ | (b’^c’) ]
where [ b | c | d ] means the matrix with columns equal to the three vectors, and b^c is the cross product of two vectors.

Then the transformation that takes a position X in the original model to a new position X’ is:
X’ = M’ * inv(M) * (X - A) + A’
where inv(M) is the inverse matrix.

I can’t help thinking there must be a neater way of doing this though. Hopefully someone else will be good enough to post it. :wink:

Simon

maybe compute orthonormal axis :
A B C are vertices

AB=B-A
AC=C-A
N=AB^AC (Nx=AByACz-ABzACy Ny=ABzACx-ABxACz Nz=etc…)

then you got your three orthonormal axis (normalized) :
AY=N/|N|;
AZ=AB/[AB|;
AX=AY^AZ;

and its origin O is the vertice A

to compute world coordinate from local coordinate (LX,LY,LZ) you can do :
WorldPos=O+LXAX+LYAY+LZ*AZ

to compute local coordinate from world coordinate (WX,WY,WZ) you can do :
LX=(W-O).AX ( “.” mean scalar product)
LY=(W-O).AY ( “.” mean scalar product)
LZ=(W-O).AZ ( “.” mean scalar product)

NB : from this local axis you can also easily determine translation & rotation

If you use my Matrix4f solution you can simply transform all the weapon’s local coordinates where (0, 0, 0) will end up at the center of the triangle in the direction of the triangle normal.
You’ll have to use Vector4f and scale the result with the resulting w-coordinate, but that is just standard affine transform stuff in 3D.

I also know that it works in practice because I use the above function in my 3D L-system stuff to place meshes at a certain position + local coordinate system.

More info here:

I tried your solution last night, but I got stuck .
I have the Matrix4f which was returned by your function (let’s call it weaponMatrix) and have it normalized, and then the Matrix4f which represents the current modelview matrix (currentMatrix) .
Which operation I should do with the currentMatrix and the weaponMatrix to have my weapon place correctly in my current Matrix ?

Thank you very much guys .

(PS yes I suck at geometry and just want to make it work :frowning: )

I have a question for you teletubo:

  • How do you represent your game object coordinates? Are all the vertices of the triangles stored in world coordinates or are they local to the object?

The current (OpenGL) modelview matrix is applied in a later stage to either all the world coordinates or in some push/pop matrix manner if you use the local coordinate way (and perhaps in many other ways as well, I am only familiar with those two approaches).

The method depends on how the placement triangle is represented. Is it represented in global coordinates, you can just multiply all the vertices in the weapon with the “weapon matrix” and you are done.
If you have a chain of transformation matrices/quarterions, which is often the case when you have a body with limbs, you’ll have to append that chain with another matrix that describes the movement/rotation from the latest matrix in that chain to the wanted triangle.

I am not at all an expert in this area and I have only applied the world coordinate method. You might want to ask/search for an answer at gamedev.net also.

They are local to the object .

I already have the “latest matrix in that chain”, which is the matrix I referred to as currentMatrix in the previous post (it is the ModelView matrix after the trasformations on the body) .
The operation I’m looking for is exactly the one that “chains” my currentMatrix to the weaponMatrix I got from the method you provided .

I tried adding them then normalizing the axis columns, but it’s still not right, though I can see that the weapon follows the hands in some sort of … wrong way .

Thanks again .

You can do it like this I think:

Calculate the triangle vertices in global coordinates (with the current matrix) and get the coordinate system and Matrix4f (call it G) with the function.

You know that the unknown matrix M multiplied with the current matrix © will result in the same matrix as the one you calculated globally. This gives the following equation:

M x C = G

=>

M = G x inv©

You just have multiply the global matrix with the inverted current matrix.

It seems a bit more complicated than neccessary though…

it worked !

I did not do exactly what you told, but the trick was multiplying my matrices after correctly placing some transformations .
Honestly if you ask mr to explain what I did I can’t answer you, but well … thanks again !

Great!

I think that if you just use the local coordinate system for the last mesh/limb and create the matrix for the transformation to the triangle, you can skip that extra inversion part.

That’s exactly what I did . I think .