当前位置:   article > 正文

计算机图形学——实验二 几何图形变换实验_opengl二维几何变换实验

opengl二维几何变换实验

实验二 几何图形变换实验

 

一、实验目的和要求

  1. 进一步掌握二维、三维变换的数学知识、变换原理、变换种类、变换方法;
  2. 利用OpenGL实现二维、三维图形变换,在屏幕上显示变换过程或变换结果;
  3. 掌握OpenGL常用的变换函数,利用OpenGL绘制简单的三维物体。

二、实验内容

1、下面的代码采用GLUT库,使用了双缓存,在按下鼠标左键后,程序在空闲时一直不停地调用spinDisplay函数,实现了一个矩形在窗口中匀速转动(单击鼠标右键停止转动)。请修改代码,实现矩形在窗口内沿着水平线从左侧移动到右侧。通过实验说明glPushMatrix()glPopMatrix()的作用。

/*

 *  double.c

 *  This is a simple double buffered program.

 *  Pressing the left mouse button rotates the rectangle.

 *  Pressing the right mouse button stops the rotation.

 */

#include <GL/glut.h>

#include <stdlib.h>

static GLfloat spin = 0.0;

void display(void)

{

   glClear(GL_COLOR_BUFFER_BIT);

   glPushMatrix();

   glRotatef(spin, 0.0, 0.0, 1.0);

   glColor3f(1.0, 1.0, 1.0);

   glRectf(-10.0, -10.0, 10.0, 10.0);

   glPopMatrix();

   glutSwapBuffers();  //交换双缓存

}

void spinDisplay(void)

{

   spin = spin + 2.0;

   if (spin > 360.0)

      spin = spin - 360.0;

   glutPostRedisplay();  //屏幕重绘

}

void init(void)

{

   glClearColor (0.0, 0.0, 0.0, 0.0);

   glShadeModel (GL_FLAT);

}

void reshape(int w, int h)

{

   glViewport (0, 0, (GLsizei) w, (GLsizei) h);

   glMatrixMode(GL_PROJECTION);

   glLoadIdentity();

   glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0); //平行投影

   glMatrixMode(GL_MODELVIEW);

   glLoadIdentity();

}

void mouse(int button, int state, int x, int y)

{

   switch (button) {

      case GLUT_LEFT_BUTTON:

         if (state == GLUT_DOWN)

            glutIdleFunc(spinDisplay);  //设备空闲时调用的函数

         break;

      case GLUT_MIDDLE_BUTTON:

      case GLUT_RIGHT_BUTTON:

         if (state == GLUT_DOWN)

            glutIdleFunc(NULL);

         break;

      default:

         break;

   }

}

  

/*

 *  Request double buffer display mode.

 *  Register mouse input callback functions

 */

void main(int argc, char** argv)

{

   glutInit(&argc, argv);

   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);  //使用双缓存模式

   glutInitWindowSize (500, 500);

   glutInitWindowPosition (100, 100);

   glutCreateWindow (argv[0]);

   init ();

   glutDisplayFunc(display); //注册重绘函数

   glutReshapeFunc(reshape); //注册改变窗口形状函数

   glutMouseFunc(mouse);  //注册鼠标动作函数

   glutMainLoop();

}

2. 已知某三角形的三顶点坐标{50.0,50.0},{150.0,50.0},{100.0,150.0}

要求:(1)创建一个长宽分别为600600的窗口,窗口的左上角位于屏幕坐标(100100)处。

2)绘制一个由上述顶点所描绘的三角形,使得三角形位于窗口的中心;对三角形进行下列的几何变换:首先使三角形沿着其中心的x轴,y轴方向缩小到原来的25%;然后绕中心旋转-90度;最后沿着x轴平移70个单位,绘制出变换后的结果。

3. 绘制一个椅子的透视投影图,并使椅子旋转起来,通过鼠标或键盘控制旋转的方向。

参考函数:glutSolidCube(size)绘制实心立方体/glutWireCube(size)绘制线框立方体

这两个函数分别用于绘制中心位于世界坐标系原点的实心立方体和线框立方体,立方体的半径为size,size是一个双精度浮点值。

参考代码: wireobject

三、实验设计思路

1. 创建一个OpenGL工程,修改上述初始化代码display函数,将旋转glRotatef()函数修改成平移变换函数glTranslatef(),再修改一下初始位置。

2. 将上述代码进行鼠标交互等函数的清除,删减后类似与实验一中的代码。修改main函数中的窗口大小和窗口位置。主要修改display函数,glBegin(GL_TRIANGLES);开始画三角形,输入三个点glEnd绘制完成,用平移函数glTranslated、旋转函数glRotated、比例变换函数glScaled,进行从后往前的变换。最后重新绘制原来的三角形。

3. 先绘制一个桌子腿,再将椅子的整体绘制出来,利用的是glutWireCube(size)绘制线框立方体函数,最后通过平移、旋转、缩放函数将椅子在固定位置旋转起来。其中鼠标右键是停止旋转,鼠标左键是继续旋转,鼠标滚轮按钮是控制椅子的旋转方向。

四、实验代码

1. 

  1. /*
  2. * double.c
  3. * This is a simple double buffered program.
  4. * Pressing the left mouse button rotates the rectangle.
  5. * Pressing the right mouse button stops the rotation.
  6. */
  7. #include <GL/glut.h>
  8. #include <stdlib.h>
  9. static GLfloat spin = 0.0;
  10. void display(void)
  11. {
  12. glClear(GL_COLOR_BUFFER_BIT);
  13. glPushMatrix();
  14. //glRotatef(spin, 0.0, 0.0, 1.0);
  15. glTranslatef(spin, 0.0, 0.0);
  16. glColor3f(1.0, 1.0, 1.0);
  17. glRectf(-50.0, -10.0, -30.0, 10.0);
  18. glPopMatrix();
  19. glutSwapBuffers(); //交换双缓存
  20. }
  21. void spinDisplay(void)
  22. {
  23. spin = spin + 0.03;
  24. if (spin > 360.0)
  25. spin = spin - 360.0;
  26. glutPostRedisplay(); //屏幕重绘
  27. }
  28. void init(void)
  29. {
  30. glClearColor(0.0, 0.0, 0.0, 0.0);
  31. glShadeModel(GL_FLAT);
  32. }
  33. void reshape(int w, int h)
  34. {
  35. glViewport(0, 0, (GLsizei)w, (GLsizei)h);
  36. glMatrixMode(GL_PROJECTION);
  37. glLoadIdentity();
  38. glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0); //平行投影
  39. glMatrixMode(GL_MODELVIEW);
  40. glLoadIdentity();
  41. }
  42. void mouse(int button, int state, int x, int y)
  43. {
  44. switch (button) {
  45. case GLUT_LEFT_BUTTON:
  46. if (state == GLUT_DOWN)
  47. glutIdleFunc(spinDisplay); //设备空闲时调用的函数
  48. break;
  49. case GLUT_MIDDLE_BUTTON:
  50. case GLUT_RIGHT_BUTTON:
  51. if (state == GLUT_DOWN)
  52. glutIdleFunc(NULL);
  53. break;
  54. default:
  55. break;
  56. }
  57. }
  58. /*
  59. * Request double buffer display mode.
  60. * Register mouse input callback functions
  61. */
  62. void main(int argc, char** argv)
  63. {
  64. glutInit(&argc, argv);
  65. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); //使用双缓存模式
  66. glutInitWindowSize(500, 500);
  67. glutInitWindowPosition(100, 100);
  68. glutCreateWindow(argv[0]);
  69. init();
  70. glutDisplayFunc(display); //注册重绘函数
  71. glutReshapeFunc(reshape); //注册改变窗口形状函数
  72. glutMouseFunc(mouse); //注册鼠标动作函数
  73. glutMainLoop();
  74. }

 2.

  1. /*
  2. * double.c
  3. * This is a simple double buffered program.
  4. * Pressing the left mouse button rotates the rectangle.
  5. * Pressing the right mouse button stops the rotation.
  6. */
  7. #include <GL/glut.h>
  8. #include <stdlib.h>
  9. void display(void)
  10. {
  11. glClear(GL_COLOR_BUFFER_BIT);
  12. glPushMatrix(); //操作矩阵堆栈,调用函数,相当于把矩阵放到堆栈上
  13. glBegin(GL_TRIANGLES);
  14. glVertex2f(50, 50);
  15. glVertex2f(150, 50);
  16. glVertex2f(100, 150);
  17. glEnd();
  18. glFlush();
  19. glColor3f(1.0f, 1.0f, 1.0f);
  20. glTranslated(100, 100, 0);
  21. glTranslated(70, 0, 0);
  22. glRotated(-90, 0, 0, 1);
  23. glScaled(0.25, 0.25, 0.0);
  24. glTranslated(-100, -100, 0);
  25. glBegin(GL_TRIANGLES);
  26. glVertex2f(50, 50);
  27. glVertex2f(150, 50);
  28. glVertex2f(100, 150);
  29. glEnd();
  30. glFlush();
  31. glPopMatrix();
  32. }
  33. void init(void)
  34. {
  35. glMatrixMode(GL_PROJECTION); //设置投影参数
  36. glLoadIdentity();
  37. gluOrtho2D(0.0, 200.0, 0.0, 200.0);
  38. }
  39. /*
  40. * Request double buffer display mode.
  41. * Register mouse input callback functions
  42. */
  43. void main(int argc, char** argv)
  44. {
  45. glutInit(&argc, argv);
  46. glutInitDisplayMode(GLUT_RGB | GLUT_RGB); //使用双缓存模式
  47. glutInitWindowSize(600, 600);
  48. glutInitWindowPosition(100, 100);
  49. glutCreateWindow(argv[0]);
  50. init();
  51. glutDisplayFunc(display); //注册重绘函数
  52. //glutReshapeFunc(reshape); //注册改变窗口形状函数
  53. //glutMouseFunc(mouse); //注册鼠标动作函数
  54. glutMainLoop();
  55. }

 3.

  1. #include <GL/glut.h>
  2. float size = 0.25; //缩放
  3. float fTranslate;
  4. float fRotate;
  5. float fScale = 1.0f; // set inital scale value to 1.0f
  6. float K = 1.0f;
  7. float x = 1, y = 0, z = 0;
  8. void Draw_Leg() // This function draws one of the table leg
  9. {
  10. //绘制一个桌子腿
  11. glPushMatrix();
  12. glScalef(1.0f, 1.0f, 3.0f);
  13. glutWireCube(1.0 * size);
  14. glPopMatrix();
  15. }
  16. void Draw_Table() // This function draws a Table
  17. {
  18. glPushMatrix(); //将当前矩阵保存入堆栈顶(保存当前矩阵)。
  19. glScalef(5.0f, 4.0f, 1.0f); //缩放函数
  20. glColor3f(1.0, 0.0, 1.0);
  21. glutSolidCube(1 * size); //绘制线立方体
  22. glPopMatrix(); //pop出来
  23. glPushMatrix(); //将当前矩阵保存入堆栈顶(保存当前矩阵)。
  24. glScalef(4.0f, 1.0f, 4.0f); //缩放函数
  25. glTranslatef(0.0 * size, 1.5 * size, 0.5 * size);
  26. glColor3f(0.0, 0.0, 1.0);
  27. glutSolidCube(1 * size); //绘制线立方体
  28. glPopMatrix(); //pop出来
  29. glPushMatrix(); //左下角的柱子
  30. glTranslatef(-1.5 * size, -1 * size, -1.5 * size); //尺寸是相对于中心的坐标原点,按照实验指导上的大小进行的
  31. Draw_Leg();
  32. glPopMatrix();
  33. glPushMatrix(); //右下角的柱子
  34. glTranslatef(1.5 * size, -1 * size, -1.5 * size);
  35. Draw_Leg();
  36. glPopMatrix();
  37. glPushMatrix(); //右上角的柱子
  38. glTranslatef(1.5 * size, 1 * size, -1.5 * size);
  39. Draw_Leg();
  40. glPopMatrix();
  41. glPushMatrix(); //左上角的柱子
  42. glTranslatef(-1.5 * size, 1 * size, -1.5 * size);
  43. Draw_Leg();
  44. glPopMatrix();
  45. }
  46. void reshape(int width, int height)
  47. {
  48. if (height == 0) // Prevent A Divide By Zero By
  49. {
  50. height = 1; // Making Height Equal One
  51. }
  52. glViewport(0, 0, width, height); // Reset The Current Viewport
  53. glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
  54. glLoadIdentity(); // Reset The Projection Matrix
  55. // Calculate The Aspect Ratio Of The Window
  56. gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
  57. glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
  58. glLoadIdentity(); // Reset The Modelview Matrix
  59. }
  60. void idle()
  61. {
  62. glutPostRedisplay();
  63. }
  64. void redraw()
  65. {
  66. // If want display in wireframe mode
  67. //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  68. glClear(GL_COLOR_BUFFER_BIT); //当前缓冲区清除值,这里是清除颜色缓冲
  69. glLoadIdentity(); // Reset The Current Modelview Matrix
  70. if (K == 1)
  71. {
  72. glPushMatrix();
  73. glTranslatef(-1.0f, 0.0f, -6.0f); // Place the triangle at Center
  74. glRotatef(fRotate * K, x, y, z); // Rotate around Y axis
  75. Draw_Table(); // Draw triangle
  76. glPopMatrix();
  77. glPushMatrix();
  78. glTranslatef(1.0f, 0.0f, -6.0f);
  79. glRotatef(fRotate * K, y, x, z);
  80. Draw_Table();
  81. glPopMatrix();
  82. fRotate += 0.05f;
  83. }
  84. else if (K == 0) {
  85. glPushMatrix();
  86. glTranslatef(-1.0f, 0.0f, -6.0f); // Place the triangle at Center
  87. glRotatef(fRotate, x, y, 0); // Rotate around Y axis
  88. Draw_Table(); // Draw triangle
  89. glPopMatrix();
  90. glPushMatrix();
  91. glTranslatef(1.0f, 0.0f, -6.0f);
  92. glRotatef(fRotate, y, x, z);
  93. Draw_Table();
  94. glPopMatrix();
  95. }
  96. glutSwapBuffers();
  97. }
  98. void myMouse(int button, int state, int x, int y) {
  99. if (state == GLUT_DOWN)
  100. {
  101. if (button == GLUT_LEFT_BUTTON)
  102. {
  103. K = 1;
  104. }
  105. else if (button == GLUT_RIGHT_BUTTON)
  106. {
  107. K = 0;
  108. }
  109. }
  110. }
  111. void processMenuEvents_two(int option) {
  112. switch (option)
  113. {
  114. case 1:x = 1; y = 0; z = 0; break;
  115. case 2:x = 0; y = 1; z = 0; break;
  116. case 3:x = 0; y = 0; z = 1; break;
  117. default:
  118. break;
  119. }
  120. }
  121. int main(int argc, char* argv[])
  122. {
  123. glutInit(&argc, argv);
  124. glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  125. glutInitWindowSize(640, 480);
  126. int windowHandle
  127. = glutCreateWindow("Simple GLUT App");
  128. glutDisplayFunc(redraw);
  129. glutReshapeFunc(reshape);
  130. glutIdleFunc(idle);
  131. glutMouseFunc(myMouse);
  132. //鼠标滚轮
  133. glutCreateMenu(processMenuEvents_two);
  134. glutAddMenuEntry("X", 1);
  135. glutAddMenuEntry("Y", 2);
  136. glutAddMenuEntry("Z", 3);
  137. glutAttachMenu(GLUT_MIDDLE_BUTTON);
  138. glutMainLoop();
  139. return 0;
  140. }

 

五、实验结果及心得体会

1.

2.

3.

此次实验,进一步掌握二维、三维变换的数学知识、变换原理、变换种类及变换方法;使用了OpenGL利用常用的变换函数实现了二维、三维图形变换;同时还绘制了一个简单的三维立体图形。通过本次实验,进一步学习了图形学中的几何图形知识以及变换过程,收获颇多,对今后本课程的学习有了较大的帮助。

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号