L'exécutable

En blanc, le rectangle de clipping, en bleu le segment complet, en rouge le segment clippé.

 Temple1.gif (5936 octets)

Temple1.gif (5936 octets)

Temple1.gif (5936 octets)

Le source : TP-Clipping.cpp

#include <windows.h>

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

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

typedef struct Point2D {
  int x;
  int y; } Point2D ;

typedef struct Segment {
  Point2D pi;
  Point2D pf; } Segment ;

typedef struct MyRectangle {
  int xmin;
  int ymin;
  int xmax;
  int ymax; } MyRectangle ;

static int fenetre ;
static int height ;
static int mouvement = 0 ;
static int button = 0 ;
static Segment s = { {10,50},{270,180} };

int code(Point2D *p,MyRectangle *r) {
  int res = 0x0000;
  if ( p->x < r->xmin ) res |= 0x0001;
  if ( p->x > r->xmax ) res |= 0x0010;
  if ( p->y < r->ymin ) res |= 0x0100;
  if ( p->y > r->ymax ) res |= 0x1000;
  return(res);
}

int adjacents(Point2D *p1,Point2D *p2) {
  if ( ( abs(p1->x-p2->x) <=1 ) && ( abs(p1->y-p2->y) <=1 ) )
    return(1);
  return(0);
}

void traceRectangle(MyRectangle *r) {
  glBegin(GL_LINE_LOOP);
  glVertex2i(r->xmin,r->ymin);
  glVertex2i(r->xmax,r->ymin);
  glVertex2i(r->xmax,r->ymax);
  glVertex2i(r->xmin,r->ymax);
  glEnd();
}

void traceSegment(Segment *s) {
  glBegin(GL_LINES);
  glVertex2i(s->pi.x,s->pi.y);
  glVertex2i(s->pf.x,s->pf.y);
  glEnd();    
}

void clippingRecursif(Segment *s,MyRectangle *r) {
  int cpi = code(&s->pi,r);
  int cpf = code(&s->pf,r);
  //printf("%04x %04x\n",cpi,cpf);
  if ( ( cpi == 0 ) && ( cpf == 0 ) ) {
    traceSegment(s);
    //printf("Trace entre (%d,%d) et (%d,%d)\n",s->pi.x,s->pi.y,s->pf.x,s->pf.y);
    return; }
  if ( (cpi&cpf) != 0 ) {
    //printf("Ne trace pas\n");
    return; }
  //printf("Decompose entre (%d,%d) et (%d,%d)\n",s->pi.x,s->pi.y,s->pf.x,s->pf.y);
  if ( adjacents(&s->pi,&s->pf) ) {
    Segment s1 = { { s->pi.x,s->pi.y } , { s->pi.x,s->pi.y } };
    Segment s2 = { { s->pf.x,s->pf.y } , { s->pf.x,s->pf.y } };
    clippingRecursif(&s2,r);
    clippingRecursif(&s1,r);}
    else {
    int x = (s->pi.x+s->pf.x)/2;
    int y = (s->pi.y+s->pf.y)/2;
    Segment s1 = { { s->pi.x,s->pi.y } , { x,y } };
    Segment s2 = { { x,y } , { s->pf.x,s->pf.y } };
    clippingRecursif(&s2,r);
    clippingRecursif(&s1,r);}
}

void display() {
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glPushMatrix();
  MyRectangle r = { 80,60,240,200 };
  glColor3f(1.0f,1.0f,1.0f);
  traceRectangle(&r);
  glColor3f(0.0f,0.0f,1.0f);
  traceSegment(&s);
  glColor3f(1.0f,0.0f,0.0f);
  printf("(%d,%d) et (%d,%d)\n",s.pi.x,s.pi.y,s.pf.x,s.pf.y);
  clippingRecursif(&s,&r);
  glPopMatrix();
  glFlush();
  glutSwapBuffers() ;
}

static void souris(int bouton,int etat,int x,int y) {
  button = bouton;
  if ( bouton == GLUT_LEFT_BUTTON ) {
    s.pi.x = x ;
    s.pi.y = height-y ; 
    if ( etat == GLUT_DOWN ) {
      mouvement = 1 ;}
    if ( etat == GLUT_UP ) {
      mouvement = 0 ; } 
    glutPostWindowRedisplay(fenetre); }
  if ( bouton == GLUT_RIGHT_BUTTON ) {
    s.pf.x = x ;
    s.pf.y = height-y ; 
    if ( etat == GLUT_DOWN ) {
      mouvement = 1 ;}
    if ( etat == GLUT_UP ) {
      mouvement = 0 ; } 
    glutPostWindowRedisplay(fenetre); }
}

static void motion(int x,int y) {
  switch ( button ) {
  case GLUT_LEFT_BUTTON  : if ( mouvement == 1 ) {
                             s.pi.x = x ;
                             s.pi.y = height-y ; 
                             glutPostWindowRedisplay(fenetre); }
                           break;
  case GLUT_RIGHT_BUTTON : if ( mouvement == 1 ) {
                             s.pf.x = x ;
                             s.pf.y = height-y ; 
                             glutPostWindowRedisplay(fenetre); } }
}

void reshape(int w,int h) {
  glViewport(0,0,w,h);
  height = h ;
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0,w,0,h,-40.0,40.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

void CALLBACK init() {
  glShadeModel(GL_SMOOTH);
  glClearColor(0.8F,0.8F,0.8F,1.0F);
}

void main(void) {
  glutInitWindowSize(300,300);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  fenetre = glutCreateWindow("Clipping recursif");
  glutMotionFunc(motion);
  glutMouseFunc(souris);
  glutDisplayFunc(display);
  init();
  glutReshapeFunc(reshape);
  glutMainLoop();
}
WB01624_.gif (281 octets) RETOUR