计算机图形学实验(一) Bresenham画直线和中点画圆法画圆

末蓝、 2022-02-09 20:39 495阅读 0赞

图形学的第一个实验,

因为老师课上的讲解原因,所以这里将一个边长为1的正方形块作为一个像素,放大后可以看出来。

先上代码,画线的:

  1. void drawLine(node * mnode)
  2. {
  3. glClearColor(0.0f, 0.0f, 0.0f,0.0f);//绘图颜色为黑色
  4. glClear(GL_COLOR_BUFFER_BIT);
  5. glColor3f(1.0, 1.0, 1.0);
  6. glBegin(GL_LINES);
  7. //glViewport(0, 0, 400, 400);
  8. for (int i = 0; i < 400; i++)
  9. {
  10. glVertex2i(i, 0);
  11. glVertex2i(i, 400);
  12. }
  13. for (int i = 0; i < 400; i++)
  14. {
  15. glVertex2i(0, i);
  16. glVertex2i(400,i);
  17. }
  18. glEnd();
  19. //glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲池
  20. glColor3f(1.0, 0.0, 0.0);
  21. //glBegin(GL_POINTS);
  22. //glViewport(0, 0, 400, 400);
  23. int x, y, dx, dy, e;
  24. int x1 = mnode[0].x, y1 = mnode[0].y, x2 = mnode[1].x, y2 =mnode[1].y;
  25. dx = x2 - x1;
  26. dy = y2 - y1;
  27. e = -dx;
  28. x = x1;
  29. y = y1;
  30. for (int i = 0; i <= dx; i++)
  31. {
  32. //glVertex2i(x, y);
  33. glRectf(x,y, x+1, y+1); //绘制矩形
  34. x++;
  35. e = e + 2 * dy;
  36. if (e >= 0)
  37. {
  38. y++;
  39. e = e - 2 * dx;
  40. }
  41. }
  42. //glEnd();
  43. glFlush();
  44. }

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjQ3NTQ0_size_16_color_FFFFFF_t_70

放大后的图像

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjQ3NTQ0_size_16_color_FFFFFF_t_70 1

然后是画圆的代码:

  1. void drawCircle()
  2. {
  3. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色
  4. glClear(GL_COLOR_BUFFER_BIT);
  5. glColor3f(1.0, 1.0, 1.0);
  6. //glBegin(GL_POINTS);
  7. glBegin(GL_LINES);
  8. glViewport(0, 0, 400, 400);
  9. for (int i = 0; i < 400; i++)
  10. {
  11. glVertex2i(i, 0);
  12. glVertex2i(i, 400);
  13. }
  14. for (int i = 0; i < 400; i++)
  15. {
  16. glVertex2i(0, i);
  17. glVertex2i(400, i);
  18. }
  19. glEnd();
  20. //glViewport(0, 0, 400, 400);
  21. glColor3f(1.0, 0.0, 0.0);
  22. int x, y;
  23. float d;
  24. int r = 100;
  25. x = 0, y = r;
  26. d = 1.25 - r;
  27. //glVertex2i(x+r,y+r);
  28. //glVertex2i(y+r, x+r);
  29. //glVertex2i(-x+r, y+r);
  30. //glVertex2i(y+r, -x+r);
  31. //glVertex2i(x+r, -y+r);
  32. //glVertex2i(-y+r, x+r);
  33. //glVertex2i(-x+r, -y+r);
  34. //glVertex2i(-y+r, -x+r);
  35. glRectf(x+r, y+r, x +r+1, y+r+1); //绘制矩形
  36. glRectf(y+r, x+r, y+r+ 1, x+r+1); //绘制矩形
  37. glRectf(-x+r, y+r, -x+r+1, y +r+ 1); //绘制矩形
  38. glRectf(y+r, -x+r, y+r+ 1, -x+r+ 1); //绘制矩形
  39. glRectf(x+r, -y+r, x+r+ 1, -y+r+ 1); //绘制矩形
  40. glRectf(-y+r, x+r, -y+r + 1, x+r+ 1); //绘制矩形
  41. glRectf(-x+r, -y+r, -x+r + 1, -y+r + 1); //绘制矩形
  42. glRectf(-y+r, -x+r, -y+r + 1, -x+r + 1); //绘制矩形
  43. while (x <= y)
  44. {
  45. if (d <= 0)
  46. {
  47. d += 2 * x + 3;
  48. }
  49. else
  50. {
  51. d += 2 * (x - y) + 5;
  52. y--;
  53. }
  54. x++;
  55. //cout<< x <<" "<<y<< endl;
  56. /*glVertex2i(x + r, y + r);
  57. glVertex2i(y + r, x + r);
  58. glVertex2i(-x + r, y + r);
  59. glVertex2i(y + r, -x + r);
  60. glVertex2i(x + r, -y + r);
  61. glVertex2i(-y + r, x + r);
  62. glVertex2i(-x + r, -y + r);
  63. glVertex2i(-y + r, -x + r);*/
  64. glRectf(x + r, y + r, x + r + 1, y + r + 1); //绘制矩形
  65. glRectf(y + r, x + r, y + r + 1, x + r + 1); //绘制矩形
  66. glRectf(-x + r, y + r, -x + r + 1, y + r + 1); //绘制矩形
  67. glRectf(y + r, -x + r, y + r + 1, -x + r + 1); //绘制矩形
  68. glRectf(x + r, -y + r, x + r + 1, -y + r + 1); //绘制矩形
  69. glRectf(-y + r, x + r, -y + r + 1, x + r + 1); //绘制矩形
  70. glRectf(-x + r, -y + r, -x + r + 1, -y + r + 1); //绘制矩形
  71. glRectf(-y + r, -x + r, -y + r + 1, -x + r + 1); //绘制矩形
  72. }
  73. //glEnd();
  74. glFlush();
  75. }

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjQ3NTQ0_size_16_color_FFFFFF_t_70 2

放大后的代码:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjQ3NTQ0_size_16_color_FFFFFF_t_70 3

实现原理:

过各行各列像素中心构造一组网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。该算法的巧妙之处在于采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列的所求的像素。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjQ3NTQ0_size_16_color_FFFFFF_t_70 4

简单来说就是如果在中点及以下则取y,中点以上则取y+1。

中点画圆法:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjQ3NTQ0_size_16_color_FFFFFF_t_70 5

完整的代码:

  1. // ConsoleApplication2.cpp: 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include<gl/GLUT.H>
  5. #include<cmath>
  6. #include<iostream>
  7. #include "node.h"
  8. using namespace std;
  9. node Line[2] = { node(0.0,0.0),node(0.0,0.0) };
  10. int nodeNumber = 0;
  11. bool finish = false;//已经画完
  12. void Initial(void)//初始化函数
  13. {
  14. glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//白色背景,前3个是RGB,最后是Alpha值,用来控制透明,1.0表示完全不透明
  15. glMatrixMode(GL_MODELVIEW);//OpenGL按照三维方式来处理图像,所以需要一个投影变换将三维图形投影到显示器的二维空间中
  16. glLoadIdentity();
  17. gluOrtho2D(0.0, 400, 0.0, 400.0);//指定使用正投影将一个x坐标在0~200,y坐标0~150范围内的矩形坐标区域投影到显示器窗口
  18. }
  19. void drawLine(node * mnode)
  20. {
  21. glClearColor(0.0f, 0.0f, 0.0f,0.0f);//绘图颜色为黑色
  22. glClear(GL_COLOR_BUFFER_BIT);
  23. glColor3f(1.0, 1.0, 1.0);
  24. glBegin(GL_LINES);
  25. //glViewport(0, 0, 400, 400);
  26. for (int i = 0; i < 400; i++)
  27. {
  28. glVertex2i(i, 0);
  29. glVertex2i(i, 400);
  30. }
  31. for (int i = 0; i < 400; i++)
  32. {
  33. glVertex2i(0, i);
  34. glVertex2i(400,i);
  35. }
  36. glEnd();
  37. //glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲池
  38. glColor3f(1.0, 0.0, 0.0);
  39. //glBegin(GL_POINTS);
  40. //glViewport(0, 0, 400, 400);
  41. int x, y, dx, dy, e;
  42. int x1 = mnode[0].x, y1 = mnode[0].y, x2 = mnode[1].x, y2 =mnode[1].y;
  43. dx = x2 - x1;
  44. dy = y2 - y1;
  45. e = -dx;
  46. x = x1;
  47. y = y1;
  48. for (int i = 0; i <= dx; i++)
  49. {
  50. //glVertex2i(x, y);
  51. glRectf(x,y, x+1, y+1); //绘制矩形
  52. x++;
  53. e = e + 2 * dy;
  54. if (e >= 0)
  55. {
  56. y++;
  57. e = e - 2 * dx;
  58. }
  59. }
  60. //glEnd();
  61. glFlush();
  62. }
  63. void drawLine1()
  64. {
  65. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色
  66. glClear(GL_COLOR_BUFFER_BIT);
  67. glColor3f(1.0, 1.0, 1.0);
  68. glBegin(GL_LINES);
  69. //glViewport(0, 0, 400, 400);
  70. for (int i = 0; i < 400; i++)
  71. {
  72. glVertex2i(i, 0);
  73. glVertex2i(i, 400);
  74. }
  75. for (int i = 0; i < 400; i++)
  76. {
  77. glVertex2i(0, i);
  78. glVertex2i(400, i);
  79. }
  80. glEnd();
  81. //glClear(GL_COLOR_BUFFER_BIT); //清空颜色缓冲池
  82. glColor3f(1.0, 0.0, 0.0);
  83. //glBegin(GL_POINTS);
  84. //glViewport(0, 0, 400, 400);
  85. int x, y, dx, dy, e;
  86. int x1 = 0, y1 = 8, x2 = 50, y2 = 100;
  87. dx = x2 - x1;
  88. dy = y2 - y1;
  89. e = -dx;
  90. x = x1;
  91. y = y1;
  92. for (int i = 0; i <= dx; i++)
  93. {
  94. //glVertex2i(x, y);
  95. glRectf(x, y, x + 1, y + 1); //绘制矩形
  96. x++;
  97. e = e + 2 * dy;
  98. if (e >= 0)
  99. {
  100. y++;
  101. e = e - 2 * dx;
  102. }
  103. }
  104. //glEnd();
  105. glFlush();
  106. }
  107. void drawLine()
  108. {
  109. if (finish)
  110. {
  111. drawLine(&Line[0]);
  112. finish = false;
  113. }
  114. }
  115. void drawCircle()
  116. {
  117. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//绘图颜色为黑色
  118. glClear(GL_COLOR_BUFFER_BIT);
  119. glColor3f(1.0, 1.0, 1.0);
  120. //glBegin(GL_POINTS);
  121. glBegin(GL_LINES);
  122. glViewport(0, 0, 400, 400);
  123. for (int i = 0; i < 400; i++)
  124. {
  125. glVertex2i(i, 0);
  126. glVertex2i(i, 400);
  127. }
  128. for (int i = 0; i < 400; i++)
  129. {
  130. glVertex2i(0, i);
  131. glVertex2i(400, i);
  132. }
  133. glEnd();
  134. //glViewport(0, 0, 400, 400);
  135. glColor3f(1.0, 0.0, 0.0);
  136. int x, y;
  137. float d;
  138. int r = 100;
  139. x = 0, y = r;
  140. d = 1.25 - r;
  141. //glVertex2i(x+r,y+r);
  142. //glVertex2i(y+r, x+r);
  143. //glVertex2i(-x+r, y+r);
  144. //glVertex2i(y+r, -x+r);
  145. //glVertex2i(x+r, -y+r);
  146. //glVertex2i(-y+r, x+r);
  147. //glVertex2i(-x+r, -y+r);
  148. //glVertex2i(-y+r, -x+r);
  149. glRectf(x+r, y+r, x +r+1, y+r+1); //绘制矩形
  150. glRectf(y+r, x+r, y+r+ 1, x+r+1); //绘制矩形
  151. glRectf(-x+r, y+r, -x+r+1, y +r+ 1); //绘制矩形
  152. glRectf(y+r, -x+r, y+r+ 1, -x+r+ 1); //绘制矩形
  153. glRectf(x+r, -y+r, x+r+ 1, -y+r+ 1); //绘制矩形
  154. glRectf(-y+r, x+r, -y+r + 1, x+r+ 1); //绘制矩形
  155. glRectf(-x+r, -y+r, -x+r + 1, -y+r + 1); //绘制矩形
  156. glRectf(-y+r, -x+r, -y+r + 1, -x+r + 1); //绘制矩形
  157. while (x <= y)
  158. {
  159. if (d <= 0)
  160. {
  161. d += 2 * x + 3;
  162. }
  163. else
  164. {
  165. d += 2 * (x - y) + 5;
  166. y--;
  167. }
  168. x++;
  169. //cout<< x <<" "<<y<< endl;
  170. /*glVertex2i(x + r, y + r);
  171. glVertex2i(y + r, x + r);
  172. glVertex2i(-x + r, y + r);
  173. glVertex2i(y + r, -x + r);
  174. glVertex2i(x + r, -y + r);
  175. glVertex2i(-y + r, x + r);
  176. glVertex2i(-x + r, -y + r);
  177. glVertex2i(-y + r, -x + r);*/
  178. glRectf(x + r, y + r, x + r + 1, y + r + 1); //绘制矩形
  179. glRectf(y + r, x + r, y + r + 1, x + r + 1); //绘制矩形
  180. glRectf(-x + r, y + r, -x + r + 1, y + r + 1); //绘制矩形
  181. glRectf(y + r, -x + r, y + r + 1, -x + r + 1); //绘制矩形
  182. glRectf(x + r, -y + r, x + r + 1, -y + r + 1); //绘制矩形
  183. glRectf(-y + r, x + r, -y + r + 1, x + r + 1); //绘制矩形
  184. glRectf(-x + r, -y + r, -x + r + 1, -y + r + 1); //绘制矩形
  185. glRectf(-y + r, -x + r, -y + r + 1, -x + r + 1); //绘制矩形
  186. }
  187. //glEnd();
  188. glFlush();
  189. }
  190. void mouseClick(int btn, int state, int x, int y)
  191. {
  192. if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)//点击左键
  193. {
  194. y = 400 - y;
  195. node temp(x, y);
  196. if (nodeNumber<2)
  197. {
  198. Line[nodeNumber] = temp;
  199. nodeNumber++;
  200. glColor3f(1.0, 0.0, 0.0);
  201. // glViewport(0, 0, 400, 400);
  202. glBegin(GL_POINTS);
  203. glVertex2d(x, y);
  204. glEnd();
  205. glFlush();
  206. }
  207. }
  208. if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)//点击右键
  209. {
  210. //drawLine(&Line[0]);
  211. finish = true;
  212. nodeNumber = 0;
  213. }
  214. }
  215. int main(int argc, char * argv[])//这是使用glut库函数进行窗口管理
  216. {
  217. glutInit(&argc, argv);//使用glut库需要进行初始化
  218. glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);//设定窗口显示模式,颜色模型和缓存,这里是RGB颜色模型和单缓存
  219. glutInitWindowPosition(100, 100);//设定窗口的初始位置,屏幕左上角为原点,单位为像素
  220. glutInitWindowSize(400, 400);//设定窗口的大小
  221. glutCreateWindow("直线");//创建一个窗口,参数是窗口标题名
  222. Initial();
  223. glutDisplayFunc(&drawLine1);//将myDisplay指定为当前窗口的显示内容函数*/
  224. //glutMouseFunc(mouseClick);
  225. glutCreateWindow("圆");//创建一个窗口,参数是窗口标题名
  226. Initial();
  227. glutDisplayFunc(&drawCircle);//将myDisplay指定为当前窗口的显示内容函数
  228. glutMainLoop();//使窗口框架运行起来,使显示回调函数开始工作
  229. return 0;
  230. }

还有一个头文件:

  1. #pragma once
  2. #pragma once
  3. struct node//点结构
  4. {
  5. double x;
  6. double y;
  7. node()
  8. {
  9. x = 0.0;
  10. y = 0.0;
  11. }
  12. ~node() {}
  13. node(double xx, double yy)
  14. {
  15. x = xx;
  16. y = yy;
  17. }
  18. /*node & operator=(const node& a)
  19. {
  20. node m;
  21. m.x = a.x;
  22. m.y = a.y;
  23. return m;
  24. }*/
  25. };
  26. struct side//边结构
  27. {
  28. node a;
  29. node b;
  30. side(node aa, node bb)
  31. {
  32. a.x = aa.x;
  33. a.y = aa.y;
  34. b.y = bb.y;
  35. b.x = bb.x;
  36. }
  37. side(int n)
  38. {
  39. a.x = 0;
  40. a.y = 0;
  41. b.x = 0;
  42. b.y = 0;
  43. }
  44. side()
  45. {
  46. a.x = 0;
  47. a.y = 0;
  48. b.x = 0;
  49. b.y = 0;
  50. }
  51. };

发表评论

表情:
评论列表 (有 0 条评论,495人围观)

还没有评论,来说两句吧...

相关阅读