#include #include #include #define N 30 /* Info.Graphique(Infographie) : Sutherland Hodgman : Clipping de polygone 13-03-04 ©2004 http://www.Software-DS.com Didier STRAUS gcc -o Sutherland_Hodgman Sutherland_Hodgman.c -L/usr/X11R6/lib -lX11 */ typedef struct point {int x; int y;} point; /* variables globales */ GC gc; Display *display; int screen,N2; Window win,root; int win_larg,win_haut; unsigned long white_pixel, black_pixel; /* Prototypes */ void charger(point ptI,point PS[N]); point Intersection(point P1, point P2, point P3, point P4); int visible(point P, point P1, point P2); int coupe(point S,point P,point F1,point F2); int Sutherland_Hodgman(int * N1,int N3,point PL[N],point PW[N]); void gerer_evenement(); void Creat_fenetre(void); void contact_serveur(); /* ******************************************************************** */ void contact_serveur() { if ((display = XOpenDisplay("")) == NULL) { fprintf(stderr, "Can't open Display\n"); exit(1); } } /* contact_serveur */ /* ******************************************************************** */ void Creat_fenetre(void) { short border_width; screen = DefaultScreen(display); root = RootWindow(display,screen); white_pixel= WhitePixel(display,screen); black_pixel= BlackPixel(display,screen); border_width = 3; win_larg = DisplayWidth(display,screen)/4; win_haut = DisplayHeight(display,screen)/4; win = XCreateSimpleWindow(display,root,0,0,win_larg,win_haut, border_width,black_pixel,white_pixel); gc=DefaultGC(display,screen); XStoreName(display,win,"Sutherland_Hodgman"); XMapWindow(display,win); } /* ******************************************************************** */ void gerer_evenement() { char *str1="http://www.Software-DS.com"; int i,N1,NW,dist; point POLY[N]; point FENE[N]; N1=NW=0; XSelectInput(display,win,ExposureMask | KeyPressMask | ButtonPressMask); for(;;) { XEvent ev; XNextEvent(display,&ev); switch(ev.type){ case Expose : /* On va afficher des dessins ;) */ FENE[0].x=20; FENE[0].y=20; FENE[1].x=80; FENE[1].y=20; FENE[2].x=80; FENE[2].y=80; FENE[3].x=20; FENE[3].y=80; FENE[4].x=20; FENE[4].y=20; POLY[0].x=60; POLY[0].y=0; POLY[1].x=4; POLY[1].y=40; POLY[2].x=56; POLY[2].y=88; POLY[3].x=90; POLY[3].y=50; NW=4; N1=4; // la fenetre polygone (le carre) for(i=0;i<(NW-1);i++) { XDrawLine(display,win,gc,FENE[i].x,FENE[i].y,FENE[i+1].x,FENE[i+1].y); } XDrawLine(display,win,gc,FENE[NW-1].x,FENE[NW-1].y,FENE[0].x,FENE[0].y); dist=130; for(i=0;i<(NW-1);i++) { // on affiche le carre avec un decalage vers la droite de 'dist' pixels XDrawLine(display,win,gc,FENE[i].x+dist,FENE[i].y,FENE[i+1].x+dist,FENE[i+1].y); } XDrawLine(display,win,gc,FENE[NW-1].x+dist,FENE[NW-1].y,FENE[0].x+dist,FENE[0].y); for(i=0;i0) { if (coupe(S,P,PW[i],PW[i+1])) { ptI=Intersection(S,P,PW[i],PW[i+1]); charger(ptI,PS); } } *N1=N2; for(k=0;k0)) { PL[j]=PS[k]; j++; } } // for k *N1=j; } /* Sutherland_Hodgman */ /* *********************************************************** */ int coupe(point S,point P,point F1,point F2) { int v1,v2; v1=visible(S,F1,F2); v2=visible(P,F1,F2); if ((v1*v2)<0) return 1; // signe ­ else return 0; // signe = } /* coupe */ /* *********************************************************** */ int visible(point P, point P1, point P2) { int signe; signe=((P2.x-P1.x)*(P.y-P1.y))-((P.x-P2.x)*(P2.y-P1.y)); if (signe<0) return -1; else if (signe>0) return 1; return 0; // signe=0 } /* visible */ /* *********************************************************** */ point Intersection(point P1, point P2, point P3, point P4) { point res; double mat[2][2]; double a,b,c,d,e,f,s,t; a=P2.x-P1.x; b=-(P4.x-P3.x); c=P2.y-P1.y; d=-(P4.y-P3.y); e=P3.x-P1.x; f=P3.y-P1.y; /* calcul de la matrice inverse */ mat[0][0]=d/(a*d-b*c); mat[0][1]=-b/(a*d-b*c); mat[1][0]=-c/(a*d-b*c); mat[1][1]=a/(a*d-b*c); /* (s,t)= M^(-1)*b (b=[e,f]) */ s=mat[0][0]*e + mat[0][1]*f; t=mat[1][0]*e + mat[1][1]*f; res.x=P1.x+(P2.x-P1.x)*s; res.y=P1.y+(P2.y-P1.y)*s; // XDrawPoint(display,win,gc,res.x+1,res.y+1); return res; } /* Intersection */ /* *********************************************************** */ void charger(point ptI,point PS[N]) { // N2 et PS sont declare en globales ! PS[N2].x=ptI.x; PS[N2].y=ptI.y; N2++; } /* charger */