Skip to main content
gamedev.net
🔒 Locked

Help with Rotation function

Started by boolean010 Aug 21, 2000 at 12:29 AM 5 replies 550+ views
Original Post
boolean010
boolean010
Hello everyone, I''ve written a simple program that''s suppose to rotate a 3d wireframe cube on the screen, the only problem is that even though I specify an angle for both the x and the y the program only rotates around the y. I''ve included my function below, any help would be appreciated. Thank You Boolean0110 void RotateObject ( float angx, float angy, float angz ) { float x, y, z; float newx, newy, newz; float worldZ = testObject.worldPos.z; float csx, snx; float csy, sny; float csz, snz; csx = cos(angx*3.14/180); snx = sin(angx*3.14/180); csy = cos(angy*3.14/180); sny = sin(angy*3.14/180); csz = cos(angz*3.14/180); snz = sin(angz*3.14/180); // Rotate original set of vertices tempObject = testObject; for ( int currPoly=0; currPoly
** boolean010 **
wolverine
wolverine
try doing it like this:

    
...

newx = tempObject.face[currPoly].vertex[currVertex].x;
newy = tempObject.face[currPoly].vertex[currVertex].y;
newz = tempObject.face[currPoly].vertex[currVertex].z;


// Rotate around x-axis

if ( angx != 0 ) {
newy = newy * csx - newz * snx;
newz = newy * snx + newz * csx;
newx = newx;
}


// Rotate around y-axis

if ( angy != 0 ) {
newx = newx * csy - newz * sny;
newz = newx * sny + newz * csy;
newy = newy;
}

// Rotate around z-axis

if ( angz != 0 ) {
newx = newx * csz - newy * snz;
newy = newx * snz + newy * csz;
newz = newz;
}

...


hope it works
boolean010
boolean010
That didn''t seem to work. I think instead of the problem
being specific to the RotateObject function. I think the problem
might be the program as a whole. So I''ve included the source code. Again, I really appreciate all the input I can get, and yes, I''m new to programming and 3d.

// Include files
///////////////////////////////////////////////////////////////////////
#include
#include


// Constant declaration
///////////////////////////////////////////////////////////////////////
const char CLASS_NAME[] = "Guava App";

const int POINTS_IN_POLY = 4;
const int MAX_POINTS = 4;
const int MAX_POLYS = 6;
const int DISTANCE = 500;



// Type declaration
///////////////////////////////////////////////////////////////////////
typedef struct Point3d_typ {
float x, y, z;
} Point3d;

typedef struct Poly_typ {
Point3d vertex[POINTS_IN_POLY];
} Poly;

typedef struct Object3d_typ {
Poly face[MAX_POLYS];
Point3d worldPos;
int polyCount;
} Object3d;


// Global variables
///////////////////////////////////////////////////////////////////////
HDC hdc;
HPEN hWhitePen = CreatePen ( PS_SOLID, 0, RGB(255,255,255) );
HPEN hBlackPen = CreatePen ( PS_SOLID, 0, RGB(0,0,0) );


Object3d testObject, tempObject;
int angx=0, angy=0, angz=0;
int deltax=1, deltay=1, deltaz=1;


int countClock=0, countSpeed=100;

// Function prototype
///////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WindowFunc ( HWND, UINT, WPARAM, LPARAM );


void InitObject ();
void DrawObject ( HWND hwnd, int draw );
void RotateObject ( float, float, float );
void Line ( HDC hdc, int x1, int y1, int x2, int y2 );


int WINAPI WinMain ( HINSTANCE hThisInst, HINSTANCE hPrevInst,
LPSTR lpszArgs, int nWinMode )
{
HWND hwnd;
MSG msg;
WNDCLASS wcl;

wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wcl.hCursor = LoadCursor ( NULL, IDC_ARROW );
wcl.hIcon = LoadIcon ( NULL, IDI_APPLICATION );
wcl.hInstance = hThisInst;
wcl.lpfnWndProc = WindowFunc;
wcl.lpszClassName = CLASS_NAME;
wcl.lpszMenuName = NULL;
wcl.style = 0;

if ( !RegisterClass(&wcl)) return 0;

hwnd = CreateWindow (
CLASS_NAME,
"Guava Application",
WS_OVERLAPPEDWINDOW,
0, 0, 640, 480,
NULL,
NULL,
hThisInst,
NULL
);

if ( !hwnd ) return 0;

ShowWindow ( hwnd, nWinMode );
UpdateWindow ( hwnd );

hdc = GetDC ( hwnd );



InitObject();



while ( 1 ) {
if ( PeekMessage ( &msg, NULL, 0, 0, PM_REMOVE ) ) {
if ( msg.message == WM_QUIT )
break;

TranslateMessage ( &msg );
DispatchMessage ( &msg );
}

DrawObject ( hwnd, 1 );
Sleep(14);
DrawObject ( hwnd, 0 );


RotateObject ( angx,angy,angz );

angx = (angx + 1) % 360;
angy = (angy + 2) % 360;


}
return 0;
}

LRESULT CALLBACK WindowFunc ( HWND hwnd, UINT message, WPARAM wParam,
LPARAM lParam )
{
switch ( message ) {
case WM_DESTROY:
ReleaseDC ( hwnd, hdc );
DeleteObject ( hWhitePen );
DeleteObject ( hBlackPen );
PostQuitMessage(0);
break;

break;


default:
return DefWindowProc ( hwnd, message, wParam, lParam );
}
return 0;
}

void InitObject ()
{
testObject.worldPos.x = 0;
testObject.worldPos.y = 0;
testObject.worldPos.z = 300;


testObject.polyCount = 6;

testObject.face[0].vertex[0].x = -30;
testObject.face[0].vertex[0].y = 30;
testObject.face[0].vertex[0].z = 30;

testObject.face[0].vertex[1].x = -30;
testObject.face[0].vertex[1].y = 30;
testObject.face[0].vertex[1].z = -30;

testObject.face[0].vertex[2].x = 30;
testObject.face[0].vertex[2].y = 30;
testObject.face[0].vertex[2].z = -30;

testObject.face[0].vertex[3].x = 30;
testObject.face[0].vertex[3].y = 30;
testObject.face[0].vertex[3].z = 30;


testObject.face[1].vertex[0].x = 30;
testObject.face[1].vertex[0].y = 30;
testObject.face[1].vertex[0].z = -30;

testObject.face[1].vertex[1].x = -30;
testObject.face[1].vertex[1].y = 30;
testObject.face[1].vertex[1].z = -30;

testObject.face[1].vertex[2].x = -30;
testObject.face[1].vertex[2].y = -30;
testObject.face[1].vertex[2].z = -30;

testObject.face[1].vertex[3].x = 30;
testObject.face[1].vertex[3].y = -30;
testObject.face[1].vertex[3].z = -30;

testObject.face[2].vertex[0].x = -30;
testObject.face[2].vertex[0].y = -30;
testObject.face[2].vertex[0].z = 30;

testObject.face[2].vertex[1].x = 30;
testObject.face[2].vertex[1].y = -30;
testObject.face[2].vertex[1].z = 30;

testObject.face[2].vertex[2].x = 30;
testObject.face[2].vertex[2].y = -30;
testObject.face[2].vertex[2].z = -30;

testObject.face[2].vertex[3].x = -30;
testObject.face[2].vertex[3].y = -30;
testObject.face[2].vertex[3].z = -30;


testObject.face[3].vertex[0].x = -30;
testObject.face[3].vertex[0].y = 30;
testObject.face[3].vertex[0].z = 30;

testObject.face[3].vertex[1].x = 30;
testObject.face[3].vertex[1].y = 30;
testObject.face[3].vertex[1].z = 30;

testObject.face[3].vertex[2].x = 30;
testObject.face[3].vertex[2].y = -30;
testObject.face[3].vertex[2].z = 30;

testObject.face[3].vertex[3].x = -30;
testObject.face[3].vertex[3].y = -30;
testObject.face[3].vertex[3].z = 30;


testObject.face[4].vertex[0].x = -30;
testObject.face[4].vertex[0].y = 30;
testObject.face[4].vertex[0].z = 30;

testObject.face[4].vertex[1].x = -30;
testObject.face[4].vertex[1].y = -30;
testObject.face[4].vertex[1].z = 30;

testObject.face[4].vertex[2].x = -30;
testObject.face[4].vertex[2].y = -30;
testObject.face[4].vertex[2].z = -30;

testObject.face[4].vertex[3].x = -30;
testObject.face[4].vertex[3].y = 30;
testObject.face[4].vertex[3].z = -30;


testObject.face[5].vertex[0].x = 30;
testObject.face[5].vertex[0].y = 30;
testObject.face[5].vertex[0].z = 30;

testObject.face[5].vertex[1].x = 30;
testObject.face[5].vertex[1].y = 30;
testObject.face[5].vertex[1].z = -30;

testObject.face[5].vertex[2].x = 30;
testObject.face[5].vertex[2].y = -30;
testObject.face[5].vertex[2].z = -30;

testObject.face[5].vertex[3].x = 30;
testObject.face[5].vertex[3].y = -30;
testObject.face[5].vertex[3].z = 30;




tempObject = testObject;
}

void DrawObject ( HWND hwnd, int draw )
{
float x, y, z;
int screenX1, screenY1;
int screenX2, screenY2;


if ( draw )
SelectObject ( hdc, hWhitePen );
else
SelectObject ( hdc, hBlackPen );


float worldX = tempObject.worldPos.x;
float worldY = tempObject.worldPos.y;
float worldZ = tempObject.worldPos.z;


for ( int currPoly=0; currPoly

for ( int currVertex=0; currVertex
x = tempObject.face[currPoly].vertex[currVertex].x+worldX;
y = tempObject.face[currPoly].vertex[currVertex].y+worldY;
z = tempObject.face[currPoly].vertex[currVertex].z+worldZ;

screenX1 = (int) 320 + ( x / z * DISTANCE );
screenY1 = (int) 240 - ( y / z * DISTANCE );


x = tempObject.face[currPoly].vertex[currVertex+1].x+worldX;
y = tempObject.face[currPoly].vertex[currVertex+1].y+worldY;
z = tempObject.face[currPoly].vertex[currVertex+1].z+worldZ;

screenX2 = (int) 320 + ( x / z * DISTANCE );
screenY2 = (int) 240 - ( y / z * DISTANCE );

Line ( hdc, screenX1, screenY1, screenX2, screenY2 );

}

x = tempObject.face[currPoly].vertex[0].x+worldX;
y = tempObject.face[currPoly].vertex[0].y+worldY;
z = tempObject.face[currPoly].vertex[0].z+worldZ;

screenX1 = 320 + ( x / z * DISTANCE );
screenY1 = 240 - ( y / z * DISTANCE );

Line ( hdc, screenX1, screenY1, screenX2, screenY2 );
}

}

void Line ( HDC hdc, int x1, int y1, int x2, int y2 )
{
MoveToEx ( hdc, x1, y1, NULL );
LineTo ( hdc, x2, y2 );
}

void RotateObject ( float angx, float angy, float angz )
{
float x, y, z;
float newx, newy, newz;
float worldZ = testObject.worldPos.z;
float csx, snx;
float csy, sny;
float csz, snz;

csx = cos(angx*3.14/180);
snx = sin(angx*3.14/180);

csy = cos(angy*3.14/180);
sny = sin(angy*3.14/180);

csz = cos(angz*3.14/180);
snz = sin(angz*3.14/180);


// Rotate original set of vertices
tempObject = testObject;



for ( int currPoly=0; currPoly for ( int currVertex=0; currVertex
newx = x = tempObject.face[currPoly].vertex[currVertex].x;
newy = y = tempObject.face[currPoly].vertex[currVertex].y;
newz = z = tempObject.face[currPoly].vertex[currVertex].z;

// Rotate around x-axis
if ( angx != 0 ) {
newy = y * csx - z * snx;
newz = y * snx + z * csx;
newx = x;
}



// Rotate around y-axis
if ( angy != 0 ) {
newx = x * csy - z * sny;
newz = x * sny + z * csy;
newy = y;
}

// Rotate around z-axis
if ( angz != 0 ) {
newx = x * csz - y * snz;
newy = x * snz + y * csz;
newz = z;
}





tempObject.face[currPoly].vertex[currVertex].x = newx;
tempObject.face[currPoly].vertex[currVertex].y = newy;
tempObject.face[currPoly].vertex[currVertex].z = newz;
}

}

}

** boolean010 **
wolverine
wolverine
use the source tags to put your source code in here. it looks better and it's easier to read (read the forum faq if you don't know how to put them)

this is your rotating function:
            
void RotateObject ( float angx, float angy, float angz )
{
float x, y, z;
float newx, newy, newz;
float worldZ = testObject.worldPos.z;
float csx, snx;
float csy, sny;
float csz, snz;

csx = cos(angx*3.14/180);
snx = sin(angx*3.14/180);

csy = cos(angy*3.14/180);
sny = sin(angy*3.14/180);

csz = cos(angz*3.14/180);
snz = sin(angz*3.14/180);


// Rotate original set of vertices

tempObject = testObject;


for ( int currPoly=0; currPoly
for ( int currVertex=0; currVertex

newx = x = tempObject.face[currPoly].vertex[currVertex].x;
newy = y = tempObject.face[currPoly].vertex[currVertex].y;
newz = z = tempObject.face[currPoly].vertex[currVertex].z;

// Rotate around x-axis

if ( angx != 0 ) {
newy = y * csx - z * snx;
newz = y * snx + z * csx;
newx = x;
}


// Rotate around y-axis

if ( angy != 0 ) {
newx = x * csy - z * sny;
newz = x * sny + z * csy;
newy = y;
}

// Rotate around z-axis

if ( angz != 0 ) {
newx = x * csz - y * snz;
newy = x * snz + y * csz;
newz = z;
}



tempObject.face[currPoly].vertex[currVertex].x = newx;
tempObject.face[currPoly].vertex[currVertex].y = newy;
tempObject.face[currPoly].vertex[currVertex].z = newz;
}

}



I suppose you take angz=0. right?

Well imagine that in some part of your program angzx=10 and angy=15. Then you call RotateObject( angx, angy, angz).

Your function will execute this first:
if ( angx != 0 ) {
newy = y * csx - z * snx;
newz = y * snx + z * csx;
newx = x;
}

newx and newy will have new values.
When you make this:

if ( angy != 0 ) {
newx = x * csy - z * sny;
newz = x * sny + z * csy;
newy = y;
}

you will replace the values of newx and newy without saving them.
That's what i think the problem is.
I didn't look at the entire code, but try solving this problem first, and if you don't suceed post again.
And put your program with the source tags.


Edited by - wolverine on August 24, 2000 10:08:39 AM
boolean010
boolean010
Hello Wolverine,

I would like to thank you for taking the time to help me out, your last suggestion ( which is very similiar to the first) got things going the way they needed to be. I have to admit that sometimes when your programming your eyes only see what you want them to see, so when I saw your first post I assumed that It was because I wasn''t initilaizing the (newx,newy,newz) variables, and right away, without reading the full modification I proceeded to try what you suggested, and that''s where the problem came in. Thanks again

** boolean010 **
FReY
FReY
    

void RotateObject ( float angx, float angy, float angz )
{
float x, y, z;
float newx, newy, newz;
float worldZ = testObject.worldPos.z;
float csx, snx;
float csy, sny;
float csz, snz;
csx = cos(angx*3.14/180);
snx = sin(angx*3.14/180);
csy = cos(angy*3.14/180);
sny = sin(angy*3.14/180);
csz = cos(angz*3.14/180);
snz = sin(angz*3.14/180);
// Rotate original set of vertices

tempObject = testObject;
for ( int currPoly=0; currPoly
for ( int currVertex=0; currVertex
newx = x = tempObject.face[currPoly].vertex[currVertex].x;
newy = y = tempObject.face[currPoly].vertex[currVertex].y;
newz = z = tempObject.face[currPoly].vertex[currVertex].z;
// Rotate around x-axis

if ( angx != 0 ) {
newy = y * csx - z * snx;
newz = y * snx + z * csx;
y=newy;
z=newz;

}
// Rotate around y-axis

if ( angy != 0 ) {
newx = x * csy - z * sny;
newz = x * sny + z * csy;
x=newx;
z=newz;
}
// Rotate around z-axis

if ( angz != 0 ) {
newx = x * csz - y * snz;
newy = x * snz + y * csz;
x=newx;
y=newy;
}
tempObject.face[currPoly].vertex[currVertex].x = newx;
tempObject.face[currPoly].vertex[currVertex].y = newy;
tempObject.face[currPoly].vertex[currVertex].z = newz;
}
}


The above program *SHOULD* be correct, notice the:
x=newx,y=newy,z=newz lines added.

Of course, I don''t know if AP''s code works, I haven''t tried it, but mine should...

FReY
do unto others... and then run like hell.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.