home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / diverses / leda / src / plane / _delauna.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-15  |  39.5 KB  |  1,507 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _delaunay_tree.c
  7. +
  8. +
  9. +  Copyright (c) 1991  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. /*****************************************************************************
  16. +
  17. +    Delaunay tree    by Olivier Devillers
  18. +
  19. +        Fully dynamic construction of the Delaunay triangulation with
  20. +        good randomized complexity
  21. +
  22. +    Copyright (c) 1990
  23. +    INRIA, 2004 route des Lucioles, 06 565 Valbonne Cedex, France
  24. +
  25. +
  26. ******************************************************************************/
  27.  
  28.  
  29. #include <LEDA/delaunay_tree.h>
  30.  
  31.  
  32. #define Fini        0
  33. #define Infini1     1        /* 1 point a l'infini */
  34. #define Infini2        2        /* 2 points a l'infini */
  35. #define Infini3        3        /* 3 points a l'infini, c'est la racine */
  36. #define Impossible    99        /* Le voisin du precedent */
  37. #define U 0                /* indices pour les trois sommets */
  38. #define V 1
  39. #define W 2
  40.  
  41.  
  42. /*****************************************************************************
  43.  
  44.             Declarations de type
  45.  
  46. ******************************************************************************/
  47.  
  48.  
  49. struct LISTENOEUD{
  50.     NOEUD *item;
  51.     LISTENOEUD *next;
  52. };
  53.  
  54.  
  55.  
  56. struct REINSERER {
  57.     DT_item    x;                /* a point devant etre reinserer */
  58.     NOEUD   *detruit1,            /* triangles a detruire si ils existent */
  59.         *detruit2;            /* NULL sinon xpx1 est direct et xpx2 indirect*/
  60.     listenoeud
  61.         decroches;            /* triangles decroches */
  62.     REINSERER
  63.         *finf,*fsup;        /* pour l'arbre binaire */
  64. };
  65.  
  66.  
  67.  
  68. struct STAR{
  69.     STAR
  70.             *next,*previous;/*arete suivante et precedente sur le polygone*/
  71.     NOEUD
  72.             *triangle;        /* triangle adjacent */
  73.     int        n,p,arete;        /*point suivant, precedent, arete dans le triangle*/
  74. };
  75.  
  76.  
  77.  
  78.  
  79. struct NOEUD{
  80.  
  81.     int        type;    /* le triangle est Fini ou Infini[123] 
  82.                    dans le cas d'un triangle infini, les sommets
  83.                    infinis sont la direction a` l'infini */
  84.     
  85.     int        degenere;  /* booleen, 3 pts alignes ? */
  86.     int        direct;       /* booleen, le triangle est-il direct ? */
  87.         int             stacked;
  88.     int        visite;       /* triangle marque visite si ce flag
  89.                           est le flag courant.
  90.                       pour la suppression le triangle est
  91.                                   marque si il appartient ou a
  92.                                   appartenu a A 
  93.                                 */
  94.     
  95.     int        detruire;   /* le triangle est a detruire si ce flag
  96.                        est le flag courant */
  97.     coord     cx,cy;            /* centre du cercle 
  98.                                           (uniqu^t pour tracer voronoi)*/
  99.     coord    a2,b2,a3,b3,c1,z0,z1,z2; /* pour les tests de conflit */
  100.     
  101.     DT_item    meurtrier; /* NULL si le triangle n'est pas mort */
  102.     DT_item    s[3];       /* sommets du triangle */
  103.                    /* U est le createur */
  104.                    /* si Infini1 alors W est a l'infini */
  105.                    /* si Infini2 alors V et W sont a l'infini */
  106.                    /* si Infini3 alors U,V et W sont a l'infini*/
  107.     NOEUD
  108.             *pere,        /* pere */
  109.             *bpere,        /* beau-pere */
  110.             *fils[3];    /* fils */
  111.     listenoeud
  112.             bfils;        /* liste des beaux-fils */
  113.     NOEUD
  114.             *voisin[3],    /* 3 voisins (courant ou a la mort) */
  115.             *creation[3],    /* 3 voisins a la creation */
  116.             *special[3];    /* 3 voisins speciaux! */
  117.     star    star[3];        /* pointeur reciproque vers Star */
  118.  
  119.  
  120. };
  121.  
  122. /*****************************************************************************
  123.  
  124.             Allocation memoire
  125.  
  126. ******************************************************************************/
  127.  
  128. #define SIZEALLOC 100
  129.  
  130.  
  131. char* delaunay_tree::alloc_block(int size)
  132. {
  133.    char* p =  (char*)malloc( size + sizeof(char*) ); 
  134.  
  135.    if (!p) error_handler(1,"out of memory");
  136.  
  137.    *((char**)p) = used_blocks;
  138.    used_blocks = p;
  139.  
  140.    return (used_blocks+sizeof(char*)) ; 
  141.  }
  142.  
  143.  
  144. void delaunay_tree::free_blocks()
  145. {
  146.   char* p;
  147.   while (used_blocks)
  148.   { p = used_blocks;
  149.     used_blocks = *((char**)used_blocks);
  150.     free(p);
  151.    }
  152. }
  153.  
  154. void delaunay_tree::poubelle_point(DT_item p)
  155. { p->cree = (noeud) Poubelle_point;
  156.   Poubelle_point = p;
  157. }
  158.  
  159. DT_item delaunay_tree::vrai_alloc_point()
  160. {
  161.  if ( ! item_nombre ) {
  162.         item_next = (DT_item) alloc_block( (item_nombre = SIZEALLOC) * sizeof(DT_POINT) ) ; 
  163.     }
  164.     item_nombre--;
  165.     return item_next++;
  166. }
  167.  
  168. DT_item delaunay_tree::alloc_point()
  169. {
  170.     if ( Poubelle_point ) { DT_item p = Poubelle_point;
  171.                 Poubelle_point = (DT_item) Poubelle_point->cree;
  172.                 return p;  }
  173.     return vrai_alloc_point();
  174. }
  175.  
  176.  
  177. void delaunay_tree::poubelle_listenoeud(listenoeud p)
  178. {
  179.   p->next =  Poubelle_listenoeud;
  180.   Poubelle_listenoeud = p;
  181. }
  182.  
  183. listenoeud delaunay_tree::vrai_alloc_listenoeud()
  184. {
  185.  if ( ! listenoeud_nombre ) {
  186.         listenoeud_next = (listenoeud) alloc_block((listenoeud_nombre = SIZEALLOC) * sizeof(LISTENOEUD) ) ; 
  187.     }
  188.     listenoeud_nombre--;
  189.     return listenoeud_next++;
  190. }
  191.  
  192. listenoeud delaunay_tree::alloc_listenoeud()
  193. {
  194.     if ( Poubelle_listenoeud ) 
  195.                               { listenoeud p = Poubelle_listenoeud;
  196.                     Poubelle_listenoeud = Poubelle_listenoeud->next;
  197.                 return p;  }
  198.     return vrai_alloc_listenoeud();
  199. }
  200.  
  201.  
  202. void delaunay_tree::poubelle_noeud(noeud p)
  203. /* on ne se resert que des noeud dont le champs detruire n'est pas flag */
  204.   p->fils[0] =  Poubelle_noeud;
  205.   Poubelle_noeud = p;
  206.   if (fl != p->detruire ) { fl = p->detruire; Libre_noeud = Poubelle_noeud ;}
  207. }
  208.  
  209. noeud delaunay_tree::vrai_alloc_noeud()
  210. {
  211.  if ( ! noeud_nombre ) {
  212.         noeud_next = (noeud) alloc_block((noeud_nombre = SIZEALLOC) * sizeof(NOEUD) ) ; 
  213.     }
  214.     noeud_nombre--;
  215.     return noeud_next++;
  216. }
  217.  
  218. noeud delaunay_tree::alloc_noeud()
  219. /* on ne se resert que des noeud dont le champs detruire n'est pas flag */
  220. {    
  221.     if (Libre_noeud && Libre_noeud->fils[0] )
  222.             { noeud p = Libre_noeud->fils[0];
  223.               Libre_noeud->fils[0] = Libre_noeud->fils[0]->fils[0];
  224.               return p;  }
  225.     return vrai_alloc_noeud();
  226. }
  227.  
  228.  
  229. void delaunay_tree::poubelle_star(star p)
  230. {
  231.   p->next =  Poubelle_star;
  232.   Poubelle_star = p;
  233. }
  234.  
  235. star delaunay_tree::vrai_alloc_star()
  236. {
  237.  if ( ! star_nombre ) {
  238.         star_next = (star) alloc_block((unsigned int) (star_nombre = SIZEALLOC) * sizeof(STAR) ) ; 
  239.     }
  240.     star_nombre--;
  241.     return star_next++;
  242. }
  243.  
  244.  
  245. star delaunay_tree::alloc_star()
  246. {
  247.     if ( Poubelle_star ) { star p = Poubelle_star;
  248.                    Poubelle_star = Poubelle_star->next;
  249.                    return p;  }
  250.     return vrai_alloc_star();
  251. }
  252.  
  253.  
  254. void delaunay_tree::poubelle_reinserer( reinserer p)
  255. {
  256.   p->finf =  Poubelle_reinserer;
  257.   Poubelle_reinserer = p;
  258. }
  259.  
  260. reinserer delaunay_tree::vrai_alloc_reinserer()
  261. {
  262.  if ( ! reinserer_nombre ) {
  263.         reinserer_next = (reinserer) alloc_block((reinserer_nombre = SIZEALLOC) * sizeof(REINSERER) ) ; 
  264.     }
  265.     reinserer_nombre--;
  266.     return reinserer_next++;
  267. }
  268.  
  269.  
  270. reinserer delaunay_tree::alloc_reinserer()
  271. {
  272.     if ( Poubelle_reinserer ) {reinserer p = Poubelle_reinserer;
  273.                       Poubelle_reinserer = Poubelle_reinserer->finf;
  274.                    return p;  }
  275.  
  276.     return vrai_alloc_reinserer();
  277. }
  278.  
  279. /*****************************************************************************
  280.  
  281.             Structure Reinsert
  282.  
  283. ******************************************************************************/
  284.  
  285. reinserer delaunay_tree::locate( reinserer n, DT_item x)
  286. {
  287.     reinserer nn;
  288.  
  289.     if ( ! Reinsert ) {
  290.         nn = alloc_reinserer();
  291.         nn->x = x;
  292.         nn->decroches = NULL;
  293.         nn->detruit1 = NULL;
  294.         nn->detruit2 = NULL;
  295.         nn->finf = NULL;
  296.         nn->fsup = NULL;
  297.         Reinsert = nn;
  298.      return nn;
  299.     }
  300.     if ( n->x == x) return n;
  301.     if ( x->n < n->x->n ) {
  302.         if (n->finf) return locate(n->finf,x);
  303.         nn = alloc_reinserer();
  304.         nn->x = x;
  305.         nn->decroches = NULL;
  306.         nn->detruit1 = NULL;
  307.         nn->detruit2 = NULL;
  308.         nn->finf = NULL;
  309.         nn->fsup = NULL;
  310.         n->finf = nn;
  311.     } else {
  312.         if (n->fsup) return locate(n->fsup,x);
  313.         nn = alloc_reinserer();
  314.         nn->x = x;
  315.         nn->decroches = NULL;
  316.         nn->detruit1 = NULL;
  317.         nn->detruit2 = NULL;
  318.         nn->finf = NULL;
  319.         nn->fsup = NULL;
  320.         n->fsup = nn;
  321.     }
  322.     return nn;
  323. }
  324.  
  325. void delaunay_tree::clear_Reinsert( reinserer n)
  326. {    listenoeud l,ll;
  327.     if ( ! Reinsert ) return;
  328.     if (n->finf) clear_Reinsert(n->finf);
  329.     if (n->fsup) clear_Reinsert(n->fsup);
  330.     for ( l = n->decroches; l; l = ll ) {ll = l->next; poubelle_listenoeud(l);}
  331.     poubelle_reinserer(n);
  332.     if ( n == Reinsert ) Reinsert = NULL;
  333. }
  334.  
  335. /*****************************************************************************
  336.  
  337.             Structure Star
  338.  
  339. ******************************************************************************/
  340.  
  341. void delaunay_tree::clear_Star()
  342. {
  343.     star s;
  344.  
  345.     if ( ! Star ) return;
  346.     for ( s = Star->next ; s != Star ;)
  347.                 {s = s->next; poubelle_star(s->previous);}
  348.     poubelle_star(Star);
  349.     Star = NULL;
  350. }
  351.  
  352. void delaunay_tree::init_Star( noeud n, int i, int j, int k)
  353. /* l'arete i,j de n est sur le bord de star */
  354. {
  355.     star s;
  356.  
  357.     if (! n) {
  358.         Star->next = first_star;
  359.         first_star->previous = Star;
  360.         first_star = NULL;
  361.         return;
  362.     }
  363.     s = alloc_star();
  364.     s->triangle = n;
  365.     s->p = i;
  366.     s->n = j;
  367.     s->arete = k;
  368.     n->star[k] = s ;
  369.     s->previous = Star;
  370.     if (! Star ) first_star = s;
  371.     else         Star->next = s;
  372.     Star = s;
  373. }
  374.  
  375. star delaunay_tree::loc_Star( DT_item xx)
  376. /* trouve l'arete telle que xx soit le point precedent */
  377. {
  378.     star s;
  379.  
  380.     s = Star;
  381.     while ( s->triangle->s[s->p] != xx ) s = s->next ;
  382.     return s;
  383. }
  384.  
  385. void delaunay_tree::split_Star( star n1,star n2)
  386. /* raccroche les n1 a n2 en viarant la partie intermediare */
  387. {
  388.     star s,ss;
  389.  
  390.     if (n1==n2) {
  391.         s = alloc_star();
  392.         s->previous = n1;
  393.         s->next = n1->next;
  394.         n1->next = s;
  395.         s->next->previous = s;
  396.         return;
  397.     }
  398.     for ( s = n1->next; s != n2 ; ){ss=s->next; poubelle_star(s); s=ss; }
  399.     n1->next = n2;
  400.     Star = n2->previous = n1;
  401. }
  402.  
  403. /*****************************************************************************
  404.  
  405.             Procedures
  406.  
  407. ******************************************************************************/
  408.  
  409. void delaunay_tree::beaufils( noeud bf, noeud bp)
  410. /* ajoute bf a la liste des beaufils de bp */
  411. {
  412.     listenoeud nov;
  413.  
  414.     nov = alloc_listenoeud();
  415.     nov->next = bp->bfils;
  416.     nov->item = bf;
  417.     bp->bfils = nov;
  418. }
  419.  
  420. void delaunay_tree::plusbeaufils( noeud bf, noeud bp)
  421. /* enleve bf a la liste des beaufils de bp */
  422. {
  423.     listenoeud n,nn;
  424.  
  425.     if ( bp->bfils->item == bf ) {
  426.         nn = bp->bfils;
  427.         bp->bfils = bp->bfils->next ;
  428.         poubelle_listenoeud(nn);
  429.         return;
  430.     }
  431.     for ( n = bp->bfils; n->next->item != bf; n = n->next );
  432.     nn = n->next ;
  433.     n->next = n->next->next ;
  434.     poubelle_listenoeud(nn);
  435. }
  436.  
  437. void delaunay_tree::demiplan( noeud t)
  438. /* calcul de la normale */
  439. {
  440.     t->type = Infini1;
  441.     t->degenere = 0;
  442.     if ( t->direct ) {
  443.             t->cx= t->s[U]->y - t->s[V]->y ;
  444.             t->cy= t->s[V]->x - t->s[U]->x ;
  445.     } else {
  446.             t->cx= t->s[V]->y - t->s[U]->y ;
  447.             t->cy= t->s[U]->x - t->s[V]->x ;
  448.     }
  449. }
  450.  
  451. void delaunay_tree::cercle( noeud t)
  452. {
  453.     register double a,b,c,d;
  454. /* calcul pour les tests de conflits */
  455.        t->a2 = t->s[1]->x - t->s[0]->x ;
  456.        t->b2 = t->s[1]->y - t->s[0]->y ;
  457.        t->a3 = t->s[2]->x - t->s[0]->x ;
  458.        t->b3 = t->s[2]->y - t->s[0]->y ;
  459.  
  460.        t->c1 = t->a2 * t->b3 - t->a3 * t->b2 ;
  461.        t->z1 = t->a2 * (t->s[1]->x + t->s[0]->x) + t->b2 * (t->s[1]->y+t->s[0]->y);
  462.        t->z2 = t->a3 * (t->s[2]->x + t->s[0]->x) + t->b3 * (t->s[2]->y+t->s[0]->y);
  463. /* calcul du centre et du rayon du cercle  */
  464.     a = t->s[U]->x * t->s[U]->x + t->s[U]->y * t->s[U]->y ;
  465.     b = t->s[V]->x * t->s[V]->x + t->s[V]->y * t->s[V]->y - a ;
  466.     c = t->s[W]->x * t->s[W]->x + t->s[W]->y * t->s[W]->y - a ;
  467.     d = 2*( (t->s[V]->x - t->s[U]->x) * (t->s[W]->y - t->s[U]->y)
  468.                 - (t->s[W]->x - t->s[U]->x) * (t->s[V]->y - t->s[U]->y));
  469.     if ( (t->degenere = (d==0) ) ) { 
  470.                         t->cx= t->pere->cx ;
  471.                         t->cy= t->pere->cy ;
  472.                     return;
  473.                 }
  474.     t->cx=(b*(t->s[W]->y - t->s[U]->y)-c*(t->s[V]->y - t->s[U]->y))/d;
  475.     t->cy=(c*(t->s[V]->x - t->s[U]->x)-b*(t->s[W]->x - t->s[U]->x))/d;
  476. }
  477.  
  478. int delaunay_tree::confondu( DT_item a, DT_item b)
  479. {
  480.     return ((a->x == b->x)&&(a->y==b->y));
  481. }
  482.  
  483. int delaunay_tree::direct( noeud n)
  484. /* teste si un triangle est direct */
  485. {
  486.     switch(n->type){
  487.     case Fini       : 
  488.         return ((n->s[V]->x - n->s[U]->x)*(n->s[W]->y - n->s[U]->y)
  489.                 - (n->s[V]->y - n->s[U]->y)*(n->s[W]->x - n->s[U]->x) > 0);
  490.     case Infini1     :
  491.         return ((n->s[V]->x - n->s[U]->x)*n->s[W]->y
  492.                 - (n->s[V]->y - n->s[U]->y)*n->s[W]->x > 0);
  493.     case Infini2     :
  494.         return (n->s[V]->x*n->s[W]->y - n->s[V]->y*n->s[W]->x > 0);
  495.     case Infini3     : return 1;
  496.     case Impossible  : return 1;
  497.     }
  498.     return 2;
  499. }
  500.  
  501. int delaunay_tree::conflit( noeud n, DT_item p)
  502. /* teste si un point est en conflit avec une region */
  503. {
  504.     register coord a1,c2,c3,z0;
  505.  
  506.     switch(n->type){
  507.     case Fini        :
  508.         a1 = p->x - n->s[0]->x ;
  509.         c3 = p->y - n->s[0]->y ;
  510.  
  511.         z0 = a1 * (p->x + n->s[0]->x) + c3 * (p->y + n->s[0]->y) ;
  512.      
  513.         c2 = n->a3 * c3 - a1 * n->b3 ;
  514.         c3 = a1 * n->b2 - n->a2 * c3 ;
  515.  
  516.     /********** Arithmetique double precision ************/
  517.     /* On utilise le fait que les flottants de l'accelerateur
  518.        flottant sont stockes avec une mantisse de 64 bits !!!
  519.            Pour faire du calcul entier juste, faite le en flottant !
  520.     */
  521.  
  522.     a1=(double)z0*(double)n->c1 + (double)n->z1*(double)c2 + (double)n->z2*(double)c3;
  523.         return (n->direct ? ( a1 <= 0.0)  : (a1 >= 0.0) );
  524.  
  525.     case Infini1    : 
  526.         return (n->direct)
  527.             ?    ( ( (p->x - n->s[U]->x)* (n->s[U]->y - n->s[V]->y)
  528.                     + (p->y - n->s[U]->y)* (n->s[V]->x - n->s[U]->x) ) >= 0 )
  529.             :    ( ( (p->x - n->s[U]->x)* (n->s[V]->y - n->s[U]->y)
  530.                     + (p->y - n->s[U]->y)* (n->s[U]->x - n->s[V]->x) ) >= 0 ) ;
  531.     case Infini2    :
  532.                 return ( (p->x - n->s[U]->x) * (n->s[V]->x + n->s[W]->x)
  533.                     +(p->y - n->s[U]->y) * (n->s[V]->y + n->s[W]->y) >= 0 );
  534.     case Infini3    : return 1;
  535.     case Impossible : return 0;
  536.     }
  537.     return 0;
  538. }
  539.  
  540.  
  541.  
  542. void delaunay_tree::clear()
  543. {
  544.   if (arbre != nouveau)
  545.   { flag++;
  546.     arbre->s[U]->visite = flag;
  547.     arbre->s[V]->visite = flag;
  548.     arbre->s[W]->visite = flag;
  549.     clear_items(nouveau);
  550.    }
  551.   free_blocks();
  552.   init();
  553. }
  554.  
  555. delaunay_tree::~delaunay_tree() { clear(); }
  556.  
  557. delaunay_tree::delaunay_tree()  { init(); }
  558.  
  559. void delaunay_tree::init()
  560. /* initialisation du Delaunay tree avec les trois points a l'infini */
  561. {
  562.         counter = 0;
  563.         flag=1; 
  564.         Star = NULL; 
  565.         Reinsert = NULL; 
  566.         Poubelle_noeud = Libre_noeud = NULL;
  567.  
  568.         used_blocks=NULL;
  569.         Poubelle_point=NULL;
  570.         Poubelle_listenoeud=NULL;
  571.         Poubelle_noeud=NULL;
  572.         Libre_noeud=NULL;
  573.         Poubelle_star=NULL;
  574.         Poubelle_reinserer=NULL;
  575.         fl = 0;
  576.         item_nombre = 0;
  577.         item_next = 0;
  578.         listenoeud_nombre = 0;
  579.         listenoeud_next = 0;
  580.         noeud_nombre = 0;
  581.         noeud_next = 0;
  582.         star_nombre = 0;
  583.         star_next = 0;
  584.         reinserer_nombre = 0;
  585.         reinserer_next = 0;
  586.         first_star=NULL;
  587.  
  588.  
  589.     arbre = alloc_noeud();
  590.     nouveau = arbre;
  591.  
  592.     arbre->type = Infini3;
  593.     arbre->degenere = 0;
  594.     arbre->visite = 0;
  595.     arbre->stacked = 0;
  596.     arbre->detruire = 0;
  597.     arbre->meurtrier = NULL;
  598.     arbre->fils[U] = arbre->fils[V] = arbre->fils[W] = NULL ;
  599.     arbre->bfils = NULL;
  600.     arbre->pere = NULL;
  601.     arbre->bpere = NULL;
  602.     arbre->voisin[U] =
  603.     arbre->voisin[V] =
  604.     arbre->voisin[W] =
  605.     arbre->creation[U] =
  606.     arbre->creation[V] =
  607.     arbre->creation[W] = alloc_noeud();
  608.     arbre->direct = 1;
  609.  
  610.     arbre->voisin[W]->visite = 0;
  611.     arbre->voisin[W]->stacked = 0;
  612.     arbre->voisin[W]->type = Impossible ;
  613.     arbre->voisin[W]->degenere = 0;
  614.     arbre->voisin[W]->meurtrier = NULL ;
  615.     arbre->voisin[W]->fils[U] = arbre->voisin[W]->fils[V] =
  616.                             arbre->voisin[W]->fils[W] = NULL ;
  617.     arbre->voisin[W]->bfils = NULL ;
  618.     arbre->voisin[W]->pere = NULL ;
  619.     arbre->voisin[W]->bpere = NULL ;
  620.     arbre->voisin[W]->voisin[U] =
  621.     arbre->voisin[W]->voisin[V] =
  622.     arbre->voisin[W]->voisin[W] =
  623.     arbre->voisin[W]->creation[U] =
  624.     arbre->voisin[W]->creation[V] =
  625.     arbre->voisin[W]->creation[W] = arbre ;
  626.     arbre->voisin[W]->direct = 0;
  627.  
  628.     arbre->s[U] = arbre->voisin[W]->s[U] = alloc_point();
  629.     arbre->s[V] = arbre->voisin[W]->s[V] = alloc_point();
  630.     arbre->s[W] = arbre->voisin[W]->s[W] = alloc_point();
  631.     arbre->s[U]->x =  2;
  632.     arbre->s[U]->y =  0;
  633.     arbre->s[V]->x = -1;
  634.     arbre->s[V]->y =  2;
  635.     arbre->s[W]->x = -1;
  636.     arbre->s[W]->y = -2;
  637.     arbre->s[U]->n = 0;
  638.     arbre->s[V]->n = 0;
  639.     arbre->s[W]->n = 0;
  640.  
  641. }
  642.  
  643. noeud delaunay_tree::Insert( noeud n, DT_item p)
  644. /* recherche d'un conflit */
  645. {
  646.     listenoeud l;
  647.     noeud nn;
  648.     int i;
  649.  
  650.     if ( flag != n->visite ) {
  651.      n->visite = flag;
  652.      if ( conflit(n,p)){
  653.         if ( n->meurtrier ) {
  654.             for (i=U; i<=W; i++) if ( n->fils[i] )
  655.                 if ( nn = Insert( n->fils[i], p) ) return nn ;
  656.         } else return n ;
  657.         for ( l = n->bfils; l ; l = l->next )
  658.                 if ( nn = Insert( l->item, p) ) return nn ;
  659.      }
  660.     }
  661.     return NULL ;
  662. }
  663.  
  664. noeud delaunay_tree::creenoeud( noeud pere, int i, DT_item p)
  665. {
  666.                 nouveau = pere->fils[i] = alloc_noeud();
  667.                 beaufils(nouveau, pere->voisin[i] );
  668.                 nouveau->visite = flag;
  669.                 nouveau->stacked = flag;
  670.                 nouveau->detruire = 0;
  671.                 nouveau->meurtrier = NULL;
  672.                 nouveau->fils[U] = nouveau->fils[V] = nouveau->fils[W] = NULL ;
  673.                 nouveau->bfils = NULL;
  674.                 nouveau->s[U]=p;                    /* createur */
  675.                 switch(i){
  676.                 case U: nouveau->direct = pere->direct;
  677.                         nouveau->s[V]= pere->s[V];
  678.                         nouveau->s[W]= pere->s[W]; break;
  679.                 case V: nouveau->direct = ! pere->direct;
  680.                         nouveau->s[V]= pere->s[U];
  681.                         nouveau->s[W]= pere->s[W]; break;
  682.                 case W: nouveau->direct = pere->direct;
  683.                         nouveau->s[V]= pere->s[U];
  684.                         nouveau->s[W]= pere->s[V]; break;
  685.                 }
  686.                 nouveau->pere = pere;
  687.                 nouveau->bpere =
  688.                 nouveau->voisin[U] =
  689.                 nouveau->creation[U] = pere->voisin[i];
  690.                                         /* nouveau est-il fini ou infini */
  691.                 switch ( pere->type ) {
  692.                 case Fini       :
  693.                     cercle(nouveau);
  694.                     nouveau->type = Fini; break;
  695.                 case Infini1    :
  696.                     switch (i) {
  697.                     case U: 
  698.                     case V: demiplan(nouveau); nouveau->type = Infini1;
  699.                             nouveau->degenere = 0; break;
  700.                     case W: cercle(nouveau); nouveau->type = Fini; break;
  701.                     }break;
  702.                 case Infini2    :
  703.                     switch (i) {
  704.                     case U: nouveau->type = Infini2;
  705.                             nouveau->degenere = 0;break; 
  706.                     case V:
  707.                     case W: nouveau->type = Infini1; demiplan(nouveau);
  708.                             nouveau->degenere = 0;break; 
  709.                     }break;
  710.                 case Infini3    : nouveau->type = Infini2;
  711.                                     nouveau->degenere = 0;break; 
  712.                 case Impossible : break;
  713.                 }
  714.     return nouveau;
  715. }
  716.  
  717. int delaunay_tree::creation( noeud detruit, DT_item p)
  718. /* creation eventuelle des nouveaux noeuds et des liens et des voisinages*/
  719. {
  720.     DT_item first= NULL;
  721.     noeud n1,father;
  722.     int arete;        /* indice sur n1 de l'arete axe-createur */ 
  723.     int a,b,c;        /* indice des trois sommets sur father */
  724.     int a1,b1,c1;    /* indice des trois sommets sur le noeud precedent */
  725.     int j;
  726.  
  727.     if ( ! detruit)
  728.                     return 0;
  729.         for (j=U; j<= W - detruit->type; j++) if (confondu(p,detruit->s[j]))
  730.                                     return 0;
  731.         detruit->meurtrier = p;
  732.         a = U; b = V; c = W;
  733.         while (     detruit->voisin[c]->meurtrier
  734.                 ||    conflit ( detruit->voisin[c],p)         ){
  735.             detruit->voisin[c]->meurtrier = p;
  736.             a1 = a; b1 = b; c1 = c;
  737.             for (j=U; j<=W; j++)
  738.                 if (detruit->voisin[c1]->s[j] == detruit->s[a1])        a=j ;
  739.                 else if (detruit->voisin[c1]->s[j] == detruit->s[b1])    c=j ;
  740.                 else                                                    b=j;
  741.             detruit = detruit->voisin[c1] ;
  742.         }
  743.                 p->cree = n1 = creenoeud(detruit,c,p);
  744.                 /* n1 remplace pere comme voisin de son beau-pere*/
  745.                 for (j=U; j<=W; j++)
  746.                     if (    (detruit->voisin[c]->s[j] != n1->s[V])
  747.                         &&    (detruit->voisin[c]->s[j] != n1->s[W])) break;
  748.                 detruit->voisin[c]->voisin[j] = n1 ;
  749.                 switch (c) {
  750.                     case U : first = detruit->s[a=(detruit->direct) ? W : V ];
  751.                                     break;
  752.                     case V : first = detruit->s[a=(detruit->direct) ? U : W ];
  753.                                     break;
  754.                     case W : first = detruit->s[a=(detruit->direct) ? V : U ];
  755.                                     break;
  756.                 }
  757.                 b = c; c = U+V+W -b -a ;
  758.                 father = detruit;
  759.                 arete =  (n1->direct) ? V : W ;
  760.     do {
  761.                 /* ac est l'arete par laquelle n1 est fils de father */
  762.                 /* on veut tourner autour de a en faisant bouger c vers b */
  763.                 /* i e on tourne dans le sens direct */
  764.         while (     father->voisin[c]->meurtrier
  765.                 ||    conflit ( father->voisin[c],p)         ){
  766.             father->voisin[c]->meurtrier = p;
  767.             a1 = a; b1 = b; c1 = c;
  768.             for (j=U; j<=W; j++)
  769.                 if (father->voisin[c1]->s[j] == father->s[a1])            a=j ;
  770.                 else if (father->voisin[c1]->s[j] == father->s[b1])        c=j ;
  771.                 else                                                    b=j;
  772.             father = father->voisin[c1] ;
  773.         }
  774.         if (father->fils[c])
  775.                 n1->creation[arete] = n1->voisin[arete] = father->fils[c] ;
  776.         else {  n1->creation[arete] = n1->voisin[arete] = creenoeud(father,c,p);
  777.                 /* le nouveau remplace pere comme voisin de son beau-pere*/
  778.                 for (j=U; j<=W; j++)
  779.                     if (    (father->voisin[c]->s[j] != father->fils[c]->s[V])
  780.                         &&    (father->voisin[c]->s[j] != father->fils[c]->s[W]))
  781.                                                                         break;
  782.                 father->voisin[c]->voisin[j] = father->fils[c] ;
  783.         }
  784.         arete =  (father->fils[c]->direct) ? V : W ;
  785.         father->fils[c]->creation[V+W-arete] =
  786.                         father->fils[c]->voisin[V+W-arete] = n1 ;
  787.         n1 = father->fils[c] ;
  788.         j = a ;
  789.         a = b ;
  790.         b = c ;
  791.         c = j ;
  792.     } while ( father->s[a] != first );
  793.     return 1;
  794. }
  795.  
  796. DT_item delaunay_tree::localise( noeud detecte, DT_item p)
  797. /* determination du plus proche voisin */
  798. {
  799.     DT_item first= NULL,trouve = NULL;
  800.     coord dist, distance = 10000000.0;
  801.     noeud father;
  802.     int a,b,c;        /* indice des trois sommets sur father */
  803.     int a1,b1,c1;    /* indice des trois sommets sur le noeud precedent */
  804.     int j;
  805.  
  806.     if (!detecte)
  807.                     return NULL;
  808.  
  809.         for (j=U; j<= W - detecte->type; j++) if (confondu(p,detecte->s[j]))
  810.                                     return detecte->s[j];
  811.         detecte->visite = flag++ ;
  812.         a = U; b = V; c = W;
  813.         while (     ( detecte->voisin[c]->visite == flag )
  814.                 ||    conflit ( detecte->voisin[c],p)         ){
  815.             detecte->voisin[c]->visite = flag;
  816.             a1 = a; b1 = b; c1 = c;
  817.             for (j=U; j<=W; j++)
  818.                 if (detecte->voisin[c1]->s[j] == detecte->s[a1])        a=j ;
  819.                 else if (detecte->voisin[c1]->s[j] == detecte->s[b1])    c=j ;
  820.                 else                                                    b=j;
  821.             detecte = detecte->voisin[c1] ;
  822.         }
  823.                 switch (c) {
  824.                     case U : first = detecte->s[a=(detecte->direct) ? W : V ];
  825.                                     break;
  826.                     case V : first = detecte->s[a=(detecte->direct) ? U : W ];
  827.                                     break;
  828.                     case W : first = detecte->s[a=(detecte->direct) ? V : U ];
  829.                                     break;
  830.                 }
  831.                 b = c; c = U+V+W -b -a ;
  832.                 father = detecte;
  833.     do {
  834.                 /* on veut tourner autour de a en faisant bouger c vers b */
  835.                 /* i e on tourne dans le sens direct */
  836.         while (     ( father->voisin[c]->visite == flag )
  837.                 ||    conflit ( father->voisin[c],p)         ){
  838.             father->voisin[c]->visite = flag;
  839.             a1 = a; b1 = b; c1 = c;
  840.             for (j=U; j<=W; j++)
  841.                 if (father->voisin[c1]->s[j] == father->s[a1])            a=j ;
  842.                 else if (father->voisin[c1]->s[j] == father->s[b1])        c=j ;
  843.                 else                                                    b=j;
  844.             father = father->voisin[c1] ;
  845.         }
  846.         if (father->s[a]->n) {
  847.             dist = (p->x - father->s[a]->x) * (p->x - father->s[a]->x) +
  848.                     (p->y - father->s[a]->y) * (p->y - father->s[a]->y)    ;
  849.             if (dist < distance) { distance = dist; trouve = father->s[a]; }
  850.         }
  851.         j = a ;
  852.         a = b ;
  853.         b = c ;
  854.         c = j ;
  855.     } while ( father->s[a] != first );
  856.     return trouve;
  857. }
  858.  
  859. void delaunay_tree::add_x1x2( reinserer r, noeud v, DT_item p)
  860. /* ajoute v a comme triangle detruit de r */
  861. {
  862.     if ( v->direct )
  863.                      if  (p==v->s[V]) r->detruit1 = v;
  864.                      else              r->detruit2 = v;
  865.     else            
  866.                      if  (p==v->s[W]) r->detruit1 = v;
  867.                      else              r->detruit2 = v;
  868. }
  869.  
  870. void delaunay_tree::add_decroche( reinserer r, noeud v)
  871. /* ajoute v a la liste des decroches de r */
  872. {
  873.     listenoeud nov;
  874.  
  875.     nov = alloc_listenoeud();
  876.     nov->next = r->decroches;
  877.     nov->item = v;
  878.     r->decroches = nov;
  879. }
  880.  
  881. void delaunay_tree::destroy( noeud u, DT_item p)
  882. /* recherche recursive pour initialisation de Reinsert */
  883. {
  884.     int i;
  885.     listenoeud l;
  886.     reinserer rr;
  887.  
  888.     if ( ! u ) return;
  889.     if (u->detruire == flag) return;
  890.     for ( i=U ; i<=W; i++ ) if (u->s[i]==p) break;
  891.     if ( i<=W ) {
  892.         u->detruire = flag;
  893.         if (u->meurtrier)
  894.             for ( i=U ; i<=W; i++ ) if (u->fils[i]) destroy(u->fils[i], p);
  895.         for ( l=u->bfils; l; l = l->next )      destroy(l->item   , p);
  896.         if (u->s[U]==p) return;
  897.         rr = locate(Reinsert,u->s[U]);
  898.         add_x1x2(rr,u,p);
  899.     } else {
  900.         rr = locate(Reinsert,u->s[U]);
  901.         add_decroche(rr,u);
  902.         if (u->pere->detruire == flag)    u->pere        = NULL;
  903.         else                            u->bpere    = NULL;
  904.     }
  905. }
  906.  
  907. void delaunay_tree::recherche( DT_item p)
  908. /* init des structures Star et Reinsert */
  909. {
  910.     DT_item first;
  911.     noeud father;
  912.     int arete;        /* indice sur n1 de l'arete axe-createur */ 
  913.     int a,b,c;        /* indice des trois sommets sur father */
  914.     int a1,b1,c1;    /* indice des trois sommets sur le noeud precedent */
  915.     int j;
  916.  
  917.     clear_Reinsert(Reinsert); 
  918.     clear_Star();
  919.         arete = (  p->cree->direct  ) ? V : W ;
  920.         first = p->cree->s[V + W - arete ];
  921.         father = p->cree->pere;
  922.         for (j=U; j<=W; j++)
  923.             if (father->s[j] == p->cree->s[V + W - arete ])        a=j ;
  924.             else if (father->s[j] == p->cree->s[arete])            c=j ;
  925.             else                                b=j;
  926.     do {
  927.                 /* ac est l'arete par laquelle on est fils de father */
  928.                 /* on veut tourner autour de a en faisant bouger c vers b */
  929.                 /* et que on tourne autour de a dans le sens inverse */
  930.         while ( ( father->voisin[c]->meurtrier == p )
  931.                 || (father->voisin[c]->visite == flag) ) {
  932.             a1 = a; b1 = b; c1 = c;
  933.             for (j=U; j<=W; j++)
  934.                 if (father->voisin[c1]->s[j] == father->s[a1])            a=j ;
  935.                 else if (father->voisin[c1]->s[j] == father->s[b1])        c=j ;
  936.                 else                                                    b=j;
  937.             father = father->voisin[c1] ;
  938.             father->visite = flag ;
  939.             father->meurtrier = NULL;
  940.         }
  941.         father->visite = flag ;
  942.         father->meurtrier = NULL;
  943.         a1 = a; b1 = b; c1 = c;
  944.         for (j=U; j<=W; j++)
  945.                 if (father->voisin[c1]->s[j] == father->s[a1])            a=j ;
  946.                 else if (father->voisin[c1]->s[j] == father->s[b1])        c=j ;
  947.                 else                                                    b=j;
  948.         father->voisin[c1]->special[b] = father;
  949.         if ( father->voisin[c1]->voisin[b]->s[U] == p )
  950.                                 father->voisin[c1]->voisin[b] = father;
  951.         plusbeaufils(father->fils[c1], father->voisin[c1] );
  952.         destroy(father->fils[c1],p);
  953.         poubelle_noeud(father->fils[c1]);
  954.         father->fils[c1] = NULL;
  955.         init_Star(father,a1,b1,c1);
  956.         a = b1 ;
  957.         b = c1 ;
  958.         c = a1 ;
  959.     } while ( father->s[a] != first );
  960.     init_Star( (noeud) NULL, 0, 0, 0);
  961. }
  962.  
  963. void delaunay_tree::reinsertion( reinserer n, DT_item p)
  964. {
  965.     listenoeud l;
  966.     noeud u,v,w,ww,w1,w2;
  967.     DT_item x1,x2;
  968.     int i,j,k,a,b,c,a1,b1,c1;
  969.     star s1,s2;
  970.  
  971.     /* traitement des noeuds decroches */
  972.     for ( l=n->decroches; l; l = l->next )
  973.         if ( l->item->pere ) {
  974.         /* il faut trouver un nouveau beau-pere et tous les voisinages 
  975.                    par cette arete */
  976.             u = l->item->pere;
  977.             for( i=U; i<=W; i++) if (u->fils[i] == l->item) break;
  978.             l->item->bpere = u->special[i];
  979.             l->item->creation[U] = u->special[i];
  980.             l->item->special[U] = u->special[i];
  981.             if ( l->item->voisin[U]->detruire == flag )
  982.                                 l->item->voisin[U] = u->special[i];
  983.             beaufils(l->item, u->special[i]);
  984.             for( j=U; j<=W; j++)
  985.                 if (    (l->item->bpere->s[j] != l->item->s[V] )
  986.                     &&    (l->item->bpere->s[j] != l->item->s[W] ) ) break;
  987.             l->item->bpere->voisin[j] = l->item;
  988.         } else {
  989.         /* il faut trouver un nouveau pere */
  990.             u = l->item->bpere;
  991.             for( i=U; i<=W; i++) if (u->s[i] == l->item->s[V]) break;
  992.             for( j=U; j<=W; j++) if (u->s[j] == l->item->s[W]) break;
  993.             i = U+V+W -i -j;
  994.             u= l->item->pere = u->special[i];
  995.             for( i=U; i<=W; i++) if (u->s[i] == l->item->s[V]) break;
  996.             for( j=U; j<=W; j++) if (u->s[j] == l->item->s[W]) break;
  997.             i = U+V+W -i -j;
  998.             u->fils[i] = l->item;
  999.         }
  1000.     /* traitement des noeuds detruits */
  1001.     if ( ! n->detruit1 ) return;
  1002.     x1 =  ( n->detruit1->s[V] == p ) ? n->detruit1->s[W] : n->detruit1->s[V];
  1003.     x2 =  ( n->detruit2->s[V] == p ) ? n->detruit2->s[W] : n->detruit2->s[V];
  1004.     s1 = loc_Star(x1);
  1005.     s2 = loc_Star(x2)->previous ;
  1006.     u = s1->triangle;
  1007.     /* Cas 1 (triangle x x1 x2 a creer) u n'est pas en conflit avec x */
  1008.     if ( ! conflit(u, n->x) ) {
  1009.             /* u est le beau pere de x x1 x2 a cree */
  1010.             for( i=U; i<=W; i++) if (u->s[i] == x1) break;
  1011.             for( j=U; j<=W; j++) if (u->s[j] == x2) break;
  1012.             k = U+V+W -i -j;
  1013.             u = u->voisin[k] ;
  1014.             /* u est le pere */
  1015.             for( i=U; i<=W; i++) if (u->s[i] == x1) break;
  1016.             for( j=U; j<=W; j++) if (u->s[j] == x2) break;
  1017.             i = U+V+W -i -j;
  1018.             n->x->cree =ww = creenoeud(u ,i,n->x);
  1019.         /* ww est le fils de son pere */
  1020.             u->voisin[i] = ww->bpere;        /* voisin a la mort */
  1021.         /* voisinage beau-fils beau-pere */
  1022.             ww->bpere->voisin[k] = ww;
  1023.         /* voisinage avec les "freres" du nouveau */
  1024.             i = ( ww->s[V] == x1 ) ? V : W ;
  1025.             u = n->detruit2->creation[(n->detruit2->s[V]==p)?V:W] ;
  1026.             ww->voisin[i] = ww->creation[i] = u;
  1027.             for( j=U; j<=W; j++) if ( u->creation[j] == n->detruit2 ) break;
  1028.             u->creation[j] = u->special[j] = ww ;
  1029.             if ( u->voisin[j]->detruire == flag ) u->voisin[j] = ww ;
  1030.             if ( u->voisin[j]->visite == flag ) u->voisin[j] = ww ;
  1031.             u = n->detruit1->creation[(n->detruit1->s[V]==p)?V:W] ;
  1032.             ww->voisin[V+W-i] = ww->creation[V+W-i] = u;
  1033.             for( j=U; j<=W; j++) if ( u->creation[j] == n->detruit1 ) break;
  1034.             u->creation[j] = u->special[j] = ww ;
  1035.             if ( u->voisin[j]->detruire == flag ) u->voisin[j] = ww ;
  1036.             if ( u->voisin[j]->visite == flag ) u->voisin[j] = ww ;
  1037.         /* mise a jour de Star */
  1038.             poubelle_noeud(n->detruit1);
  1039.             poubelle_noeud(n->detruit2);
  1040.             split_Star(s1,s2); s2=s1->next;
  1041.             s1->triangle = ww;
  1042.             s2->triangle = ww;
  1043.             for( i=U; i<=W; i++) if (ww->s[i] == x1)    s1->p = s2->arete = i;
  1044.                         else     if (ww->s[i] == n->x ) s1->n = s2->p = i;
  1045.                         else                           s1->arete = s2->n = i;
  1046.             ww->star[s1->arete] = s1;
  1047.             ww->star[s2->arete] = s2;
  1048.     return;
  1049.     }
  1050.     /* Cas 2  */
  1051.     v = u; w1=NULL;
  1052.     w = n->detruit1->creation[(n->detruit1->s[V]==p)?V:W] ;
  1053.     a = s1->p ;
  1054.     c = s1->n ;
  1055.     b = s1->arete ;
  1056.     do {
  1057.     /* on tourne dans le sens inverse */
  1058.         while ( conflit( v->voisin[c], n->x ) ) {
  1059.             a1 = a; b1 = b; c1 = c;
  1060.             for (j=U; j<=W; j++) if ( v->voisin[c1]->s[j] == v->s[a1]) a = j;
  1061.                         else     if ( v->voisin[c1]->s[j] == v->s[b1]) c = j;
  1062.                         else                                           b = j;
  1063.             v = v->voisin[c1];
  1064.             v->meurtrier = n->x;
  1065.         }
  1066.             v->meurtrier = n->x;
  1067.             ww = creenoeud(v,c,n->x);
  1068.         /* voisinage beau-fils beau-pere */
  1069.             for (j=U; j<=W; j++)
  1070.                     if (    ( ww->bpere->s[j] != ww->s[V] )
  1071.                         &&    ( ww->bpere->s[j] != ww->s[W] ) ) break;
  1072.             if ( ww->bpere->visite == flag ){ /* le beau-pere est dans A */
  1073.                 ww->bpere->voisin[j] = ww;
  1074.             } else {
  1075.                 ww->bpere->special[j] = ww;
  1076.                 if ( ww->bpere->voisin[j]->detruire == flag )
  1077.                                                 ww->bpere->voisin[j] = ww ;
  1078.                 if ( ww->bpere->voisin[j]->visite == flag )
  1079.                                                 ww->bpere->voisin[j] = ww ;
  1080.             }
  1081.         /* voisinage nouvelle arete */
  1082.             for (j=U;j<=W;j++) if((ww->s[j]!=n->x)&&(ww->s[j]!=v->s[a]))break;
  1083.             ww->voisin[j] = ww->creation[j] = w ;
  1084.             if ( !w1 ) {
  1085.               for (j=U;j<=W;j++) if((w->s[j]!=n->x)&&(w->s[j]!=v->s[a]))break;
  1086.               w1 = w->special[j] = w->creation[j] = ww ;
  1087.               if (w->voisin[j]->visite == flag ) w->voisin[j] = ww ;
  1088.               if (w->voisin[j]->detruire == flag ) w->voisin[j] = ww ;
  1089.             } else {
  1090.               for (j=U;j<=W;j++) if((w->s[j]!=n->x)&&(w->s[j]!=v->s[a]))break;
  1091.               w->voisin[j] = w->creation[j] = ww ;
  1092.             }
  1093.             w = ww;
  1094.         /* mise a jour de Star */
  1095.             if ( ww->bpere->visite != flag ){/* le beau-pere n'est pas dans A */
  1096.                 v->star[c]->triangle = ww;
  1097.                 ww->star[U] = v->star[c];
  1098.                 ww->star[U]->arete = U;
  1099.                 ww->star[U]->n = (v->s[a] == w->s[V] ) ? V : W ;
  1100.                 ww->star[U]->p = V+W-ww->star[U]->n ;
  1101.             }
  1102.         j = a ; a = b ; b = c ; c = j ;
  1103.     } while ( v->s[a] != x2) ; 
  1104.         /* voisinage autour de x x2 */
  1105.             n->x->cree = w2 = w;
  1106.             ww = n->detruit2->creation[(n->detruit2->s[V]==p)?V:W] ;
  1107.             for (j=U; j<=W; j++) if((ww->s[j]!=n->x)&&(ww->s[j]!=v->s[a]))break;
  1108.             if (ww->voisin[j]->visite == flag ) ww->voisin[j] = w ;
  1109.             if (ww->voisin[j]->detruire == flag ) ww->voisin[j] = w ;
  1110.             ww->creation[j] = ww->special[j] = w ;
  1111.             for (j=U; j<=W; j++) if((w->s[j]!=n->x)&&(w->s[j]!=v->s[a]))break;
  1112.             w->voisin[j] = w->creation[j] = ww ;
  1113.     do {
  1114.     /* on tourne toujours dans le sens inverse */
  1115.         while ( conflit( v->voisin[c], n->x ) ) {
  1116.             a1 = a; b1 = b; c1 = c;
  1117.             for (j=U; j<=W; j++) if ( v->voisin[c1]->s[j] == v->s[a1]) a = j;
  1118.                         else     if ( v->voisin[c1]->s[j] == v->s[b1]) c = j;
  1119.                         else                                           b = j;
  1120.             v = v->voisin[c1];
  1121.             v->meurtrier = n->x;
  1122.         }
  1123.             v->meurtrier = n->x;
  1124.         j = a ; a = b ; b = c ; c = j ;
  1125.     } while ( v->s[a] != x1) ; 
  1126.         /* mise a jour de Star */
  1127.             split_Star(s1,s2); s2=s1->next;
  1128.             s1->triangle = w1;
  1129.             s2->triangle = w2;
  1130.             poubelle_noeud(n->detruit1);
  1131.             poubelle_noeud(n->detruit2);
  1132.             for( i=U; i<=W; i++) if (w1->s[i] == x1)    s1->p = i;
  1133.                         else     if (w1->s[i] == n->x ) s1->n = i;
  1134.                         else                            s1->arete = i;
  1135.             w1->star[s1->arete] = s1;
  1136.             for( i=U; i<=W; i++) if (w2->s[i] == x2)    s2->n = i;
  1137.                         else     if (w2->s[i] == n->x ) s2->p = i;
  1138.                         else                            s2->arete = i;
  1139.             w2->star[s2->arete] = s2;
  1140. }
  1141.  
  1142. void delaunay_tree::parcours( reinserer n, DT_item p)
  1143. {
  1144.     if ( ! n ) return;
  1145.     parcours(n->finf,p);
  1146.     reinsertion(n,p);
  1147.     parcours(n->fsup,p);
  1148. }
  1149.  
  1150.  
  1151. void delaunay_tree::trace_items(noeud n, delaunay_f2* trace_item)
  1152. /* exploration recursive pour le trace des points */
  1153. {
  1154.   noeud* stack = new noeud[counter+10];
  1155.   int top = 0;
  1156.   stack[0] = n;
  1157.   n->stacked = flag;
  1158.  
  1159.   while (top >= 0)
  1160.   { n = stack[top--];   //pop
  1161.     n->visite = flag;
  1162.     for (int i=U; i<=W; i++)
  1163.       if ( n->s[i] && n->s[i]->visite != flag )
  1164.             { n->s[i]->visite = flag ;
  1165.               trace_item(n->s[i]->x, n->s[i]->y);
  1166.              }
  1167.  
  1168.     for (i=W; i>=U; i--)
  1169.         { noeud v = n->voisin[i];
  1170.       if ( v->stacked != flag )
  1171.            { stack[++top] = v;          //push
  1172.              v->stacked = flag;
  1173.             }
  1174.          }
  1175.  
  1176.    } // while stack not empty
  1177.  
  1178.  delete stack;
  1179.  
  1180. }
  1181.  
  1182. void delaunay_tree::list_items(noeud n, list(DT_item)& L)
  1183. /* exploration recursive pour le trace des points */
  1184. {
  1185.   noeud* stack = new noeud[counter+10];
  1186.   int top = 0;
  1187.   stack[0] = n;
  1188.   n->stacked = flag;
  1189.  
  1190.   while (top >= 0)
  1191.   { n = stack[top--];   //pop
  1192.     n->visite = flag;
  1193.     for (int i=U; i<=W; i++)
  1194.       if ( n->s[i] && n->s[i]->visite != flag )
  1195.             { n->s[i]->visite = flag ;
  1196.               L.append(n->s[i]);
  1197.              }
  1198.  
  1199.     for (i=W; i>=U; i--)
  1200.         { noeud v = n->voisin[i];
  1201.       if ( v->stacked != flag )
  1202.            { stack[++top] = v;          //push
  1203.              v->stacked = flag;
  1204.             }
  1205.          }
  1206.  
  1207.    } // while stack not empty
  1208.  
  1209.  delete stack;
  1210.  
  1211. }
  1212.  
  1213. void delaunay_tree::clear_items(noeud n)
  1214. {
  1215.   noeud* stack = new noeud[counter+10];
  1216.   int top = 0;
  1217.   stack[0] = n;
  1218.   n->stacked = flag;
  1219.  
  1220.   while (top >= 0)
  1221.   { n = stack[top--];   //pop
  1222.     n->visite = flag;
  1223.     for (int i=U; i<=W; i++)
  1224.       if ( n->s[i] && n->s[i]->visite != flag )
  1225.             { n->s[i]->visite = flag ;
  1226.               clear_inf(n->s[i]->i);
  1227.              }
  1228.  
  1229.     for (i=W; i>=U; i--)
  1230.         { noeud v = n->voisin[i];
  1231.       if ( v->stacked != flag )
  1232.            { stack[++top] = v;          //push
  1233.              v->stacked = flag;
  1234.             }
  1235.          }
  1236.  
  1237.    } // while stack not empty
  1238.  
  1239.  delete stack;
  1240. }
  1241.  
  1242.  
  1243. void delaunay_tree::del_noeud( noeud n, delaunay_f4* trace_segment,int both)
  1244. /* exploration recursive de delaunay_tree */
  1245. {
  1246.   noeud* stack = new noeud[counter+10];
  1247.   int top = 0;
  1248.   stack[0] = n;
  1249.   n->stacked = flag;
  1250.  
  1251.   int i;
  1252.  
  1253.   while (top >= 0)
  1254.   { n = stack[top--];   //pop
  1255.  
  1256.     n->visite = flag;
  1257.  
  1258.     for (i=U; i<=W; i++)
  1259.           if ( both || n->voisin[i]->visite != flag ) 
  1260.            { int j = (i==U) ? V : U ; 
  1261.              int k = U + V + W -i -j ;
  1262.          if (( n->type == Fini ) || ((i == W) && (n->type==Infini1) ) )
  1263.                 trace_segment(n->s[j]->x,n->s[j]->y, n->s[k]->x, n->s[k]->y);
  1264.         }
  1265.  
  1266.     for (i=W; i>=U; i--)
  1267.         { noeud v = n->voisin[i];
  1268.       if ( v->stacked != flag )
  1269.            { stack[++top] = v;          //push
  1270.              v->stacked = flag;
  1271.             }
  1272.          }
  1273.  
  1274.    } // while stack not empty
  1275.  
  1276.  delete stack;
  1277.  
  1278.  }
  1279.  
  1280.  
  1281. void delaunay_tree::vor( noeud n, delaunay_f6* trace_segment, delaunay_F6* pt_infi, int both)
  1282. {
  1283.  
  1284.   int i,j;
  1285.   coord x,y,mx,my;
  1286.   int order[3];
  1287.  
  1288.   int top = 0;
  1289.   noeud* stack = new noeud[counter+10];
  1290.   stack[0] = n;
  1291.   n->stacked = flag;
  1292.  
  1293.   while (top >= 0)
  1294.   { 
  1295.     n = stack[top--];   //pop
  1296.  
  1297.     n->visite = flag;
  1298.  
  1299.         if (n->direct)
  1300.          { order[0] = 0;
  1301.            order[1] = 1;
  1302.            order[2] = 2;
  1303.           }
  1304.         else 
  1305.          { order[0] = 2;
  1306.            order[1] = 1;
  1307.            order[2] = 0;
  1308.           }
  1309.  
  1310.     for (j=0; j<3; j++)
  1311.         { 
  1312.           int i = order[j];
  1313.  
  1314.                if (both ||  n->voisin[i]->visite != flag )
  1315.         {   int k;
  1316.                     if (n->direct)
  1317.                        k = (i==2) ? 0 : i+1; 
  1318.                     else 
  1319.                        k = (i==0) ? 2 : i-1; 
  1320.  
  1321.             coord sx0 = n->s[k]->x;
  1322.                     coord sy0 = n->s[k]->y;
  1323.  
  1324.             switch (n->type){
  1325.             case Fini :
  1326.             if (! n->degenere ) {
  1327.                 switch ( n->voisin[i]->type ){
  1328.                 case Fini : if ( ! n->voisin[i]->degenere ){
  1329. trace_segment(n->cx,n->cy, n->voisin[i]->cx, n->voisin[i]->cy,sx0,sy0); 
  1330.                                             break;
  1331.                 }
  1332.                 case Infini1  : 
  1333.                   pt_infi(n->cx,n->cy, n->voisin[i]->cx, n->voisin[i]->cy,&x,&y);
  1334.                                   trace_segment(n->cx, n->cy,x,y,sx0,sy0);
  1335.                   break ;
  1336.                 }
  1337.                 break;
  1338.             }
  1339.             case Infini1  :
  1340.                 if ( n->degenere &&  n->voisin[i]->degenere ) break;
  1341.                 switch ( n->voisin[i]->type ){
  1342.                 case Fini :
  1343.                 if ( ! n->voisin[i]->degenere ) 
  1344.                                 { pt_infi(n->voisin[i]->cx, 
  1345.                                           n->voisin[i]->cy, 
  1346.                                           n->cx,n->cy,&x,&y);
  1347.                                   trace_segment(x,y,
  1348.                                                 n->voisin[i]->cx, 
  1349.                                                 n->voisin[i]->cy,
  1350.                                                 sx0,sy0);
  1351.                   break ;
  1352.                  }
  1353.                 case Infini1  :
  1354.                   if (i == W)
  1355.                                   { mx = ( n->s[U]->x + n->s[V]->x )/2 ;
  1356.                     my = ( n->s[U]->y + n->s[V]->y )/2 ;
  1357.                     pt_infi(mx,my, n->cx,n->cy,&x,&y);
  1358.                     pt_infi(mx,my, n->voisin[i]->cx, 
  1359.                                                    n->voisin[i]->cy,&mx, &my);
  1360.                     trace_segment(mx,my, x,y,sx0,sy0);
  1361.                    }
  1362.                 }
  1363.                 break;
  1364.  
  1365.             } //switch
  1366.  
  1367.                   } //if
  1368.  
  1369.            }  // for
  1370.  
  1371.     for (i=W; i>=U; i--)
  1372.         { noeud v = n->voisin[i];
  1373.       if ( v->stacked != flag )
  1374.            { stack[++top] = v;          //push
  1375.              v->stacked = flag;
  1376.             }
  1377.          }
  1378.  
  1379.    } // while stack not empty
  1380.  
  1381.  delete stack;
  1382.  
  1383. }
  1384.  
  1385. DT_item delaunay_tree::neighbor(double x,double y)
  1386. /* recherche du plus proche voisin de (x,y) */
  1387. {
  1388.     DT_POINT requete;
  1389.     DT_item reponse;
  1390.  
  1391.     flag++;
  1392.     if (arbre == nouveau) return NULL;
  1393.     requete.x = x; requete.y = y;
  1394.     reponse = localise(Insert(arbre,&requete), &requete);
  1395.     return  reponse;
  1396. }
  1397.  
  1398. void delaunay_tree::del(double x, double y)
  1399. { DT_item p = neighbor(x,y);
  1400.   if (p==nil || p->x != x || p->y != y) return;
  1401.   del_item(p);
  1402.  }
  1403.  
  1404. void delaunay_tree::del_item( DT_item ppp)
  1405. {
  1406.     DT_item p;
  1407.  
  1408.     if (!ppp) return;
  1409.  
  1410.     flag++;
  1411.     p = (DT_item) ppp ;
  1412.     nouveau = p->cree->pere;    /* pour si on supprime le dernier */
  1413.     recherche(p);
  1414.     last = nouveau ;
  1415.     parcours(Reinsert,p);
  1416.         clear_inf(p->i);
  1417.         counter--;
  1418.     poubelle_point(p);
  1419. }
  1420.  
  1421. DT_item delaunay_tree::insert( coord x, coord y, void* inf)
  1422. /* procedure d'insertion d'un point dans l'arbre */
  1423. {
  1424.     DT_item p;
  1425.  
  1426.     flag++;
  1427.     p = alloc_point();
  1428.     p->x = x;
  1429.     p->y = y;
  1430.         p->i = inf;
  1431.     p->n = flag;
  1432.     if (! creation( Insert(arbre,p), p )) 
  1433.         { poubelle_point(p); 
  1434.           return neighbor(x,y);
  1435.          }
  1436.         copy_inf(inf);
  1437.         counter++;
  1438.     last = nouveau ;
  1439.     return p;
  1440. }
  1441.  
  1442. void delaunay_tree::all_items(list(DT_item)& L)
  1443. /* procedure tracant tous les points */
  1444. {
  1445.     if (arbre == nouveau) return;
  1446.     flag++;
  1447.     arbre->s[U]->visite = flag;
  1448.     arbre->s[V]->visite = flag;
  1449.     arbre->s[W]->visite = flag;
  1450.     list_items(nouveau, L);
  1451. }
  1452.  
  1453. void delaunay_tree::trace_triang_edges( delaunay_f4 *seg,int both)
  1454. /* procedure de trace de delaunay */
  1455. {
  1456.     if (arbre == nouveau) return;
  1457.     flag++;
  1458.     del_noeud(nouveau,seg, both);
  1459. }
  1460.  
  1461. void delaunay_tree::trace_voronoi_sites(delaunay_f2 *trace_item)
  1462. {
  1463.     if (arbre == nouveau) return;
  1464.     flag++;
  1465.     trace_items(nouveau,trace_item);
  1466. }
  1467.  
  1468. void delaunay_tree::trace_voronoi_edges(delaunay_f6 *trace_seg, delaunay_F6 *pt_infi, int both)
  1469. {
  1470.     if (arbre == nouveau) return;
  1471.     flag++;
  1472.     vor(nouveau,trace_seg,pt_infi, both);
  1473. }
  1474.  
  1475. void delaunay_tree::convex_hull(list(DT_item)& CH)
  1476.  CH.clear();
  1477.  
  1478.  if (arbre == nouveau) return;
  1479.  
  1480.  for (int j=2;j>=0;j--)
  1481.  { noeud v = arbre->voisin[0];
  1482.  
  1483.    int i = (j == 0) ? 2 : j-1;
  1484.  
  1485.    DT_item start = v->s[i];
  1486.  
  1487.    do
  1488.    { int k;
  1489.      if (v->type == Infini1) CH.append(v->s[i]);
  1490.      if (v->direct)
  1491.         k = (i == 0) ? 2 : i-1;
  1492.      else
  1493.         k = (i == 2) ? 0 : i+1;
  1494.      noeud w = v->voisin[k];
  1495.      for(i=0;w->voisin[i] != v;i++); 
  1496.      v = w;
  1497.     } while (v->s[i] != start);
  1498.  
  1499.   }
  1500. }
  1501.  
  1502.  
  1503.  
  1504.