Divide complex matrix into simple matrices.

Started by
5 comments, last by dpadam450 2 months ago

Does anyone know how to divide complex rotation matrix into simple X, Y, and Z rotation matrices?

I was searching for it but can't find any sources how to divide a matrix.

Advertisement

I have code to decompose 3x3 rotation matrices into Euler angles but I'm not sharing it because it's generally not the right thing to do. Euler angles have a number of problems and should be avoided except as a way for humans to input rotations (and maybe for camera controllers). In both of those cases you only go from Euler to matrix, never the reverse.

A better method would be to decompose the matrix into rotation axis vector and rotation around that axis. That doesn't have the same issues as Euler angles.

it's generally not the right thing to do.

^^ This.

Sword7 said:
I was searching for it but can't find any sources how to divide a matrix.

Because you aren't “dividing a matrix”. You can implement a transformation in terms of additional transformations, but it's suspicious to even ask about why you're doing that. It isn't wrong so much as unusual.

Rather than “dividing a matrix”, you're trying to decompose it oddly. A 4x4 transformation matrix can be viewed as 3 basis vectors for each of x, y, an z, a shear vector, a translation vector, and a scalar that's usually 0 for a vector (when position is irrelevant or should vanish) and 1 for a point/vertex (when position matters). That's usually as far as it goes for breaking it down.

Normally that matrix would have the result of all three of your single-axis rotations as part of it, but they've already had the angles multiplied in through sine and cosine operations. Order matters, which is why they're usually composed directly from Euler angles rather than as three individual rotations. You'll have to undo that. The math isn't hard if there was neither shear nor scaling, typically giving either infinitely many solutions where you pick one in a half-circle range or giving no solution if the math doesn't work out correctly. Even so, asking for it suggests you've misunderstood something along the way.

It's one of those questions where asking it means you should probably learn more on the topic because the answer won't fully make sense. There are plenty of books and videos. “Mathematics for 3D Game Programming”, “3D Math Primer for Graphics and Game Development”, “Mathematics for Game Programming and Computer Graphics”, “Linear Algebra for Game Developers”, the free MIT Linear Algebra course on YouTube, the Khan Academy Linear Algebra course, take your pick or more besides.

@Sword7 Division isn't defined for matrices. The reason is that matrix 'multiplication' isn't really multiplication, it's composition. If you think of matrices like functions, then matrix multiplication is like F(G(x)) not F(x)*G(x). That's why order matters. If you want to undo the application of one matrix to another, you need to use the matrix inverse.

Sword7 said:
Does anyone know how to (CENSORED) complex rotation matrix into simple X, Y, and Z rotation matrices?

You can look up for code to convert rotations to Euler Angles.
I have one:

__forceinline sVec3 ToEuler (const int order = 0x012) 
	{
		int a0 = (order>>8)&3;
		int a1 = (order>>4)&3;
		int a2 = (order>>0)&3;

		sVec3 euler;
		float d = (*this)[a0][a2]; // this is actually a 4x4 matrix class using OpenGL convention
		
		if (d > (1.0f-FP_EPSILON)) 
		{ 
			euler[a0] = -atan2f((*this)[a2][a1], (*this)[a1][a1]);
			euler[a1] = -3.1415926535897932384626433832795f/2.0f; // it hurts to remove digits from PI, so...
			euler[a2] = 0;
			return euler;
		}
		if (d < -(1.0f-FP_EPSILON))
		{ 
			euler[a0] = -atan2f((*this)[a2][a1], (*this)[a1][a1]);
			euler[a1] = 3.1415926535897932384626433832795f/2.0f;
			euler[a2] = 0;
			return euler;
		}
		euler[a0] =	-atan2f(-(*this)[a1][a2], (*this)[a2][a2]);
		euler[a1] =	-asinf ( (*this)[a0][a2]);
		euler[a2] =	-atan2f(-(*this)[a0][a1], (*this)[a0][a0]);
		return euler;
	}

The code allows to set the order of Euler Angles.
0x012 maps to X,Y,Z order,
0x210 maps to Z,Y,X order, and so on.

The returned values of the vec3 are the x,y,z, angles in that given order.

You then can create 3 rotation matrices from X,Y,Z axis given those x,y,z, angles, which is what you want.

Each column of a model matrix equates to a vector in world space of the new x,y,z axis of that model. Depends what your goal is with the code, but if you have an airplane and the nose points down the z axis. You can find the angle that vector is rotated in the world this way. Might help solve your problem? State what your problem is and people might be able to give solutions to it.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

This topic is closed to new replies.

Advertisement