红宝书上根据机器人手臂的例子做了简单的修改.
本来以为这次重新看了矩阵变换,对矩阵变换已经有了比较深刻的认识,直到合上书,在没有参考书上代码的情况下,
尝试自己实现这个简单的机器人手臂的变换,才知道还是有许多不足.
总结几个在理解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;
}
关于红宝书上机器人手臂的例子和矩阵变换
最新推荐文章于 2020-06-21 17:29:28 发布