L'exécutable

TP07-1.png (4651 octets)

TP07-2.png (4582 octets)

TP07-3.png (4566 octets)

TP07-4.png (4622 octets)

/* Dessin d'un segment de droite par Bresenham  */
/* Remplissage 2D d'un triangle                 */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2010                                */

#if defined(WIN32) || defined(WIN64)
  #define _CRTDBG_MAP_ALLOC
  #if defined(_DEBUG)
    #define _AFXDLL
    #include <afx.h>
  #endif
#endif
#include <stdlib.h>
#if defined(WIN32) || defined(WIN64)
  #include <crtdbg.h>
#endif
#include <stdio.h>
#include <math.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include "Position2D.h"
#include "Segment2D.h"
#include "Triangle2D.h"
#include "Trace.h"

/* Variables globales                           */

static int sc = 0;

/* Fonction executee lors d'un changement       */
/* de la taille de la fenetre OpenGL            */
/* Configuration d'une camera de visualisation  */
/* en projection en parallele orthographique    */

void reshape(int tx,int ty) {
  glViewport(0,0,tx,ty);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho((-tx/2)/10.0,(-tx/2+tx)/10.0,
          (-ty/2)/10.0,(-ty/2+ty)/10.0,
          -1.0,1.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin                      */

void display(void) {
  glClearColor(0.6F,0.6F,0.6F,1.0F) ;
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) ;
  Position2D *ps11 = new Position2D(-15.0,9.0);
  Position2D *ps12 = new Position2D(10.0,-10.0);
  Segment2D *s1 = new Segment2D(ps11,ps12);
  Position2D *ps21 = new Position2D(3.0,2.0);
  Position2D *ps22 = new Position2D(15.0,6.0);
  Segment2D *s2 = new Segment2D(ps21,ps22);
  Position2D *ps32 = new Position2D(-7.0,-13.0);
  Position2D *ps31 = new Position2D(-17.0,5.0);
  Segment2D *s3 = new Segment2D(ps31,ps32);
  Position2D *pt1 = new Position2D(-13.0,9.0);
  Position2D *pt2 = new Position2D(11.0,13.0);
  Position2D *pt3 = new Position2D(2.0,-10.0);
  Triangle2D *t = new Triangle2D(pt1,pt2,pt3);
  glPushMatrix();
  if ( sc == 0 ) {
    glColor3f(0.0F,1.0F,0.0F);
    s1->trace();
    s2->trace();
    s3->trace(); }
  if ( ( sc == 2 ) || ( sc == 3 ) ) {
    glColor3f(0.0F,0.0F,1.0F);
    t->remplit(); }
  if ( ( sc == 1 ) || ( sc == 3 ) ) {
    glColor3f(1.0F,0.0F,0.0F);
    t->trace(); }
  glPopMatrix();
  delete(s1);
  delete(ps11);
  delete(ps12);
  delete(s2);
  delete(ps21);
  delete(ps22);
  delete(s3);
  delete(ps31);
  delete(ps32);
  delete(pt1);
  delete(pt2);
  delete(pt3);
  delete(t);
  glFlush();
  glutSwapBuffers();
  int error = glGetError();
  if ( error != GL_NO_ERROR )
    printf("Attention, erreur OpenGL %d\n",error);
}

/* Fonction executee lors de la frappe          */
/* d'une touche alphanumerique du clavier       */

void keyboard(unsigned char key,int x,int y) {
  switch ( key ) {
    case 0x0D : sc = (sc+1)%4;
                glutPostRedisplay();
                break;
    case 0x1B : exit(0); }
}

/* Fonction d'initialisation d'OpenGL           */
void init(void) {
  glPointSize(10.0F);
}

/* Fonction principale                          */

int main(int argc,char **argv) {

#if defined(WIN32) || defined(WIN64)
  _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
  //_crtBreakAlloc = 109;
#endif

  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
  glutInitWindowSize(400,300); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("Bresenham & remplissage triangle");
  init();
  glutReshapeFunc(reshape);
  glutKeyboardFunc(keyboard);
  glutDisplayFunc(display);
  glutMainLoop();
  return(0);
}

Position2D.h

/* Position en coordonnees homogenes 2D         */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2010                                */

#ifndef ____POSITION2D____
#define ____POSITION2D____

class Position2D  {

  public :
    double c[3];

  public :
    Position2D(void);
    Position2D(double x,double y);
    Position2D(Position2D *p);
    ~Position2D(void);
    void print(void);
};

#endif

Position2D.cpp

/* Position en coordonnees homogenes 2D         */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2010                                */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include "Position2D.h"

Position2D::Position2D(void) {
  c[0] = c[1] = 0.0;
  c[2] = 1.0;
}

Position2D::Position2D(double x,double y) {
  c[0] = x;
  c[1] = y;
  c[2] = 1.0;
}

Position2D::Position2D(Position2D *p) {
  c[0] = p->c[0];
  c[1] = p->c[1];
  c[2] = p->c[2];
}

Position2D::~Position2D(void) {
}

void Position2D::print(void) {
  printf("%20.14lf %20.14lf %lf",c[0],c[1],c[2]);
}

Segment2D.h

/* Segment en 2D                                */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2010                                */

#ifndef ____SEGMENT2D____
#define ____SEGMENT2D____

class Position2D;
class Rectangle2D;

class Segment2D  {

  public :
    Position2D *pi,*pf;

  public :
    Segment2D(void);
    Segment2D(Position2D *p1,Position2D *p2);
    Segment2D(Segment2D *s);
    ~Segment2D(void);
    void print(void);
    void trace(void);
    int clip(Rectangle2D *r);
};

#endif

Segment2D.cpp

/* Segment en 2D                                */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2010                                */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include "Segment2D.h"
#include "Position2D.h"
#include "Rectangle2D.h"
#include "Trace.h"

Segment2D::Segment2D(void) {
  pi = new Position2D();
  pf = new Position2D();
}

Segment2D::Segment2D(Position2D *p1,Position2D *p2) {
  pi = new Position2D(p1);
  pf = new Position2D(p2);
}

Segment2D::Segment2D(Segment2D *s) {
  pi = new Position2D(s->pi);
  pf = new Position2D(s->pf);
}

Segment2D::~Segment2D(void) {
  delete(pi);
  delete(pf);
}

void Segment2D::print(void) {
  pi->print();
  printf("\n");
  pf->print();
  printf("\n");
}

static int round(double v) {
  return((int) (v + (( v > 0.0 ) ? 0.4999 : -0.4999)));
}

void Segment2D::trace(void) {
  traceSegment(round(pi->c[0]),round(pi->c[1]),
               round(pf->c[0]),round(pf->c[1]));
}

double intersection(double ai,double bi,
                    double af,double bf,double val) {
  if ( af-ai != 0 )
    return(bi + (val-ai)/(af-ai)*(bf-bi));
    else
    return(1000000.0);
}

int code(Position2D *p,Rectangle2D *r) {
  int code = 0; 
  if ( p->c[0] < r->ig->c[0] )
    code += 1;
  if ( p->c[0] > r->sd->c[0] )
    code += 2;
  if ( p->c[1] < r->ig->c[1] )
    code += 4;
  if ( p->c[1] > r->sd->c[1] )
    code += 8;
  return(code);
}

int Segment2D::clip(Rectangle2D *r) {
  int c1,c2;
  c1 = code(pi,r);
  c2 = code(pf,r);
  while ( ( c1 || c2 ) && ( (c1&c2) == 0 ) ) {
    if ( !c1 ) {
      Position2D p = *pi;
      *pi = *pf;
      *pf = p;
      int aux = c1;
      c1 = c2;
      c2 = aux; }
    if ( (c1&0x01) != 0 ) {
      pi->c[1] = intersection(pi->c[0],pi->c[1],
                              pf->c[0],pf->c[1],
                              r->ig->c[0]);
      pi->c[0] = r->ig->c[0]; }
      else
      if ( (c1&0x02) != 0 ) {
        pi->c[1] = intersection(pi->c[0],pi->c[1],
                                pf->c[0],pf->c[1],
                                r->sd->c[0]);
        pi->c[0] = r->sd->c[0]; }
        else
        if ( (c1&0x04) != 0 ) {
          pi->c[0] = intersection(pi->c[1],pi->c[0],
                                  pf->c[1],pf->c[0],
                                  r->ig->c[1]);
          pi->c[1] = r->ig->c[1]; }
          else
          if ( (c1&0x08) != 0 ) {
            pi->c[0] = intersection(pi->c[1],pi->c[0],
                                    pf->c[1],pf->c[0],
                                    r->sd->c[1]);
            pi->c[1] = r->sd->c[1]; }
    c1 = code(pi,r); }
  return ( !c1 && !c2);
}

Triangle2D.h

/* Triangle en 2D                               */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2010                                */

#ifndef ____TRIANGLE2D____
#define ____TRIANGLE2D____

class Position2D;

class Triangle2D  {

  public :
    Position2D *p1,*p2,*p3;

  public :
    Triangle2D(void);
    Triangle2D(Position2D *pt1,
               Position2D *pt2,
               Position2D *pt3);
    Triangle2D(Triangle2D *t);
    ~Triangle2D(void);
    void print(void);
    void trace(void);
    void remplit(void);
};

#endif

Triangle2D.cpp

/* Triangle en 2D                               */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2010                                */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

#include "Triangle2D.h"
#include "Position2D.h"
#include "Trace.h"

Triangle2D::Triangle2D(void) {
  p1 = new Position2D();
  p2 = new Position2D();
  p3 = new Position2D();
}

Triangle2D::Triangle2D(Position2D *pt1,
                       Position2D *pt2,
                       Position2D *pt3) {
  p1 = new Position2D(pt1);
  p2 = new Position2D(pt2);
  p3 = new Position2D(pt3);
}

Triangle2D::Triangle2D(Triangle2D *t) {
  p1 = new Position2D(t->p1);
  p2 = new Position2D(t->p2);
  p3 = new Position2D(t->p3);
}

Triangle2D::~Triangle2D(void) {
  delete(p1);
  delete(p2);
  delete(p3);
}

void Triangle2D::print(void) {
  p1->print();
  printf("\n");
  p2->print();
  printf("\n");
  p3->print();
  printf("\n");
}

static int round(double v) {
  return((int) (v + (( v > 0.0 ) ? 0.4999 : -0.4999)));
}

void Triangle2D::trace(void) {
  traceSegment(round(p1->c[0]),round(p1->c[1]),
               round(p2->c[0]),round(p2->c[1]));
  traceSegment(round(p1->c[0]),round(p1->c[1]),
               round(p3->c[0]),round(p3->c[1]));
  traceSegment(round(p3->c[0]),round(p3->c[1]),
               round(p2->c[0]),round(p2->c[1]));
}

static void gereAbscisse(int x,int y,int *xmin,int *xmax) {
  if ( x < xmin[y] )
    xmin[y] = x;
  if ( x > xmax[y] )
    xmax[y] = x;
}

static void traceCote(int xi,int yi,int xf,int yf,
                      int *xmin,int *xmax,int ymin) {
  int i,cumul;
  yi -= ymin;
  yf -= ymin;
  int x = xi;
  int y = yi;
  int dx = xf - xi;
  int dy = yf - yi;
  int xinc = ( dx > 0 ) ? 1 : -1;
  int yinc = ( dy > 0 ) ? 1 : -1;
  dx = abs(dx);
  dy = abs(dy);
  gereAbscisse(x,y,xmin,xmax);
  if ( dx > dy ) {
    cumul = dx / 2;
    for ( i = 1 ; i <= dx ; i++ ) {
      x += xinc;
      cumul += dy;
      if (cumul >= dx) {
        cumul -= dx;
        y += yinc; }
      gereAbscisse(x,y,xmin,xmax); } }
    else {
    cumul = dy / 2;
    for ( i = 1 ; i <= dy ; i++ ) {
      y += yinc;
      cumul += dx;
      if ( cumul >= dy ) {
        cumul -= dy;
        x += xinc; }
      gereAbscisse(x,y,xmin,xmax); } }
}

void Triangle2D::remplit(void) {
  int ymin = round(p1->c[1]);
  int ymax = round(p1->c[1]);
  if ( round(p2->c[1]) < ymin )
    ymin = round(p2->c[1]);
  if ( round(p2->c[1]) > ymax )
    ymax = round(p2->c[1]);
  if ( round(p3->c[1]) < ymin )
    ymin = round(p3->c[1]);
  if ( round(p3->c[1]) > ymax )
    ymax = round(p3->c[1]);
  int dy = ymax-ymin+1;
  int *xmin =(int *) calloc(dy,sizeof(int));
  int *xmax =(int *) calloc(dy,sizeof(int));
  for ( int i = 0 ; i < dy ; i++ ) {
    xmax[i] = -1000000;
    xmin[i] = 1000000; }
  traceCote(round(p1->c[0]),round(p1->c[1]),
            round(p2->c[0]),round(p2->c[1]),
            xmin,xmax,ymin);
  traceCote(round(p1->c[0]),round(p1->c[1]),
            round(p3->c[0]),round(p3->c[1]),
            xmin,xmax,ymin);
  traceCote(round(p3->c[0]),round(p3->c[1]),
            round(p2->c[0]),round(p2->c[1]),
            xmin,xmax,ymin);
  glBegin(GL_POINTS);
  for ( int y = ymin ; y <= ymax ; y++ )
    for ( int x = xmin[y-ymin] ; x <= xmax[y-ymin] ; x++ )
      glVertex2i(x,y);
  glEnd();
  free(xmin);
  free(xmax);
}

Trace.h

/* Fonctions de dessin OpenGL                   */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2010                                */

#ifndef ____TRACE____
#define ____TRACE____

void traceSegment(int xi,int yi,int xf,int yf);

#endif

Trace.cpp

/* Fonctions de dessin OpenGL                   */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Novembre 2010                                */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

void traceSegment(int xi,int yi,int xf,int yf) {
  glBegin(GL_POINTS);
  int i,cumul;
  int x = xi;
  int y = yi;
  int dx = xf - xi;
  int dy = yf - yi;
  int xinc = ( dx > 0 ) ? 1 : -1;
  int yinc = ( dy > 0 ) ? 1 : -1;
  dx = abs(dx);
  dy = abs(dy);
  glVertex2i(x,y);
  if ( dx > dy ) {
    cumul = dx / 2;
    for ( i = 1 ; i <= dx ; i++ ) {
      x += xinc;
      cumul += dy;
      if (cumul >= dx) {
        cumul -= dx;
        y += yinc; }
      glVertex2i(x,y); } }
    else {
    cumul = dy / 2;
    for ( i = 1 ; i <= dy ; i++ ) {
      y += yinc;
      cumul += dx;
      if ( cumul >= dy ) {
        cumul -= dy;
        x += xinc; }
      glVertex2i(x,y); } }
  glEnd();
}

RETOUR