L'exécutable

Le source : Position2D.h

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

#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

Le source : Position2D.cpp

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

#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]);
}

Le source : Segment2D.h

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

#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);
    double abscisse(double y);
    double ordonnee(double x);
    int clip(Rectangle2D *r);
};

#endif

Le source : Segment2D.cpp

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

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

#include "Segment2D.h"
#include "Position2D.h"
#include "Rectangle2D.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)));
}

int code(Position2D *p,Rectangle2D *r) {
  int code = 0x0000; 
  if ( p->c[0] < r->ig->c[0] )
    code |= 0x0001;
  if ( p->c[0] > r->sd->c[0] )
    code |= 0x0002;
  if ( p->c[1] < r->ig->c[1] )
    code |= 0x0004;
  if ( p->c[1] > r->sd->c[1] )
    code |= 0x0008;
  return(code);
}

double Segment2D::abscisse(double y) {
  double a = (pf->c[1]-pi->c[1])/(pf->c[0]-pi->c[0]);
  double b = pi->c[1] - a*pi->c[0];
  return((y-b)/a);
}

double Segment2D::ordonnee(double x) {
  double a = (pf->c[1]-pi->c[1])/(pf->c[0]-pi->c[0]);
  double b = pi->c[1] - a*pi->c[0];
  return(a*x+b);
}

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&0x0001) != 0 ) {
      pi->c[1] = ordonnee(r->ig->c[0]);
      pi->c[0] = r->ig->c[0]; }
      else
      if ( (c1&0x0002) != 0 ) {
        pi->c[1] = ordonnee(r->sd->c[0]);
        pi->c[0] = r->sd->c[0]; }
        else
        if ( (c1&0x0004) != 0 ) {
          pi->c[0] = abscisse(r->ig->c[1]);
          pi->c[1] = r->ig->c[1]; }
          else
          if ( (c1&0x0008) != 0 ) {
            pi->c[0] = abscisse(r->sd->c[1]);
            pi->c[1] = r->sd->c[1]; }
    c1 = code(pi,r); }
  return ( !c1 && !c2);
}

Le source : Rectangle2D.h

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

#ifndef ____RECTANGLE2D____
#define ____RECTANGLE2D____

class Position2D;
class Segment2D;

class Rectangle2D  {

  public :
    Position2D *ig,*sd;

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

#endif

Le source : Rectangle2D.cpp

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

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

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

Rectangle2D::Rectangle2D(void) {
  ig = new Position2D();
  sd = new Position2D();
}

Rectangle2D::Rectangle2D(Position2D *p1,Position2D *p2) {
  ig = new Position2D(p1);
  sd = new Position2D(p2);
}

Rectangle2D::Rectangle2D(Rectangle2D *s) {
  ig = new Position2D(s->ig);
  sd = new Position2D(s->sd);
}

Rectangle2D::~Rectangle2D(void) {
  delete(ig);
  delete(sd);
}

void Rectangle2D::print(void) {
  ig->print();
  printf("\n");
  sd->print();
  printf("\n");
}

void Rectangle2D::clip(Segment2D *s) {
  s->clip(this);
}

Le source : Cohen-Sutherland.cpp

/* Clipping de Cohen-Sutherland                 */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Septembre 2011                               */

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

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

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

/* Variables et constantes globales             */

static int scn = 0;

/* Fonction d'initialisation des parametres     */
/* OpenGL ne changeant pas au cours de la vie   */
/* du programme                                 */

void init(void) {
}

/* Scene dessinee                               */

static void drawRectangle(Rectangle2D *r) {
  glPushMatrix();
  glBegin(GL_LINE_LOOP);
  glVertex2d(r->ig->c[0],r->ig->c[1]);
  glVertex2d(r->sd->c[0],r->ig->c[1]);
  glVertex2d(r->sd->c[0],r->sd->c[1]);
  glVertex2d(r->ig->c[0],r->sd->c[1]);
  glEnd();
  glPopMatrix();
}

static void drawSegment(Segment2D *s) {
  glPushMatrix();
  glBegin(GL_LINES);
  glVertex2d(s->pi->c[0]+0.4999,s->pi->c[1]+0.4999);
  glVertex2d(s->pf->c[0]+0.4999,s->pf->c[1]+0.4999);
  glEnd();
  glPopMatrix();
}

void sceneAvecClipping(void) {
  Position2D *p1 = new Position2D(100.0,80.0);
  Position2D *p2 = new Position2D(300.0,220.0);
  Rectangle2D *r = new Rectangle2D(p1,p2);
  delete(p1);
  delete(p2);
  glPushMatrix();
  glColor3f(1.0F,1.0F,1.0F);
  drawRectangle(r);
  glPopMatrix();
  for ( int i = 0 ; i < 100 ; i++ ) {
    Position2D *pi = new Position2D(rand()%400,rand()%300);
    Position2D *pf = new Position2D(rand()%400,rand()%300);
    Segment2D *s = new Segment2D(pi,pf);
    delete(pi);
    delete(pf);
    glColor3f(1.0F,0.0F,0.0F);
    if ( s->clip(r) )
      drawSegment(s);
    delete(s); }
  delete(r);
}

void sceneSansClipping(void) {
  Position2D *p1 = new Position2D(100.0,80.0);
  Position2D *p2 = new Position2D(300.0,220.0);
  Rectangle2D *r = new Rectangle2D(p1,p2);
  delete(p1);
  delete(p2);
  glPushMatrix();
  glColor3f(1.0F,1.0F,1.0F);
  drawRectangle(r);
  glPopMatrix();
  for ( int i = 0 ; i < 100 ; i++ ) {
    Position2D *pi = new Position2D(rand()%400,rand()%300);
    Position2D *pf = new Position2D(rand()%400,rand()%300);
    Segment2D *s = new Segment2D(pi,pf);
    delete(pi);
    delete(pf);
    glColor3f(1.0F,0.0F,0.0F);
    drawSegment(s);
    delete(s); }
  delete(r);
}

/* Fonction executee lors d'un changement       */
/* de la taille de la fenetre OpenGL            */

void reshape(int tx,int ty) {
  glViewport(0,0,tx,ty); 
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0,tx,0,ty,-20.0,20.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

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

void display(void) {
  glClearColor(0.5F,0.5F,0.5F,0.5F);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  srand(1);
  glPushMatrix();
  if ( scn )
    sceneAvecClipping();
    else 
    sceneSansClipping();
  glPopMatrix();
  glFlush();
  glutSwapBuffers();
  int error = glGetError();
  if ( error != GL_NO_ERROR )
    printf("Erreur : %d\n",error);
}

/* Fonction executee lors de l'appui            */
/* d'une touche alphanumerique du clavier       */

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

/* Fonction principale                          */

int main(int argc,char **argv) {
  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(400,300); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("Clipping de Cohen-Sutherland"); 
  init();
  glutKeyboardFunc(keyboard);
  glutReshapeFunc(reshape);
  glutDisplayFunc(display);
  glutMainLoop();
  return(0);
}

RETOUR