Matrix Rotate

Started by
8 comments, last by Zakwayda 18 years, 6 months ago
How do i set up a matrix and multiply a rotation so that it rotates around a certain point? What i'm trying to do is have a Sprite class and i have a float Rotation variable. in the rendering stage, the rotation of every sprite is then calculated but it rotates around the point (0,0,0)... i want it to rotate around the center of the sprite
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
Advertisement
As you've obviously noted, rotation is defined about the origin [0,0,0]. The trick is to do the following:

Translate by [-SpriteX,-SpriteY]
Rotate by [theta]
Translate by [SpriteX,SpriteY]

Basically you move the sprite to the origin before rotating, and then "undo" the move operation immediately afterwards [smile]

In the above example replace the "-SpriteX" and "-SpriteY" with the negative of whatever of the center point of your sprite is.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

doesn't that seem... un.. professional? (is that the word i'm looking for?) and take up memory? there has to be some way i can just pick an axis to rotate around...
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
Thats basic matrix mathematics for you [wink]

Go to any matrix-maths course and they'll explain it properly for you if you wish.

For performance, there might be a quicker way... D3DXMatrixRotationAxis() might be able to do what you want.

I would be surprised if you found matrix composition as a bottleneck in your pipeline, but if you did, it's quite simple to multiply them out on paper and then hard-code a simplified version...

It was a while back, but in my VB6 days I wrote this article on 2D/3D transforms. Hand multiplying the SRT matrix wasn't particularly entertaining, but it allowed me to eliminate a large number of common terms and improve the "function" performance by 2.5x (or thereabouts).

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

hmmm.. that vector, how would i specify that i want it at something like (100,200,0) and rotated on the Z axis?
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
i don't really understand how the D3DXMatrixRotationAxis() function works
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
can someone explain the D3DXVECTOR3 parameter? i tried putting the point it's at but it's not rotating on the Z axis at the point...

D3DXMATRIX *WINAPI D3DXMatrixRotationAxis(
D3DXMATRIX *pOut,
CONST D3DXVECTOR3 *pV,
FLOAT Angle
);
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
The D3DXVECTOR3 parameters is the normalized vector you wish to rotate around.For example, a vector (0.f, 1.f, 0.f) will make a rotation basically like a rotation in the y axis of the world. a vector (1.f, 0.f, 0.f) will make a rotation like one made around the x axis and so on....
.
ok, how's this? is this efficient? but i know it's not correct b/c it's not rotating about the center, it looks like it rotating in the bottom right axis...

[source lang=cpp]				D3DXMatrixRotationZ(&RotateM, m_Pos.Radian);				// Rotate about the center of sprite				D3DXMatrixTranslation( &TranslationM,					-1 * (Position.x + Center.x),					-1 * (Position.y + Center.y),					0.0f);				D3DXMatrixMultiply(&OutM, &TranslationM, &RotateM);				D3DXMatrixTranslation( &TranslationM,					Position.x + Center.x,					Position.y + Center.y,					0.0f);				D3DXMatrixMultiply(&OutM, &OutM, &TranslationM);				// Scaling				D3DXMatrixScaling( &ScaleM, 					m_fScaleFactorX, 					m_fScaleFactorY, 					1.0f );				D3DXMatrixMultiply(&OutM, &OutM, &ScaleM);					// Set and draw sprite				W_Graphics.GetSpriteCOM()->SetTransform( &OutM );
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
Quote:hmmm.. that vector, how would i specify that i want it at something like (100,200,0) and rotated on the Z axis?
Jollyjeffers gave the answer here:
Quote:Translate by [-SpriteX,-SpriteY]
Rotate by [theta]
Translate by [SpriteX,SpriteY]
In DirectX terms (pseudocode - I don't know the DirectX function names):
D3DXMatrix T1, R, T2, M;SetTranslationMatrix(T1, -100, -200, 0);SetRotationMatrixZ(R, angleInRadians);SetTranslationMatrix(T2, 100, 200, 0);M = T1 * R * T2;
M is now the matrix that will rotate your object on the z axis about the point (100,200,0), or any other point.

I'll also say that there may be better ways to do this. Generally it's a good idea to keep your objects - models, sprites, or whatever - defined in local space (usually centered at the origin and aligned with the world axes). Then when you're ready to draw, just apply the appropriate transform matrix, usually M = R*T. That avoids all the above complications with rotating an object about some other point than the origin.

This topic is closed to new replies.

Advertisement