// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** //
// Description : m_SetRotation sets the angle of the sprite.
// Parameters : angle - the angle to rotate to.
// Return Values: none.
// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** //
void CSpriteInstance::m_setRotation(float angle)
{
if(m_VB)
{
m_VB->Release();
m_VB = NULL;
}
//convert to rads
angle = angle * (D3DX_PI/180);
//center of the sprite X and Y
float center_x, center_y;
center_x = m_Vertices[1].x - (m_width/2);
center_y = m_Vertices[3].y - (m_height/2);
//calculate the hypot
float hyp = (squ(m_width/2) + squ(m_height/2));
hyp = sqrt(hyp);
m_Vertices[0].x = center_x - sin(angle) * hyp;
m_Vertices[0].y = center_y - cos(angle) * hyp;
m_Vertices[1].x = center_x + sin(angle) * hyp;
m_Vertices[1].y = center_y - cos(angle) * hyp;
m_Vertices[2].x = center_x + sin(angle) * hyp;
m_Vertices[2].y = center_y + cos(angle) * hyp;
m_Vertices[3].x = center_x - sin(angle) * hyp;
m_Vertices[3].y = center_y + cos(angle) * hyp;
//create the vertex buffer
pTemplate->pDevice->CreateVertexBuffer(4*sizeof(FVF2D), 0, FVF2D_FORMAT,
D3DPOOL_DEFAULT, &m_VB);
VOID* pVertices = NULL;
//lock and copy the square
m_VB->Lock(0, sizeof(m_Vertices), (BYTE**)&pVertices, 0);
memcpy(pVertices, m_Vertices, sizeof(m_Vertices));
//unlock
m_VB->Unlock();
}
I calculate the center of the sprite, then using pythagorams threum i calculate the lenght of the hypotenuse, I then use the center to calculate the new positions of each vertex.
this is the order of the vertices
topleft[0]
topright[1]
bottomright[2]
bottomleft[3]
Before anyone starts saying use matrices, then id like to say "no" <img src="smile.gif" width=15 height=15 align=middle> i dont want to use them, this way I will learn more
Thanks for your help in advance <img src="smile.gif" width=15 height=15 align=middle> </pre>
Rotating a Polygon
I decided to write my own rotation function for my sprites in dx8, i cant manage to get it working, i use a textured square
Didn't tested it, I don't actually think it will work but...
ok, imagine that we make a cartesian plane centered in center_x, center_y.
now we take m_Vertices[1] and trace a line to the center.
That angle is Alpha.
we need also:
Hypot = sqrt(m_Vertices[1].y^2 + m_Vertices[1].x^2);
Now:
Alpha = asin(m_Vertices[1].y - center_y/Hypot);
Temp = acos(m_Vertices[1].y - center_y/Hypot);
// To get a 2*Pi angle
if (Temp < 0 && Alpha > 0){Alpha += 2*(Alpha - D3DX_PI/4);}
if (Temp < 0 && Alpha < 0){Alpha -= 2*(Alpha + D3DX_PI/4);}
//that's some cheating to make it a 2*Pi degree
//Anyway, if this doesen't work try to get the Alpha Value
//Now, the angle you want to rotate:
Alpha += Angle;
m_Vertices[0].x = center_x + sin(D3DX_PI - Alpha) * hyp;
m_Vertices[0].y = center_y - cos(D3DX_PI - Alpha) * hyp;
m_Vertices[1].x = center_x + sin(Alpha) * hyp;
m_Vertices[1].y = center_y + cos(Alpha) * hyp;
m_Vertices[2].x = center_x - sin( - Alpha) * hyp;
m_Vertices[2].y = center_y + cos( - Alpha) * hyp;
m_Vertices[3].x = center_x - sin(D3DX_PI + Alpha) * hyp;
m_Vertices[3].y = center_y - cos(D3DX_PI + Alpha) * hyp;
Well, tell me what happends.
[edited by - algumacoisaqualquer on August 5, 2002 7:04:18 PM]
ok, imagine that we make a cartesian plane centered in center_x, center_y.
now we take m_Vertices[1] and trace a line to the center.
That angle is Alpha.
we need also:
Hypot = sqrt(m_Vertices[1].y^2 + m_Vertices[1].x^2);
Now:
Alpha = asin(m_Vertices[1].y - center_y/Hypot);
Temp = acos(m_Vertices[1].y - center_y/Hypot);
// To get a 2*Pi angle
if (Temp < 0 && Alpha > 0){Alpha += 2*(Alpha - D3DX_PI/4);}
if (Temp < 0 && Alpha < 0){Alpha -= 2*(Alpha + D3DX_PI/4);}
//that's some cheating to make it a 2*Pi degree
//Anyway, if this doesen't work try to get the Alpha Value
//Now, the angle you want to rotate:
Alpha += Angle;
m_Vertices[0].x = center_x + sin(D3DX_PI - Alpha) * hyp;
m_Vertices[0].y = center_y - cos(D3DX_PI - Alpha) * hyp;
m_Vertices[1].x = center_x + sin(Alpha) * hyp;
m_Vertices[1].y = center_y + cos(Alpha) * hyp;
m_Vertices[2].x = center_x - sin( - Alpha) * hyp;
m_Vertices[2].y = center_y + cos( - Alpha) * hyp;
m_Vertices[3].x = center_x - sin(D3DX_PI + Alpha) * hyp;
m_Vertices[3].y = center_y - cos(D3DX_PI + Alpha) * hyp;
Well, tell me what happends.
[edited by - algumacoisaqualquer on August 5, 2002 7:04:18 PM]
I couldnt get it to work, however it now rotates around
x = 0, y = 0
how can i get it to rotate around the objects center?
Heres the code I use:
x = 0, y = 0
how can i get it to rotate around the objects center?
Heres the code I use:
angle = angle * (D3DX_PI/180); fcos = cos(angle); fsin = sin(angle); //center of the sprite X and Y float center_x, center_y; center_x = m_Vertices[1].x - (m_width/2); center_y = m_Vertices[3].y - (m_height/2); //calculate the hypot float hyp = (squ(m_width/2) + squ(m_height/2)); hyp = sqrt(hyp); m_Vertices[0].x = (m_Vertices[0].x * fcos) - (m_Vertices[0].y * fsin); m_Vertices[0].y = (m_Vertices[0].x * fsin) + (m_Vertices[0].y * fcos); m_Vertices[1].x = (m_Vertices[1].x * fcos) - (m_Vertices[1].y * fsin); m_Vertices[1].y = (m_Vertices[1].x * fsin) + (m_Vertices[1].y * fcos); m_Vertices[2].x = (m_Vertices[2].x * fcos) - (m_Vertices[2].y * fsin); m_Vertices[2].y = (m_Vertices[2].x * fsin) + (m_Vertices[2].y * fcos); m_Vertices[3].x = (m_Vertices[3].x * fcos) - (m_Vertices[3].y * fsin); m_Vertices[3].y = (m_Vertices[3].x * fsin) + (m_Vertices[3].y * fcos);
OK This time
ive got it to stay in the same place, but for some reason the polygon scales ( by getting smaller ) each time i call the function, heres the new code :-)

float fcos = 0, fsin = 0; //convert to rads angle = angle * (D3DX_PI/180.0f); //calculate cos/sin fcos = cos(angle); fsin = sin(angle); float center_x = 0, center_y = 0; float vector_x = 0,vector_y = 0; //center of the sprite X and Y //transform the polygon to 0,0 for(index = 0; index < 4; index++) { center_x += m_Vertices[index].x; center_y += m_Vertices[index].y; } vector_x = center_x / 4; vector_y = center_y / 4; //transform the polygon to 0,0 for(index = 0; index < 4; index++) { m_Vertices[index].x -= vector_x; m_Vertices[index].y -= vector_y; } //rotate the polygon m_Vertices[0].x = (m_Vertices[0].x * fcos) - (m_Vertices[0].y * fsin); m_Vertices[0].y = (m_Vertices[0].x * fsin) + (m_Vertices[0].y * fcos); m_Vertices[1].x = (m_Vertices[1].x * fcos) - (m_Vertices[1].y * fsin); m_Vertices[1].y = (m_Vertices[1].x * fsin) + (m_Vertices[1].y * fcos); m_Vertices[2].x = (m_Vertices[2].x * fcos) - (m_Vertices[2].y * fsin); m_Vertices[2].y = (m_Vertices[2].x * fsin) + (m_Vertices[2].y * fcos); m_Vertices[3].x = (m_Vertices[3].x * fcos) - (m_Vertices[3].y * fsin); m_Vertices[3].y = (m_Vertices[3].x * fsin) + (m_Vertices[3].y * fcos); //retransform to original pos for(index = 0; index < 4; index++) { m_Vertices[index].x += vector_x; m_Vertices[index].y += vector_y; }
OK This time
ive got it to stay in the same place, but for some reason the polygon scales ( by getting smaller ) each time i call the function, heres the new code :-)

float fcos = 0, fsin = 0; //convert to rads angle = angle * (D3DX_PI/180.0f); //calculate cos/sin fcos = cos(angle); fsin = sin(angle); float center_x = 0, center_y = 0; float vector_x = 0,vector_y = 0; //center of the sprite X and Y //transform the polygon to 0,0 for(index = 0; index < 4; index++) { center_x += m_Vertices[index].x; center_y += m_Vertices[index].y; } vector_x = center_x / 4; vector_y = center_y / 4; //transform the polygon to 0,0 for(index = 0; index < 4; index++) { m_Vertices[index].x -= vector_x; m_Vertices[index].y -= vector_y; } //rotate the polygon m_Vertices[0].x = (m_Vertices[0].x * fcos) - (m_Vertices[0].y * fsin); m_Vertices[0].y = (m_Vertices[0].x * fsin) + (m_Vertices[0].y * fcos); m_Vertices[1].x = (m_Vertices[1].x * fcos) - (m_Vertices[1].y * fsin); m_Vertices[1].y = (m_Vertices[1].x * fsin) + (m_Vertices[1].y * fcos); m_Vertices[2].x = (m_Vertices[2].x * fcos) - (m_Vertices[2].y * fsin); m_Vertices[2].y = (m_Vertices[2].x * fsin) + (m_Vertices[2].y * fcos); m_Vertices[3].x = (m_Vertices[3].x * fcos) - (m_Vertices[3].y * fsin); m_Vertices[3].y = (m_Vertices[3].x * fsin) + (m_Vertices[3].y * fcos); //retransform to original pos for(index = 0; index < 4; index++) { m_Vertices[index].x += vector_x; m_Vertices[index].y += vector_y; }
OK This time
ive got it to stay in the same place, but for some reason the polygon scales ( by getting smaller ) each time i call the function, heres the new code :-)

float fcos = 0, fsin = 0; //convert to rads angle = angle * (D3DX_PI/180.0f); //calculate cos/sin fcos = cos(angle); fsin = sin(angle); float center_x = 0, center_y = 0; float vector_x = 0,vector_y = 0; //center of the sprite X and Y //transform the polygon to 0,0 for(index = 0; index < 4; index++) { center_x += m_Vertices[index].x; center_y += m_Vertices[index].y; } vector_x = center_x / 4; vector_y = center_y / 4; //transform the polygon to 0,0 for(index = 0; index < 4; index++) { m_Vertices[index].x -= vector_x; m_Vertices[index].y -= vector_y; } //rotate the polygon m_Vertices[0].x = (m_Vertices[0].x * fcos) - (m_Vertices[0].y * fsin); m_Vertices[0].y = (m_Vertices[0].x * fsin) + (m_Vertices[0].y * fcos); m_Vertices[1].x = (m_Vertices[1].x * fcos) - (m_Vertices[1].y * fsin); m_Vertices[1].y = (m_Vertices[1].x * fsin) + (m_Vertices[1].y * fcos); m_Vertices[2].x = (m_Vertices[2].x * fcos) - (m_Vertices[2].y * fsin); m_Vertices[2].y = (m_Vertices[2].x * fsin) + (m_Vertices[2].y * fcos); m_Vertices[3].x = (m_Vertices[3].x * fcos) - (m_Vertices[3].y * fsin); m_Vertices[3].y = (m_Vertices[3].x * fsin) + (m_Vertices[3].y * fcos); //retransform to original pos for(index = 0; index < 4; index++) { m_Vertices[index].x += vector_x; m_Vertices[index].y += vector_y; }
quote:
Original post by ACAC
OK This timeive got it to stay in the same place, but for some reason the polygon scales ( by getting smaller ) each time i call the function, heres the new code :-)
I''ll tell you why. Your transformation code (shown below for just one vertex) has a bug.
quote:
Original post by ACAC
m_Vertices[0].x = (m_Vertices[0].x * fcos) - (m_Vertices[0].y * fsin);
m_Vertices[0].y = (m_Vertices[0].x * fsin) + (m_Vertices[0].y * fcos);
And the problem is this. You''re modifying m_Vertices[index].x and then using the modified value to calculate m_Vertices[index].y when you should be using the previous, unmodified value of m_Vertices[index].x. That code is equivalent to the following:
quote:
Original post by ACAC
m_Vertices[0].x = (m_Vertices[0].x * fcos) - (m_Vertices[0].y * fsin);
new_x = m_Vertices[0].x;
m_Vertices[0].y = (new_x * fsin) + (m_Vertices[0].y * fcos);
You should have code like this instead to properly rotate:
quote:
Original post by ACAC
old_x = m_Vertices[0].x;
m_Vertices[0].x = (old_x * fcos) - (m_Vertices[0].y * fsin);
m_Vertices[0].y = (old_x * fsin) + (m_Vertices[0].y * fcos);
So, your complete set of transformation should be:
old_x = m_Vertices[0].x; m_Vertices[0].x = (old_x * fcos) - (m_Vertices[0].y * fsin); m_Vertices[0].y = (old_x * fsin) + (m_Vertices[0].y * fcos); old_x = m_Vertices[1].x; m_Vertices[1].x = (old_x * fcos) - (m_Vertices[1].y * fsin); m_Vertices[1].y = (old_x * fsin) + (m_Vertices[1].y * fcos); old_x = m_Vertices[2].x; m_Vertices[2].x = (old_x * fcos) - (m_Vertices[2].y * fsin); m_Vertices[2].y = (old_x * fsin) + (m_Vertices[2].y * fcos); old_x = m_Vertices[3].x; m_Vertices[3].x = (old_x * fcos) - (m_Vertices[3].y * fsin); m_Vertices[3].y = (old_x * fsin) + (m_Vertices[3].y * fcos);
Everything else looks perfectly fine. I didn''t check your later dx8 code, so I don''t know what''s wrong with that. For DX8 specific problems, you should visit the DirectX forum.
Graham Rhodes
Senior Scientist
Applied Research Associates, Inc.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement