Cube rotation math problem

This is a discussion on Cube rotation math problem within the Game Programming forums, part of the General Programming Boards category; hey guys, i've got a problem that's driving me mad. I'm designing a little simple physics sim in opengl that ...

  1. #1
    n3v
    n3v is offline
    irregularly symmetrical n3v's Avatar
    Join Date
    Mar 2006
    Location
    Finland
    Posts
    67

    Cube rotation math problem

    hey guys, i've got a problem that's driving me mad. I'm designing a little simple physics sim in opengl that just uses cubes, and i'm trying to simulate realistic physics, but i first concluded that I'd have to account for the position of every vertex on the cube so i could test for impact against walls or other cubes. So, I made three 24 unit arrays, each the different axial component of a vertex. for example, if the first vertex was at position 1,1,1, the values of x[0], y[0], and z[0] would be 1 1 and 1.
    Anyway,I had to write a function to move the cube, but that was no problem, i simply increase all the values in the x verticies array by the same amount and it moves positively in the x direction, etc. now i'm trying to come up with a function to rotate the cube that would work something like glRotate. I was planning to have my function take the following arguments:
    1. magnitude of rotation (number of degrees) in float
    2. three floats that would have a value between 0.0 and 1.0 for each axis to determine the magnitude of rotation in each. for example 90.0,1.0,0.5,0.0 would rotate the cube 90 degrees relative to the x axis, 45 degrees relative to the y axis, and none at all in relation to the z axis.

    and anyway, the first attempts i've had at making this function have been total rubbish, they've failed miserably. My latest (and totally not working) code is as follows:
    Code:
    void object::spin(float deg, float x, float y, float z) {
         float xlength,ylength,zlength,len1,len2;
         deg = ((deg/180)*pi);
         len1 = (sin(deg)*2);
         len2 = (cos(deg)*2) - 2;
         xlength = (len1 * z)+(len2 * y);
         ylength = (len1 * x)+(len2 * z);
         zlength = (len1 * y)+(len2 * x);
         for (int n = 0; n<24;n++) { //xvertex, yvertex, and zvertex are the names for the arrays in which the vertex data is kept
             xvertex[n] += xlength;
             yvertex[n] += ylength;
             zvertex[n] += zlength;
             }
         }
    any help would be greatly appreciated. Thanks.
    If you make a man a fire,
    he will be warm for a day.
    If you set a man on fire,
    he will be warm for the rest of his life.

  2. #2
    Registered User
    Join Date
    Oct 2006
    Posts
    250
    You might want to take a look at some of David Baraff's introduction to physically based modeling. Once you got the basics down, he also published more advanced stuff, but this particular series provides a really nice intro to the material IMHO.

  3. #3
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,584
    You don't have to account for all the vertices but you do have to account for the planes created by the vertices.

    Collisions with objects can be broken down into ray/plane intersection tests to decide if a point is on the plane, in the negative half space of it, or in the positive half space of it. After doing this you can do some plug and chug into the ray formula to get the exact location of the intersection.

    However if you have interpenetrated the plane you must 'backup' to the surface of the plane so that objects do not interpenetrate. Pixel perfect collision detection is simple mathematically but not all that simple from a programming standpoint.

    There are several documents on the internet concerning this and I'd recommend buying a book on the topic as it is far to vast to dive into in one post.

    Normally to maintain interactive frame rates collision tests look something like this:

    • Spatial rejection - is the object even close enough to the camera to be of any concern?
    • Trivial rejection - the object is close enough to the camera/player to be of concern, but does it even have a chance of colliding with another object in the next frame? Usually a sphere test.
    • Model vertex rejection - ok so we know the first two tests passed so we are going to have a collision. But which triangles are affected and which ones will definitely not be affected? No point in doing expensive tests on triangles that absolutely cannot be affected in the frame.
    • Perform expensive test on triangles that are/could be affected.
    • Pass information to physics portion of engine to calculate physical impules, angular momentum, etc, of impact.


    Doing operations like rotation, translation, scaling, shearing, etc, at the vertex level flies in the face of the design of OpenGL.

    3D graphics API's use transforms to transform vertices from local/model space to screen space. Rotations, translations, scaling, shearing, etc, etc, are all accomplished through various matrices. Concatenating these matrices arrives at the final matrix and then the vertices are transformed using this final matrix.
    Last edited by VirtualAce; 07-22-2007 at 06:33 AM.

  4. #4
    n3v
    n3v is offline
    irregularly symmetrical n3v's Avatar
    Join Date
    Mar 2006
    Location
    Finland
    Posts
    67
    well all of that is very nice, but looks rather looming and difficult at the present time. I'm going to be digging into it, but my original post was just for some help making a function that will rotate an array of verticies. like, for example, i have some verticies for a cube just like this:

    Code:
    // Front Face				
            glVertex3f(-1.0f, -1.0f,  1.0f);
            glVertex3f(-1.0f,  1.0f,  1.0f);
            glVertex3f( 1.0f,  1.0f,  1.0f);
            glVertex3f( 1.0f, -1.0f,  1.0f);
            	
    		// Back Face
    						
            glVertex3f(-1.0f, -1.0f, -1.0f);
            glVertex3f(-1.0f,  1.0f, -1.0f);
            glVertex3f( 1.0f,  1.0f, -1.0f);
            glVertex3f( 1.0f, -1.0f, -1.0f);
    		// Top Face
    					
            glVertex3f(-1.0f,  1.0f, -1.0f);
            glVertex3f(-1.0f,  1.0f,  1.0f);
            glVertex3f( 1.0f,  1.0f,  1.0f); 
            glVertex3f( 1.0f,  1.0f, -1.0f);
    		// Bottom Face
    						
            glVertex3f(-1.0f, -1.0f, -1.0f);
            glVertex3f( 1.0f, -1.0f, -1.0f);
            glVertex3f( 1.0f, -1.0f,  1.0f);
            glVertex3f(-1.0f, -1.0f,  1.0f);
    		// Right Face
    					
            glVertex3f( 1.0f, -1.0f, -1.0f); 
            glVertex3f( 1.0f,  1.0f, -1.0f); 
            glVertex3f( 1.0f,  1.0f,  1.0f);
            glVertex3f( 1.0f, -1.0f,  1.0f);
    		// Left Face
    					
            glVertex3f(-1.0f, -1.0f, -1.0f);
            glVertex3f(-1.0f, -1.0f,  1.0f);
            glVertex3f(-1.0f,  1.0f,  1.0f);
            glVertex3f(-1.0f,  1.0f, -1.0f);
    but i simply have the verticies in vectors, like this :
    Code:
    // Front Face		
            glVertex3f(xvertex[0], yvertex[0],  zvertex[0]);
            glVertex3f(xvertex[1], yvertex[1],  zvertex[1]);
            glVertex3f(xvertex[2], yvertex[2],  zvertex[2]);
            glVertex3f(xvertex[3], yvertex[3],  zvertex[3]);
    
            // Back Face
    					
            glVertex3f(xvertex[4], yvertex[4],  zvertex[4]);
            glVertex3f(xvertex[5], yvertex[5],  zvertex[5]);
            glVertex3f(xvertex[6], yvertex[6],  zvertex[6]);
            glVertex3f(xvertex[7], yvertex[7],  zvertex[7]);
    
            // Top Face
    				
            glVertex3f(xvertex[8], yvertex[8],  zvertex[8]);
            glVertex3f(xvertex[9], yvertex[9],  zvertex[9]);
            glVertex3f(xvertex[10], yvertex[10],  zvertex[10]);
            glVertex3f(xvertex[11], yvertex[11],  zvertex[11]);
            // Bottom Face
    
            glVertex3f(xvertex[12], yvertex[12],  zvertex[12]);
            glVertex3f(xvertex[13], yvertex[13],  zvertex[13]);
            glVertex3f(xvertex[14], yvertex[14],  zvertex[14]);
            glVertex3f(xvertex[15], yvertex[15],  zvertex[15]);
            
    		// Right Face
    					
            glVertex3f(xvertex[16], yvertex[16],  zvertex[16]);
            glVertex3f(xvertex[17], yvertex[17],  zvertex[17]);
            glVertex3f(xvertex[18], yvertex[18],  zvertex[18]);
            glVertex3f(xvertex[19], yvertex[19],  zvertex[19]);
    		// Left Face
    					
            glVertex3f(xvertex[20], yvertex[20],  zvertex[20]);
            glVertex3f(xvertex[21], yvertex[21],  zvertex[21]);
            glVertex3f(xvertex[22], yvertex[22],  zvertex[22]);
            glVertex3f(xvertex[23], yvertex[23],  zvertex[23]);
    i just am having problem coming up with a function that will rotate that set of verticies (or any set of vertices) relative to the x, y, and z axes, and replace the verticies' current values. I think it just boils down to trig, which isn't something i have a problem with, but I'm just having a total brain block as to how it'd be done.
    If you make a man a fire,
    he will be warm for a day.
    If you set a man on fire,
    he will be warm for the rest of his life.

  5. #5
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,584
    Doing operations like rotation, translation, scaling, shearing, etc, at the vertex level flies in the face of the design of OpenGL.

    3D graphics API's use transforms to transform vertices from local/model space to screen space. Rotations, translations, scaling, shearing, etc, etc, are all accomplished through various matrices. Concatenating these matrices arrives at the final matrix and then the vertices are transformed using this final matrix.
    In Direct3D:

    Code:
    D3DXMATRIX matRotate;
    D3DXMatrixRotationYawPitchRoll(&matRotate,x,y,z);
    
    D3DXMATRIX matTrans;
    D3DXMatrixTranslation(&matTrans,vecPos.x,vecPos.y,vecPos.z);
    
    D3DXMATRIX matWorld;
    matWorld=matRotate&matTrans;
    
    m_pDevice->SetTransform(D3DTS_WORLD,&matWorld);
    
    Render();
    You don't perform translation, scaling, or rotation at the vertex level. You do this by transforming the vertices by a matrix that has been created by concatenating or multiplying scale, rotation, translation, etc, matrices together.
    The days of doing this manually have long since passed.

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    41
    What you want to do seems to be exactly like this tutorial from NeHe (rotating cube). If you're new to OpenGL this is a good place to start learning.

    http://nehe.gamedev.net/data/lessons....asp?lesson=05

    /f

  7. #7
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901
    Look into pushing and poping matrices. You can rotate a cube or any object for that matter, completely independent of the entire modelview matrix by simply pushing a matrix, doing your rotation, then popping it again. This will rotate whatever is drawn inside the push/popmatrix block leaving any other objects unaltered.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. camera rotation matrix
    By Vick jr in forum Game Programming
    Replies: 5
    Last Post: 05-26-2009, 08:16 AM
  2. A 3D rotation problem
    By GOBLIN-85 in forum C++ Programming
    Replies: 0
    Last Post: 03-08-2009, 07:17 AM
  3. Math C Programming problem
    By ckyle in forum C Programming
    Replies: 1
    Last Post: 02-09-2006, 02:33 PM
  4. Math Problem....
    By NANO in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 11-11-2002, 03:37 AM
  5. math problem
    By unixOZ in forum Linux Programming
    Replies: 4
    Last Post: 10-19-2002, 12:17 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21