计算机图形学 实验二 DAA与Bresham以及中点圆

实验二:直线与画圆算法

实验目的: 理解光栅化,掌握几何数据如何经过一系列变换后转化为像素从而呈现在显示 设备上。

基本要求:

 实现 DDA 和 Bresenham 画线算法

 实现画圆算法

 请勿直接调用 OpenGL 库中提供的绘制线段和圆的函数,需手动模拟如何通过绘 制像素来显示几何图形,效果可参考下图。(界面显示的是“虚拟的像素”)

 可通过交互操作来确定线段的起点和终点。

实现:

  1 #include<GL/glut.h>
  2 #define EXIT_SUCCESS 0
  3 #include<stdio.h>
  4 #include<math.h>
  5 // later Edition
  6 int MODE = 0;          // 模式代码:0-DAA算法,1-Bresenham算法,2-中点圆算法
  7 bool mouseLeftDown;     // 实时记录鼠标左键状态
  8 bool mouseRightDown;    // 实时记录鼠标左键状态
  9 float mouseX, mouseY;   // 实时记录鼠标位置,与下一次鼠标位置之间形成微分
 10 
 11 int startX=0, startY=0, endX=0, endY=0;
 12 int start[2] = { 0 };
 13 int end[2] = { 0 };
 14 float red=1.0,green=1.0, blue=0.0;
 15 float PI = 3.415926535;
 16 
 17 int arr[500][500];
 18 
 19 void init(void)
 20 {
 21     //glClearColor(0.0, 0.0, 0.0, 0.0);/* select clearing color  */   // 设置背景颜色为黑色
 22     //glMatrixMode(GL_MODELVIEW);                   
 23     glClearColor(0.0, 0.0, 0.0, 0.0); /* white background */
 24     glColor3f(1.0, 0.0, 0.0); /* draw in red */
 25 
 26     /* set up viewing: */
 27     /* 500 x 500 window with origin lower left */
 28 
 29     glMatrixMode(GL_PROJECTION);
 30     glLoadIdentity();
 31     gluOrtho2D(0.0, 500.0, 0.0, 500.0);
 32     glMatrixMode(GL_MODELVIEW);
 33 }
 34 
 35 
 36 
 37 
 38 #define RED 1233
 39 #define BLUE 1234
 40 #define GREEN 1235
 41 #define WHITE 12366
 42 #define YELLOW 12367
 43 #define DAA_LINE 12368
 44 #define BRES_LINE 12369
 45 #define CIRCLE 12370
 46 void processMenuEvents(int option) {
 47     //option,就是传递过来的value的值。
 48     switch (option) {
 49     case RED:
 50         red = 1.0;
 51         green = 0.0;
 52         blue = 0.0; break;
 53     case GREEN:
 54         red = 0.0;
 55         green = 1.0;
 56         blue = 0.0; break;
 57     case BLUE:
 58         red = 0.0;
 59         green = 0.0;
 60         blue = 1.0; break;
 61     case WHITE:
 62         red = 1.0;
 63         green = 1.0;
 64         blue = 1.0; break;
 65     case YELLOW:
 66         red = 1.0;
 67         green = 1.0;
 68         blue = 0.0;break;
 69     case DAA_LINE:
 70         MODE = 0;break;
 71     case BRES_LINE:
 72         MODE = 1;break;
 73     case CIRCLE:
 74         MODE = 2;break;
 75     }
 76 }
 77 void createGLUTMenus() {
 78 
 79     int menu;
 80 
 81     // 创建菜单并告诉GLUT,processMenuEvents处理菜单事件。
 82     menu = glutCreateMenu(processMenuEvents);
 83 
 84     //给菜单增加条目
 85     glutAddMenuEntry("红色", RED);
 86     glutAddMenuEntry("蓝色", BLUE);
 87     glutAddMenuEntry("绿色", GREEN);
 88     glutAddMenuEntry("白色", WHITE);
 89     glutAddMenuEntry("黄色", YELLOW);
 90     glutAddMenuEntry("DAA_LINE", DAA_LINE);
 91     glutAddMenuEntry("BRES_LINE", BRES_LINE);
 92     glutAddMenuEntry("CIRCLE_SCAN", CIRCLE);
 93 
 94     // 把菜单和鼠标右键关联起来。
 95     glutAttachMenu(GLUT_RIGHT_BUTTON);
 96 }
 97 
 98 void DAA_alogrithm(int x0, int y0, int x1, int y1) {
 99     int x;
100     float dx, dy, y, k;
101     dx = x1 - x0,dy = y1 - y0; 
102     k = dy / dx, y = y0;
103     glPointSize(5.0);
104 
105     glBegin(GL_POINTS);
106     
107     for (x = x0;x <= x1;x++) {
108         
109         glVertex2d(x, int(y + 0.5));
110         y = y + k;
111     }
112     glEnd();
113 }
114 void y_DAA_alogrithm(int x0, int y0, int x1, int y1) {
115     int y;
116     float dx, dy, x, k;
117     dx = x1 - x0, dy = y1 - y0;
118     k = dx / dy, x = x0;
119     glPointSize(5.0);
120 
121     glBegin(GL_POINTS);
122 
123     for (y = y0;y <= y1;y++) {
124 
125         glVertex2d(int(x + 0.5),y );
126         x = x + k;
127     }
128     glEnd();
129 }
130 void Bresenham(int x0, int y0, int x1, int y1) {
131     bool is_nagetive_k = false;
132     if ((y1 - y0) * (x1 - x0) < 0) {
133         y1 *= -1, y0 *= -1;
134         is_nagetive_k = true;
135     }
136     int x, y, dx, dy, e;
137     dx = x1 - x0, dy = y1 - y0,e=-dx;
138     x = x0;y = y0;
139     glPointSize(5.0);
140 
141     glBegin(GL_POINTS);
142     for (int i = 0;i < dx;i++) {
143         if (!is_nagetive_k)glVertex2d(x, y);else {
144             glVertex2d(x, -y);
145         }
146         x++, e = e + 2 * dy; 
147         if (e >= 0)y++, e = e - 2 * dx;
148     }
149     glEnd();
150 }
151 void y_Bresenham(int x0, int y0, int x1, int y1) {
152     bool is_nagetive_k = false;
153     if ((y1 - y0) * (x1 - x0) < 0) {
154         y1 *= -1;y0 *= -1;
155         is_nagetive_k = true;
156     }
157 
158     int x, y, dx, dy, e;
159     dx = x1 - x0, dy = y1 - y0, e = -dy;
160     x = x0;y = y0;
161     glPointSize(5.0);
162 
163     glBegin(GL_POINTS);
164     for (int i = 0;i < dy;i++) {
165         if (!is_nagetive_k)glVertex2d(x, y);else {
166             glVertex2d(x, -y);
167         }
168         y++, e = e + 2 * dx;
169         if (e >= 0)x++, e = e - 2 * dy;
170     }
171     glEnd();
172 }
173 void circlePoints(int x,int y) {
174     glPointSize(5.0);
175     glBegin(GL_POINTS);
176     glVertex2d(x,y);glVertex2d(y,x);
177     glVertex2d(-x,y);glVertex2d(-y,x);
178     glVertex2d(x,-y);glVertex2d(y,-x);
179     glVertex2d(-x,-y);glVertex2d(-y,-x);
180     glEnd();
181 }
182 void mindCircle(int r) {
183     int x, y;
184     float d;
185     x = 0;y = r; d = 1.25 - r;
186     circlePoints(x, y);
187     while (x <= y) {
188         if (d < 0) {
189             d += 2 * x + 3;
190         }
191         else {
192             d += 2 * (x - y) + 5;y--;
193         }
194         x++;
195         circlePoints(x, y);
196     }
197 }
198 void display(void)
199 {
200     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
201     glColor3f(red, green, blue);
202     glLoadIdentity();
203 
204 
205    
206 
207     if (MODE == 0) {
208         if (abs(startY - endY) > abs(startX - endX)) {
209             if (startY > endY) {
210                 y_DAA_alogrithm(endX, endY,startX, startY);
211             }
212             else {
213                 y_DAA_alogrithm(startX, startY, endX, endY);
214             }
215         }
216         else {
217             if (startX > endX) {
218                 DAA_alogrithm(endX, endY, startX, startY);
219             }
220             else {
221                 DAA_alogrithm(startX, startY, endX, endY);
222             }
223         }
224     }
225     else if (MODE == 1) {
226 
227         if (startX > endX) {
228             if (abs(startY - endY) > abs(startX - endX))y_Bresenham(endX, endY, startX, startY);
229             else Bresenham(endX, endY, startX, startY);
230         }
231         else {
232             if(abs(startY - endY) > abs(startX - endX))y_Bresenham(startX, startY, endX, endY);
233             else Bresenham(startX, startY, endX, endY);
234         }
235     
236     }
237     else if(MODE==2){
238         glPushMatrix();
239         glTranslated(startX, startY, 0);
240         mindCircle(int(pow((startX - endX) * (startX - endX) + (startY - endY) * (startY - endY), 0.5)));
241         glTranslated(-endX, -endY, 0);
242         glPopMatrix();
243     }
244     
245     
246     
247     
248     /*
249     glBegin(GL_LINES);
250 
251     glVertex2d(startX, startY);glVertex2d(endX, endY);
252 
253     glEnd();
254 
255     */
256     /*
257     glPointSize(10.0);
258     for (int i = 0;i < 500;i++) {
259         glVertex2d(100, i);
260         glVertex2d(i, 100);
261         glVertex2d(i, i);
262 
263     }
264     glEnd();
265     */
266     
267     glutSwapBuffers();
268 }
269 int saveStack = 0;
270 int firstSaveFlag = -1;
271 void keyboard(unsigned char key, int x, int y)
272 
273 {
274     switch (key) {
275         case 'q':case 'Q':
276             exit(EXIT_SUCCESS);
277             break;
278     }    
279 }
280 int ww, hh;
281 
282 void mouse_process(int button, int state, int x, int y)
283 {
284     mouseX = x;
285     mouseY = y;
286     printf("(%d,%d)
", x, y);
287     printf("(%d,%d)", startX,startY);
288     printf("(%d,%d)
", endX,endY);
289     hh = glutGet(GLUT_WINDOW_HEIGHT);
290     if (button == GLUT_LEFT_BUTTON)
291     {
292         if (state == GLUT_DOWN)
293         {
294             if (!mouseLeftDown) {
295                 startX = x;startY = hh-y;
296             } 
297             
298             mouseLeftDown = true;
299         }
300         else if (state == GLUT_UP) {
301             mouseLeftDown = false;
302    
303         }
304             
305     }
306 
307     else if (button == GLUT_RIGHT_BUTTON)
308     {
309         if (state == GLUT_DOWN)
310         {
311             mouseRightDown = true;
312         }
313         else if (state == GLUT_UP)
314             mouseRightDown = false;
315     }
316 
317 
318     
319 }
320 
321 void mouse_process_active(int x, int y)
322 {
323     if (mouseLeftDown){
324         endX = x;endY = hh - y;
325         glutPostRedisplay();
326     }
327     if(mouseRightDown)
328     {   
329 
330     }
331     glutPostRedisplay();
332 
333 }
334 void mouse_process_passtive(int x, int y) {}
335 
336 
337 int main(int argc, char** argv)
338 {
339     glutInit(&argc, argv);
340     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
341     glutInitWindowSize(500, 500);
342     glutCreateWindow("19智能 右键开启菜单");
343 
344     init();
345 
346     glutDisplayFunc(display);
347   
348     // later Edition
349     glutMouseFunc(mouse_process);
350     glutMotionFunc(mouse_process_active);
351     glutPassiveMotionFunc(mouse_process_passtive);
352     createGLUTMenus();
353     glutKeyboardFunc(keyboard);
354     glutMainLoop();
355 
356     return 0;
357 }
原文地址:https://www.cnblogs.com/PRCdefender/p/14606266.html