/* rempol-tp.c - Edouard Thiel - 04/01/2001 Compilation : cc rempol-tp.c -o rempol-tp `~/helium/helium-cfg --cflags --libs` Usage : rempol-tp */ #include He_node *princ, *canvas, *panel1, *panel2, *mess1, *tog1, *tog2; #define PMAX 10000 int Px[PMAX], Py[PMAX], Pn = 0; #define MIN_DIST 3 /*--------------------------- A F F I C H A G E ------------------------------*/ int c_gris, c_rouge, c_vert, c_bleu, c_jaune, c_cyan, c_magenta; /* * Initialise les couleurs */ void init_couleurs () { c_gris = HeAllocRgb (150, 150, 150, he_black); c_rouge = HeAllocRgb (255, 0, 0, he_black); c_vert = HeAllocRgb ( 0, 255, 0, he_black); c_bleu = HeAllocRgb ( 0, 0, 255, he_black); c_jaune = HeAllocRgb (255, 255, 0, he_black); c_cyan = HeAllocRgb ( 0, 255, 255, he_black); c_magenta = HeAllocRgb (255, 0, 255, he_black); } /* * Change la couleur courante */ void couleur (int coul) { XSetForeground (he_display, he_gc, coul); } /* * Dessine une ligne joignant x1,y1 à x2,y2 */ void dessin_ligne (Window win, int x1, int y1, int x2, int y2) { XDrawLine (he_display, win, he_gc, x1, y1, x2, y2); } /* * Dessine un carré de centre x,y et de rayon MIN_DIST */ void dessin_carre (Window win, int x, int y) { int l = MIN_DIST; XDrawRectangle (he_display, win, he_gc, x-l, y-l, l*2, l*2); } /*----------------------- A L G O R I T H M E S ------------------------------*/ /* * Tri à bulle optimisé de v1, v2 sur [0..n-1]. * La clé est donnée par v1, l'information par v2. */ void tri_bulle (int *v1, int *v2, int n) { /* A COMPLETER */ } /* * Renvoie le x de l'intersection de la droite horizontale Dy avec l'arête Ai * c'est-à-dire l'arête (Px[i],Py[i]),(Px[i+1],Py[i+1]). */ int intersec_x (int i, int y) { /* A COMPLETER */ return 0; /* temporaire */ } /* * Met à jour le tableau des arêtes actives aa. * ty est le tableau des Py triés croissants. * indy est tel que Py[indy[k]] = ty[k]. * i est l'indice du premier sommet de ty pour ce niveau y. * Retour : l'indice du premier sommet de ty au niveau y suivant. */ int reactu_aretes (int *ty, int *indy, int *aa, int i) { /* A COMPLETER */ return 0; /* temporaire */ } /* * Colorie la bande [ya..yb]. * aa est le tableau des arêtes actives, c'est à dire des arêtes * qui intersectent toutes les lignes de la bande [ya..yb]. */ void remplis_niv (Window win, int ya, int yb, int *aa) { /* A COMPLETER */ } /* * Remplissage du polygone Px[], Py[], Pn. * Le polygone n'a pas besoin d'être orienté, et il peut se recouper. */ void remplissage (Window win) { /* A COMPLETER */ } /*---------------------------- I N T E R F A C E ----------------------------*/ void quit_proc (He_node *hn) { HeQuit(0); } void vider_proc (He_node *hn) { Pn = 0; HePostRepaint (canvas); } void reaffi_proc (He_node *hn) { HePostRepaint (canvas); } void princ_resize_proc (He_node *hn, int width, int height) { /* ajuste largeurs panels */ HeSetWidth (panel1, width); HeSetWidth (panel2, width); /* met le panel2 en bas */ HeJustify (panel2, NULL, HE_BOTTOM); /* le canvas prend toute la place disponible */ HeExpand (canvas, panel2, HE_BOTTOM); HeExpand (canvas, NULL, HE_RIGHT); } void canvas_resize_proc (He_node *hn, int width, int height) { static int old_width = 1, old_height = 1; int i; /* Mise à l'échelle du polygone */ for (i = 0; i < Pn; i++) { Px[i] = Px[i] * width / old_width; Py[i] = Py[i] * height / old_height; } old_width = width; old_height = height; } /* * Renvoie TRUE si les points (x0,y0) et (x1,y1) sont proches (par exemple * si (x1,y1) est dans le carré centré en (x0,y0) de rayon MIN_DIST). */ int est_proche (int x0, int y0, int x1, int y1) { return (abs(x1 - x0) <= MIN_DIST && abs(y1 - y0) <= MIN_DIST); } /* * Renvoie le numéro du premier sommet qui est proche de (x0,y0) * Si aucun sommet n'est trouvé, renvoie -1. */ int cherche_clic (int x0, int y0) { int i; for (i = 0; i < Pn; i++) if (est_proche (x0, y0, Px[i], Py[i])) return i; return -1; } void canvas_event_proc (He_node *hn, He_event *hev) { int larg = HeGetWidth (canvas), haut = HeGetHeight (canvas), re = FALSE; static int clic = -1; switch (hev->type) { case ButtonPress : { /* Bouton souris pressé */ clic = cherche_clic (hev->sx, hev->sy); if (clic < 0) { clic = Pn; Px[clic] = hev->sx; Py[clic] = hev->sy; Pn ++; re = TRUE; } } break; case MotionNotify : { /* Souris déplacée */ if (hev->sb > 0) { /* avec un bouton enfoncé */ Px[clic] = hev->sx; Py[clic] = hev->sy; re = TRUE; } } break; case ButtonRelease : { /* Bouton souris relaché */ /* Sommet glissé à l'extérieur */ if ( hev->sx < 0 || hev->sy < 0 || hev->sx >= larg || hev->sy >= haut ) { int i; /* Suppression du sommet en décalant à gauche */ Pn--; for (i = clic; i < Pn; i++) { Px[i] = Px[i+1]; Py[i] = Py[i+1]; } re = TRUE; } } break; } if (re) HePostRepaint (canvas); } void canvas_repaint_proc (He_node *hn, Window win) { int larg = HeGetWidth (canvas), i; HeDrawBg (canvas, he_white); /* Dessin des niveaux */ if (HeGetToggleValue(tog1)) { couleur (c_gris); for (i = 0; i < Pn; i++) dessin_ligne (win, 0, Py[i], larg, Py[i]); } /* Dessin du polygone */ couleur (c_bleu); for (i = 0; i < Pn-1; i++) dessin_ligne (win, Px[i], Py[i], Px[i+1], Py[i+1]); /* On ferme le polygone */ if (Pn > 2) { couleur (c_jaune); dessin_ligne (win, Px[Pn-1], Py[Pn-1], Px[0], Py[0]); } /* Dessin des sommets du polygone */ couleur (c_rouge); for (i = 0; i < Pn; i++) dessin_carre (win, Px[i], Py[i]); /* Remplissage du polygone */ if (HeGetToggleValue(tog2)) { couleur (c_vert); remplissage (win); } } /*--------------------------------- M A I N ----------------------------------*/ int main (int argc, char **argv) { HeInit (&argc, &argv); init_couleurs (); princ = HeCreateFrame (); HeSetFrameLabel (princ, "Remplissage de polygones"); HeSetFrameResizeProc (princ, princ_resize_proc); panel1 = HeCreatePanel (princ); HeCreateButtonP (panel1, "Vider", vider_proc, NULL); tog1 = HeCreateToggleLedP (panel1, "Niveaux", reaffi_proc, FALSE); tog2 = HeCreateToggleLedP (panel1, "Remplir", reaffi_proc, FALSE); HeCreateButtonP (panel1, "Quit", quit_proc, NULL); HeFit (panel1); canvas = HeCreateCanvas (princ); HeSetCanvasResizeProc (canvas, canvas_resize_proc); HeSetCanvasRepaintProc (canvas, canvas_repaint_proc); HeSetCanvasEventProc (canvas, canvas_event_proc); HeSetWidth (canvas, 400); HeSetHeight (canvas, 400); HeJustify (canvas, panel1, HE_TOP); panel2 = HeCreatePanel (princ); HeJustify (panel2, canvas, HE_TOP); mess1 = HeCreateMessageP (panel2, "Sommets : ajoute, " "déplace (tirer souris), supprime (tirer dehors)", FALSE); HeFit (panel2); HeFit (princ); return HeMainLoop (princ); }