/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Novembre 2005 */ /* Illustration du trace */ /* de cercle et de disque */ /* par l'algorithme */ /* de Bresenham (Midpoint) */ #include #include #include #include #include #include #include "ModuleCouleurs.h" #include "ModuleMenus.h" #include "ModuleReshape.h" #include "ModuleFont.h" #ifndef M_PI #define M_PI 3.14159F #endif static int aff = 0; static int r = 10; static int yy = 0; static int cc = 0; static int c = 1; static int f1; static int fv; void circle(int *p1,float r) { glColor4fv(couleurBleu()); glBegin(GL_LINE_LOOP); for ( int i = 0; i < 360; i++ ) { float angle = i * M_PI / 180; float x = (float) (p1[0] + r*cos(angle)); float y = (float) (p1[1] + r*sin(angle)); glVertex2f(x,y); } glEnd(); } void pixel(int x,int y,float *c) { glColor4fv(c); glBegin(GL_QUADS); glVertex2f(x-0.5F,y-0.5F); glVertex2f(x-0.5F,y+0.5F); glVertex2f(x+0.5F,y+0.5F); glVertex2f(x+0.5F,y-0.5F); glEnd(); glColor4fv(couleurNoir()); glBegin(GL_LINE_LOOP); glVertex2f(x-0.5F,y-0.5F); glVertex2f(x-0.5F,y+0.5F); glVertex2f(x+0.5F,y+0.5F); glVertex2f(x+0.5F,y-0.5F); glEnd(); } void trame(int xi,int xf,int y,float *c) { for ( int i = xi; i <= xf; i++ ) pixel(i,y,c); } int comptePixelsTrame(int xi,int xf) { return(xf-xi+1); } void pixelsSymetriques8(int x,int y,float *c) { pixel( x, y,c); pixel(-x, y,c); pixel( x,-y,c); pixel(-x,-y,c); pixel( y, x,c); pixel(-y, x,c); pixel( y,-x,c); pixel(-y,-x,c); } void pixelsSymetriques4(int x,int y,float *c) { pixel( x, y,c); pixel( x,-y,c); pixel( y, x,c); pixel(-y, x,c); } void pixelsSymetriques4(int cd,float *c) { pixel( cd, cd,c); pixel( cd,-cd,c); pixel(-cd, cd,c); pixel(-cd,-cd,c); } void cercle(float *c,int r) { int x,y,d; x = 0; y = r; d = 1 - r; if ( r == 0 ) { pixel(0,0,c); return; } pixelsSymetriques4(0,y,c); if ( r == 1 ) { return; } while ( y > x ) { if ( d < 0 ) d += 2 * x + 3; else { d += 2 * (x - y) + 5; y--; } x++; if ( x < y ) pixelsSymetriques8(x,y,c); else if ( x == y ) pixelsSymetriques4(x,c); } } void cercleIncomplet(float *c,int r,int max) { int x,y,d; x = 0; y = r; d = 1 - r; if ( r == 0 ) { pixel(0,0,c); return; } pixelsSymetriques4(0,y,c); if ( r == 1 ) { return; } if ( r == 0 ) return; int cp = 0; while ( ( y > x ) && ( cp < max ) ) { cp++; if ( d < 0 ) d += 2 * x + 3; else { d += 2 * (x - y) + 5; y--; } x++; if ( x < y ) pixelsSymetriques8(x,y,c); else if ( x == y ) pixelsSymetriques4(x,c); } } void disque(float *c,int r) { int x,y,d; x = 0; y = r; d = 1 - r; if ( r == 0 ) { pixel(0,0,c); return; } if ( r == 1 ) { pixel(0,y,c); pixel(0,-y,c); return; } trame(-y,y,x,c); while ( y > x ) { if ( d < 0 ) d += 2 * x + 3; else { if ( y > x ) { trame(-x,x,y,c); trame(-x,x,-y,c); } d += 2 * (x - y) + 5; y--; } x++; if ( y >= x ) { trame(-y,y,x,c); trame(-y,y,-x,c); } } } void disqueIncomplet(float *c,int r,int max) { int x,y,d; x = 0; y = r; d = 1 - r; if ( r == 0 ) { pixel(0,0,c); return; } if ( r == 1 ) { pixel(0,y,c); pixel(0,-y,c); return; } trame(-y,y,x,c); int cp = 0; while ( ( y > x ) && ( cp < max ) ) { cp++; if ( d < 0 ) d += 2 * x + 3; else { if ( y > x ) { trame(-x,x,y,c); trame(-x,x,-y,c); } d += 2 * (x - y) + 5; y--; } x++; if ( y >= x ) { trame(-y,y,x,c); trame(-y,y,-x,c); } } } void display() { int p[] = { 0,0 }; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); switch (aff) { case 0 : if ( ( cc == 1 ) || ( cc == 2 ) ) disque(couleurVert(),r); if ( ( cc == 0 ) || ( cc == 2 ) ) cercle(couleurRouge(),r); if ( c ) circle(p,r); break; case 1 : if ( ( cc == 1 ) || ( cc == 2 ) ) disqueIncomplet(couleurVert(),r,yy); if ( ( cc == 0 ) || ( cc == 2 ) ) cercleIncomplet(couleurRouge(),r,yy); if ( c ) circle(p,r); break; } glPopMatrix(); glFlush(); glutSwapBuffers(); } void myinit() { glShadeModel(GL_SMOOTH); glClearColor(0.8F,0.8F,0.8F,1.0F); } void postRedisplay() { glutPostWindowRedisplay(f1); glutPostWindowRedisplay(fv); } void key(unsigned char key,int x,int y) { switch ( key ) { case 'r' : r--; if ( r < 0 ) r = 0; postRedisplay(); break; case 'R' : r++; if ( r > 28 ) r = 28; postRedisplay(); break; case 'c' : case 'C' : c = !c; postRedisplay(); break; case ' ' : cc = (cc+1)%3; postRedisplay(); break; case 43 : yy++; if ( yy == 60 ) yy = 0; postRedisplay(); break; case 45 : yy--; if ( yy == -1 ) yy = 0; postRedisplay(); break; case 0x0D : yy = 0; aff = !aff; postRedisplay(); break; case 0x1B : exit(0); break; } } int comptePixelsCercle(int r) { int x,y,d; x = 0; y = r; d = 1 - r; if ( r == 0 ) { return(1); } if ( r == 1 ) { return(4); } int cpt = 4; while ( y > x ) { if ( d < 0 ) d += 2 * x + 3; else { d += 2 * (x - y) + 5; y--; } x++; if ( x < y ) cpt += 8; else if ( x == y ) cpt += 4; } return(cpt); } int comptePixelsCercleIncomplet(int r,int max) { int x,y,d; x = 0; y = r; d = 1 - r; if ( r == 0 ) { return(1); } if ( r == 1 ) { return(4); } int cpt = 4; int cp = 0; while ( ( y > x ) && ( cp < max ) ) { cp++; if ( d < 0 ) d += 2 * x + 3; else { d += 2 * (x - y) + 5; y--; } x++; if ( x < y ) cpt += 8; else if ( x == y ) cpt += 4; } return(cpt); } int comptePixelsDisque(int r) { int x,y,d; x = 0; y = r; d = 1 - r; if ( r == 0 ) { return(1); } if ( r == 1 ) { return(5); } int cpt = comptePixelsTrame(-y,y); while ( y > x ) { if ( d < 0 ) d += 2 * x + 3; else { if ( y > x ) { cpt += comptePixelsTrame(-x,x); cpt += comptePixelsTrame(-x,x); } d += 2 * (x - y) + 5; y--; } x++; if ( y >= x ) { cpt += comptePixelsTrame(-y,y); cpt += comptePixelsTrame(-y,y); } } return(cpt); } int comptePixelsDisqueIncomplet(int r,int max) { int x,y,d; x = 0; y = r; d = 1 - r; if ( r == 0 ) { return(1); } if ( r == 1 ) { return(5); } int cpt = comptePixelsTrame(-y,y); int cp = 0; while ( ( y > x ) && ( cp < max ) ) { cp++; if ( d < 0 ) d += 2 * x + 3; else { if ( y > x ) { cpt += comptePixelsTrame(-x,x); cpt += comptePixelsTrame(-x,x); } d += 2 * (x - y) + 5; y--; } x++; if ( y >= x ) { cpt += comptePixelsTrame(-y,y); cpt += comptePixelsTrame(-y,y); } } return(cpt); } void displayV(void) { glClearColor(0.0F,0.0F,0.0F,1.0F) ; glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glPushMatrix(); float pos = 1.0F; glColor4fv(couleurBlanc()); placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"RAYON : %6d",r); pos += 1.0F; switch (aff) { case 0 : if ( ( cc == 0 ) || ( cc == 2 ) ) { placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1, REGULAR8x13, "2*PI*R : %9.2f", 2*M_PI*r); pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1, REGULAR8x13, "PIXELS DU CERCLE : %6d", comptePixelsCercle(r)); pos += 1.0F; } if ( ( cc == 1 ) || ( cc == 2 ) ) { placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1, REGULAR8x13, "PI*R*R : %9.2f", M_PI*r*r); pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1, REGULAR8x13, "PIXELS DU DISQUE : %6d", comptePixelsDisque(r)); pos += 1.0F; } break; case 1 : if ( ( cc == 0 ) || ( cc == 2 ) ) { placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1, REGULAR8x13, "PIXELS DU CERCLE : %6d", comptePixelsCercleIncomplet(r,yy)); pos += 1.0F; } if ( ( cc == 1 ) || ( cc == 2 ) ) { placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1, REGULAR8x13, "PIXELS DU DISQUE : %6d", comptePixelsDisqueIncomplet(r,yy)); pos += 1.0F; } break; } glPopMatrix(); glFlush(); glutSwapBuffers(); } void reshapeV(int w,int h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,w,-h,0,-1.0,1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } int main(int argc,char **argv) { glutInit(&argc,argv); { glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(300,300); glutInitWindowPosition(50,50); f1 = glutCreateWindow("Cercle et disque par Bresenham"); myinit(); creationMenuBasique(); setParametresOrthoBasique(-30.0,30.0,-30.0,30.0,-40.0,40.0); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutDisplayFunc(display); } { glutInitWindowSize(300,70); glutInitWindowPosition(50,380); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); fv = glutCreateWindow("Valeurs"); creationMenuBasique(); glutDisplayFunc(displayV); glutReshapeFunc(reshapeV); glutKeyboardFunc(key); } glutMainLoop(); return(0); }