现在的位置: 首页 > 综合 > 正文

关于红宝书上机器人手臂的例子和矩阵变换

2014年03月09日 ⁄ 综合 ⁄ 共 3569字 ⁄ 字号 评论关闭
红宝书上根据机器人手臂的例子做了简单的修改.
本来以为这次重新看了矩阵变换,对矩阵变换已经有了比较深刻的认识,直到合上书,在没有参考书上代码的情况下,
尝试自己实现这个简单的机器人手臂的变换,才知道还是有许多不足.

总结几个在理解model矩阵变化时, 需要注意的地方:
1. model矩阵变换的顺序和代码的顺序相反
2. 可以理解为 ,各种model变换,都会影响坐标轴本身.比如  glRotatef(),绕 z 轴旋转 30度后, 相当于整个坐标系(x,y,z  3轴),
都跟着做了一次变换. 再调用 glTranslatef() 沿x轴向左平移时, 就不是沿着原本坐标系的x轴向左平移了,
而是沿着新坐标系的 x轴向左平移, 相当于 向以前坐标轴的左下方平移了.
3. glLoadIdentity() 会将坐标系还原,使得坐标系不再受到以前各种变换的影响,而变成最最开始的 x轴 横平, y轴竖直,z轴向外.
#include <GL/glut.h>

static float shoulder_angle = 0.0f;
static float elbow_angle = 0.0f;
static float finger_angle = 0.0f;
static float triangle_angle = 0.0f;
static float ball_angle = 0.0f;

const float BIG_ARM_LENGTH = 2.0f;
const float SMALL_ARM_LENGTH = 1.5f;
const float FINGER_LENGTH = 1.0f;
const float BALL_RADIUS = 0.5f;

void init()
{
    glClearColor( 0.0,0.0,0.0,0.0);
    glShadeModel( /*GL_FLAT*/GL_SMOOTH );
    glEnable( GL_CULL_FACE );
    glCullFace( GL_BACK);
}

void display()
{
    glClear( GL_COLOR_BUFFER_BIT );
    glMatrixMode( GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt( 0,0,5,0,0,0,0,1,0);
    
    glPushMatrix();
    {
        //    big arm
        glColor3f(1.0f,0,0);
        glTranslatef(-BIG_ARM_LENGTH/2,0,0);
        glRotatef(shoulder_angle,0,0,1);
        glTranslatef(BIG_ARM_LENGTH/2,0,0);
        glPushMatrix();
        glScalef(BIG_ARM_LENGTH,0.4,0.1);
        glutWireCube(1.0f);
        glPopMatrix();

        //    small arm
        glColor3f(1.0f,1.0f,0.0f);
        glTranslatef(BIG_ARM_LENGTH/2,0.0,0.0);
        glRotatef(elbow_angle,0,0,1);
        glTranslatef(SMALL_ARM_LENGTH/2,0.0,0.0);
        glPushMatrix();
        glScalef(SMALL_ARM_LENGTH,0.4,0.1);
        glutWireCube(1.0f);
        glPopMatrix();
        
        //    finger
        glColor3f(1.0f,0.0f,1.0f);
        glTranslatef(SMALL_ARM_LENGTH/2,0.0,0.0);
        glRotatef( finger_angle,0,0,1);
        glTranslatef( FINGER_LENGTH/2,0,0);
        glPushMatrix();
        glScalef(FINGER_LENGTH,0.4,0.1);
        glutWireCube(1.0f);
        glPopMatrix();
        

        //    the ball
        glColor3f(1.0f,0.0f,0.5f);
        glTranslatef( BALL_RADIUS * 2,0,0);
        glRotatef(ball_angle,1,0,0);
        glPushMatrix();
        glScalef(1.0f,1.0f,1.0f);
        glutWireSphere( BALL_RADIUS,10,10);
        glPopMatrix();
        
    }
    glPopMatrix();

    //    draw a triangle
    glPushMatrix();
    {
        glRotatef( triangle_angle,1,0,0);
        glBegin( GL_TRIANGLES );
        glColor3f(1,0,0);
        glVertex3f( 1,0,-1);
        glColor3f(1,1,0);
        glVertex3f( 0,1,-1);
        glColor3f(1,0,1);
        glVertex3f( -1,0,-1);
        glEnd();
    }
    glPopMatrix();


    glFlush();
}

void reshape(int w,int h)
{
    glViewport( 0,0,(GLsizei)w,(GLsizei)h);
    glMatrixMode( GL_PROJECTION);
    glLoadIdentity();
    gluPerspective( 90,(GLdouble)w/(GLdouble)h,0.1,1000);
}

void keyboard(unsigned char key,int x,int y)
{
    switch( key )
    {
    //    shoulder
    case 's':
        shoulder_angle += 5.0f;
        break;
    case 'S':
        shoulder_angle -= 5.0f;
        break;    
    //    elbow
    case 'e':
        elbow_angle += 5.0f;
        break;
    case 'E':
        elbow_angle -= 5.0f;
        break;
    //    finger
    case 'f':
        finger_angle += 5.0f;
        break;
    case 'F':
        finger_angle -= 5.0f;
        break;
    //    ball 
    case 'b':
        ball_angle += 5.0f;
        break;
    case 'B':
        ball_angle -= 5.0f;
        break;

    //    triangle
    case 't':
        triangle_angle += 5.0f;
        break;
    case 'T':
        triangle_angle -= 5.0f;
        break;
    default:
        break;
    }

    glutPostRedisplay();
}

int main( int argc,char** argv)
{
    glutInit( &argc,argv);
    glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
    glutInitWindowSize( 800,600 );
    glutInitWindowPosition( 100,100 );
    
    glutCreateWindow("Clip Plane");

    glutReshapeFunc( reshape);
    glutDisplayFunc( display);
    //glutMouseFunc( mousePress);
    //glutMotionFunc( mouseMove);
    glutKeyboardFunc( keyboard );
    
    glutMainLoop();

    return 0;
}

抱歉!评论已关闭.