_delaunay_tree.c
上传用户:gzelex
上传日期:2007-01-07
资源大小:707k
文件大小:42k
开发平台:

MultiPlatform

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