Rotation around center

Started by
5 comments, last by haegarr 18 years, 4 months ago
Hello, I want to rotate a simple triangle around its center. For this, I use { D3DXMATRIX rot; D3DXMatrixRotationYawPitchRoll(&rot, y, x, z); lpD3DDevice->SetTransform(D3DTS_WORLD, &rot); } The problem is that the object is moving on the screen (while rotating) instead of staying static. Where can this come from? Thanks a lot!
Advertisement
What are the coordinates of the triangle?
Sounds like the triangle is not centered around it's local origin.
Coords are:

p1.x = 0.0f
p1.y = 1.0f
p1.z = 10.0f

p2.x = 1.0f
p2.y = -1.0f
p2.z = 10.0f

p3.x = -1.0f
p3.y = -1.0f
p3.z = 10.0f
The z co-ordinates of your tri show that is is not lying central to (0,0,0) but 10 units away. This is the reason.

If you want to rotate the tri (or a mesh in general) around a specific point, you have to do a transformation like this:
(1) translate the world so that the mesh's center becomes (0,0,0)
(2) do the rotation as usual
(3) translate the world back so that the mesh's center becomes its original again

D3D uses row vectors, so that the particular trafo you want to be applied first must be multiplied from the left (remember that trafos are given by matrices, and matrix multiplication isn't commutative: M1*M2 != M2*M1).
So I suggest something like this (without being proven by implementation):
D3DXMATRIX temp,world;// step (1)D3DXMatrixTranslation(&world, 0, 0, -10);// step (2)D3DXMatrixRotationYawPitchRoll(&temp, y, x, z);D3DXMatrixMultiply(&world, &world, &temp);// step (3)D3DXMatrixTranslation(&temp, 0, 0, 10);D3DXMatrixMultiply(&world, &world, &temp);lpD3DDevice->SetTransform(D3DTS_WORLD, &world);


If I haven't made a mistake, the "leftmost" trafo will be the translation by -10 in z direction ( (0,0,10) is more or less the center of your tri). Then it is rotated. At least it is translated back to where it was:
M := T(0,0,-10) * R(y,x,z) * T(0,0,10)

Maybe it still tumbles a little bit, but you can see the principle from this.
Appendix: The mesh normally has a so-called "local co-ordinate system" (or "local frame" for short) with an origin and orientation (and perhaps scale). The mesh's vertices are (also normally) defined with respect to this frame. So you may translate the entire mesh without explicitely touching each and every vertex position.

You tell D3D how this local frame is given w.r.t. the world by appropriately setting the D3DTS_WORLD transformation.

Comparing this with your original solution, you see that the tri's local frame has had an origin at (0,0,0) and an orientation of yaw/pitch/roll(y,x,z). "Inside" the frame the tri's vertex co-ordinates are as you have posted.

That is: You transform the local frame by your rotation, and the mesh is transformed _with it_, but not _inside it_.

When first translating the mesh, you alter the local frame's origin, making the rotation to occur around another point. By translating the frame back you restore the its origin.
Thanks for all those explanations. I now have a texture-mapped rotating cube that is working perfectly! Thanks.
Please notice that the cube does not rotate in another way than the single tri has done. When tracking a single face during rotation you'll see that it translates on a circular path. Will say, the explanations above principally also hold for a cube (or any other mesh). The only thing is that the cube is by itself symmetric around (0,0,0) and hence rotation around (0,0,0) is more likely than that you've expected already for the tri.

This topic is closed to new replies.

Advertisement