pcb 4.1.1
An interactive printed circuit board layout editor.

rtree.c

Go to the documentation of this file.
00001 
00044 #ifdef HAVE_CONFIG_H
00045 #include "config.h"
00046 #endif
00047 
00048 #include "global.h"
00049 
00050 #include <assert.h>
00051 #include <inttypes.h>
00052 #include <setjmp.h>
00053 
00054 #include "mymem.h"
00055 
00056 #include "rtree.h"
00057 
00058 #ifdef HAVE_LIBDMALLOC
00059 #include <dmalloc.h>
00060 #endif
00061 
00062 #define SLOW_ASSERTS
00063 /* All rectangles are closed on the bottom left and open on the
00064  * top right. i.e. they contain one corner point, but not the other.
00065  * This requires that the corner points not be equal!
00066  */
00067 
00068 /* the number of entries in each rtree node
00069  * 4 - 7 seem to be pretty good settings
00070  */
00071 #define M_SIZE 6
00072 
00073 /* it seems that sorting the leaf order slows us down
00074  * but sometimes gives better routes
00075  */
00076 #undef SORT
00077 #define SORT_NONLEAF
00078 
00079 #define DELETE_BY_POINTER
00080 
00081 typedef struct
00082 {
00083   const BoxType *bptr;          /* pointer to the box */
00084   BoxType bounds;               /* copy of the box for locality of reference */
00085 } Rentry;
00086 
00087 struct rtree_node
00088 {
00089   BoxType box;                  /* bounds rectangle of this node */
00090   struct rtree_node *parent;    /* parent of this node, NULL = root */
00091   struct
00092   {
00093     unsigned is_leaf:1;         /* this is a leaf node */
00094     unsigned manage:31;         /* true==should free 'rect.bptr' if node is destroyed */
00095   }
00096   flags;
00097   union
00098   {
00099     struct rtree_node *kids[M_SIZE + 1];        /* when not leaf */
00100     Rentry rects[M_SIZE + 1];   /* when leaf */
00101   } u;
00102 };
00103 
00104 #ifndef NDEBUG
00105 #ifdef SLOW_ASSERTS
00106 static int
00107 __r_node_is_good (struct rtree_node *node)
00108 {
00109   int i, flag = 1;
00110   int kind = -1;
00111   bool last = false;
00112 
00113   if (node == NULL)
00114     return 1;
00115   for (i = 0; i < M_SIZE; i++)
00116     {
00117       if (node->flags.is_leaf)
00118         {
00119           if (!node->u.rects[i].bptr)
00120             {
00121               last = true;
00122               continue;
00123             }
00124           /* check that once one entry is empty, all the rest are too */
00125           if (node->u.rects[i].bptr && last)
00126             assert (0);
00127           /* check that the box makes sense */
00128           if (node->box.X1 > node->box.X2)
00129             assert (0);
00130           if (node->box.Y1 > node->box.Y2)
00131             assert (0);
00132           /* check that bounds is the same as the pointer */
00133           if (node->u.rects[i].bounds.X1 != node->u.rects[i].bptr->X1)
00134             assert (0);
00135           if (node->u.rects[i].bounds.Y1 != node->u.rects[i].bptr->Y1)
00136             assert (0);
00137           if (node->u.rects[i].bounds.X2 != node->u.rects[i].bptr->X2)
00138             assert (0);
00139           if (node->u.rects[i].bounds.Y2 != node->u.rects[i].bptr->Y2)
00140             assert (0);
00141           /* check that entries are within node bounds */
00142           if (node->u.rects[i].bounds.X1 < node->box.X1)
00143             assert (0);
00144           if (node->u.rects[i].bounds.X2 > node->box.X2)
00145             assert (0);
00146           if (node->u.rects[i].bounds.Y1 < node->box.Y1)
00147             assert (0);
00148           if (node->u.rects[i].bounds.Y2 > node->box.Y2)
00149             assert (0);
00150         }
00151       else
00152         {
00153           if (!node->u.kids[i])
00154             {
00155               last = true;
00156               continue;
00157             }
00158           /* make sure all children are the same type */
00159           if (kind == -1)
00160             kind = node->u.kids[i]->flags.is_leaf;
00161           else if (kind != node->u.kids[i]->flags.is_leaf)
00162             assert (0);
00163           /* check that once one entry is empty, all the rest are too */
00164           if (node->u.kids[i] && last)
00165             assert (0);
00166           /* check that entries are within node bounds */
00167           if (node->u.kids[i]->box.X1 < node->box.X1)
00168             assert (0);
00169           if (node->u.kids[i]->box.X2 > node->box.X2)
00170             assert (0);
00171           if (node->u.kids[i]->box.Y1 < node->box.Y1)
00172             assert (0);
00173           if (node->u.kids[i]->box.Y2 > node->box.Y2)
00174             assert (0);
00175         }
00176       flag <<= 1;
00177     }
00178   /* check that we're completely in the parent's bounds */
00179   if (node->parent)
00180     {
00181       if (node->parent->box.X1 > node->box.X1)
00182         assert (0);
00183       if (node->parent->box.X2 < node->box.X2)
00184         assert (0);
00185       if (node->parent->box.Y1 > node->box.Y1)
00186         assert (0);
00187       if (node->parent->box.Y2 < node->box.Y2)
00188         assert (0);
00189     }
00190   /* make sure overflow is empty */
00191   if (!node->flags.is_leaf && node->u.kids[i])
00192     assert (0);
00193   if (node->flags.is_leaf && node->u.rects[i].bptr)
00194     assert (0);
00195   return 1;
00196 }
00197 
00201 static bool
00202 __r_tree_is_good (struct rtree_node *node)
00203 {
00204   int i;
00205 
00206   if (!node)
00207     return 1;
00208   if (!__r_node_is_good (node))
00209     assert (0);
00210   if (node->flags.is_leaf)
00211     return 1;
00212   for (i = 0; i < M_SIZE; i++)
00213     {
00214       if (!__r_tree_is_good (node->u.kids[i]))
00215         return 0;
00216     }
00217   return 1;
00218 }
00219 #endif
00220 #endif
00221 
00222 #ifndef NDEBUG
00223 
00226 void
00227 __r_dump_tree (struct rtree_node *node, int depth)
00228 {
00229   int i, j;
00230   static int count;
00231   static double area;
00232 
00233   if (depth == 0)
00234     {
00235       area = 0;
00236       count = 0;
00237     }
00238   area +=
00239     (node->box.X2 - node->box.X1) * (double) (node->box.Y2 - node->box.Y1);
00240   count++;
00241   for (i = 0; i < depth; i++)
00242     printf ("  ");
00243   if (!node->flags.is_leaf)
00244     {
00245       printf (
00246           "p=0x%p node X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64 ", %" PRIi64 
00247           ")\n",
00248           (void *) node,
00249           (int64_t) (node->box.X1),
00250           (int64_t) (node->box.X2),
00251           (int64_t) (node->box.Y1),
00252           (int64_t) (node->box.Y2) );
00253     }
00254   else
00255     {
00256       printf (
00257           "p=0x%p leaf manage(%02x) X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64
00258           ", %" PRIi64 ")\n",
00259           (void *) node,
00260           node->flags.manage,
00261           (int64_t) (node->box.X1),
00262           (int64_t) (node->box.X2),
00263           (int64_t) (node->box.Y1),
00264           (int64_t) (node->box.Y2) );
00265       for (j = 0; j < M_SIZE; j++)
00266         {
00267           if (!node->u.rects[j].bptr)
00268             break;
00269           area +=
00270             (node->u.rects[j].bounds.X2 -
00271              node->u.rects[j].bounds.X1) *
00272             (double) (node->u.rects[j].bounds.Y2 -
00273                       node->u.rects[j].bounds.Y1);
00274           count++;
00275           for (i = 0; i < depth + 1; i++)
00276             printf ("  ");
00277           printf (
00278               "entry 0x%p X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64 ", "
00279               "%" PRIi64 ")\n",
00280               (void *) (node->u.rects[j].bptr),
00281               (int64_t) (node->u.rects[j].bounds.X1),
00282               (int64_t) (node->u.rects[j].bounds.X2),
00283               (int64_t) (node->u.rects[j].bounds.Y1),
00284               (int64_t) (node->u.rects[j].bounds.Y2) );
00285         }
00286       return;
00287     }
00288   for (i = 0; i < M_SIZE; i++)
00289     if (node->u.kids[i])
00290       __r_dump_tree (node->u.kids[i], depth + 1);
00291   if (depth == 0)
00292     printf ("average box area is %g\n", area / count);
00293 }
00294 #endif
00295 
00296 #ifdef SORT
00297 
00307 static int
00308 cmp_box (const BoxType * a, const BoxType * b)
00309 {
00310   if (a->X1 < b->X1)
00311     return 0;
00312   if (a->X1 > b->X1)
00313     return 1;
00314   if (a->X2 > b->X2)
00315     return 0;
00316   if (a->X2 < b->X2)
00317     return 1;
00318   if (a->Y1 < b->Y1)
00319     return 0;
00320   if (a->Y1 > b->Y1)
00321     return 1;
00322   if (a->Y2 > b->Y2)
00323     return 0;
00324   return 1;
00325 }
00326 
00327 static void
00328 sort_node (struct rtree_node *node)
00329 {
00330   if (node->flags.is_leaf)
00331     {
00332       register Rentry *r, *i, temp;
00333 
00334       for (r = &node->u.rects[1]; r->bptr; r++)
00335         {
00336           temp = *r;
00337           i = r - 1;
00338           while (i >= &node->u.rects[0])
00339             {
00340               if (cmp_box (&i->bounds, &r->bounds))
00341                 break;
00342               *(i + 1) = *i;
00343               i--;
00344             }
00345           *(i + 1) = temp;
00346         }
00347     }
00348 #ifdef SORT_NONLEAF
00349   else
00350     {
00351       register struct rtree_node **r, **i, *temp;
00352 
00353       for (r = &node->u.kids[1]; *r; r++)
00354         {
00355           temp = *r;
00356           i = r - 1;
00357           while (i >= &node->u.kids[0])
00358             {
00359               if (cmp_box (&(*i)->box, &(*r)->box))
00360                 break;
00361               *(i + 1) = *i;
00362               i--;
00363             }
00364           *(i + 1) = temp;
00365         }
00366     }
00367 #endif
00368 }
00369 #else
00370 #define sort_node(x)
00371 #endif
00372 
00377 static void
00378 adjust_bounds (struct rtree_node *node)
00379 {
00380   int i;
00381 
00382   assert (node);
00383   assert (node->u.kids[0]);
00384   if (node->flags.is_leaf)
00385     {
00386       node->box = node->u.rects[0].bounds;
00387       for (i = 1; i < M_SIZE + 1; i++)
00388         {
00389           if (!node->u.rects[i].bptr)
00390             return;
00391           MAKEMIN (node->box.X1, node->u.rects[i].bounds.X1);
00392           MAKEMAX (node->box.X2, node->u.rects[i].bounds.X2);
00393           MAKEMIN (node->box.Y1, node->u.rects[i].bounds.Y1);
00394           MAKEMAX (node->box.Y2, node->u.rects[i].bounds.Y2);
00395         }
00396     }
00397   else
00398     {
00399       node->box = node->u.kids[0]->box;
00400       for (i = 1; i < M_SIZE + 1; i++)
00401         {
00402           if (!node->u.kids[i])
00403             return;
00404           MAKEMIN (node->box.X1, node->u.kids[i]->box.X1);
00405           MAKEMAX (node->box.X2, node->u.kids[i]->box.X2);
00406           MAKEMIN (node->box.Y1, node->u.kids[i]->box.Y1);
00407           MAKEMAX (node->box.Y2, node->u.kids[i]->box.Y2);
00408         }
00409     }
00410 }
00411 
00424 rtree_t *
00425 r_create_tree (const BoxType * boxlist[], int N, int manage)
00426 {
00427   rtree_t *rtree;
00428   struct rtree_node *node;
00429   int i;
00430 
00431   assert (N >= 0);
00432   rtree = (rtree_t *)calloc (1, sizeof (*rtree));
00433   /* start with a single empty leaf node */
00434   node = (struct rtree_node *)calloc (1, sizeof (*node));
00435   node->flags.is_leaf = 1;
00436   node->parent = NULL;
00437   rtree->root = node;
00438   /* simple, just insert all of the boxes! */
00439   for (i = 0; i < N; i++)
00440     {
00441       assert (boxlist[i]);
00442       r_insert_entry (rtree, boxlist[i], manage);
00443     }
00444 #ifdef SLOW_ASSERTS
00445   assert (__r_tree_is_good (rtree->root));
00446 #endif
00447   return rtree;
00448 }
00449 
00453 static void
00454 __r_destroy_tree (struct rtree_node *node)
00455 {
00456   int i, flag = 1;
00457 
00458   if (node->flags.is_leaf)
00459     for (i = 0; i < M_SIZE; i++)
00460       {
00461         if (!node->u.rects[i].bptr)
00462           break;
00463         if (node->flags.manage & flag)
00464           free ((void *) node->u.rects[i].bptr);
00465         flag = flag << 1;
00466       }
00467   else
00468     for (i = 0; i < M_SIZE; i++)
00469       {
00470         if (!node->u.kids[i])
00471           break;
00472         __r_destroy_tree (node->u.kids[i]);
00473       }
00474   free (node);
00475 }
00476 
00480 void
00481 r_destroy_tree (rtree_t ** rtree)
00482 {
00483 
00484   __r_destroy_tree ((*rtree)->root);
00485   free (*rtree);
00486   *rtree = NULL;
00487 }
00488 
00489 typedef struct
00490 {
00491   int (*check_it) (const BoxType * region, void *cl);
00492   int (*found_it) (const BoxType * box, void *cl);
00493   void *closure;
00494 } r_arg;
00495 
00503 int
00504 __r_search (struct rtree_node *node, const BoxType * query, r_arg * arg)
00505 {
00506   assert (node);
00507   /* assert that starting_region is well formed */
00508   assert (query->X1 < query->X2 && query->Y1 < query->Y2);
00509   assert (node->box.X1 < query->X2 && node->box.X2 > query->X1 &&
00510           node->box.Y1 < query->Y2 && node->box.Y2 > query->Y1);
00511 #ifdef SLOW_ASSERTS
00512   /* assert that node is well formed */
00513   assert (__r_node_is_good (node));
00514 #endif
00515   /* the check for bounds is done before entry. This saves the overhead
00516    * of building/destroying the stack frame for each bounds that fails
00517    * to intersect, which is the most common condition.
00518    */
00519   if (node->flags.is_leaf)
00520     {
00521       register int i;
00522       if (arg->found_it)        /* test this once outside of loop */
00523         {
00524           register int seen = 0;
00525           for (i = 0; node->u.rects[i].bptr; i++)
00526             {
00527               if ((node->u.rects[i].bounds.X1 < query->X2) &&
00528                   (node->u.rects[i].bounds.X2 > query->X1) &&
00529                   (node->u.rects[i].bounds.Y1 < query->Y2) &&
00530                   (node->u.rects[i].bounds.Y2 > query->Y1) &&
00531                   arg->found_it (node->u.rects[i].bptr, arg->closure))
00532                 seen++;
00533             }
00534           return seen;
00535         }
00536       else
00537         {
00538           register int seen = 0;
00539           for (i = 0; node->u.rects[i].bptr; i++)
00540             {
00541               if ((node->u.rects[i].bounds.X1 < query->X2) &&
00542                   (node->u.rects[i].bounds.X2 > query->X1) &&
00543                   (node->u.rects[i].bounds.Y1 < query->Y2) &&
00544                   (node->u.rects[i].bounds.Y2 > query->Y1))
00545                 seen++;
00546             }
00547           return seen;
00548         }
00549     }
00550 
00551   /* not a leaf, recurse on lower nodes */
00552   if (arg->check_it)
00553     {
00554       int seen = 0;
00555       struct rtree_node **n;
00556       for (n = &node->u.kids[0]; *n; n++)
00557         {
00558           if ((*n)->box.X1 >= query->X2 ||
00559               (*n)->box.X2 <= query->X1 ||
00560               (*n)->box.Y1 >= query->Y2 || (*n)->box.Y2 <= query->Y1 ||
00561               !arg->check_it (&(*n)->box, arg->closure))
00562             continue;
00563           seen += __r_search (*n, query, arg);
00564         }
00565       return seen;
00566     }
00567   else
00568     {
00569       int seen = 0;
00570       struct rtree_node **n;
00571       for (n = &node->u.kids[0]; *n; n++)
00572         {
00573           if ((*n)->box.X1 >= query->X2 ||
00574               (*n)->box.X2 <= query->X1 ||
00575               (*n)->box.Y1 >= query->Y2 || (*n)->box.Y2 <= query->Y1)
00576             continue;
00577           seen += __r_search (*n, query, arg);
00578         }
00579       return seen;
00580     }
00581 }
00582 
00611 int
00612 r_search (rtree_t * rtree, const BoxType * query,
00613           int (*check_region) (const BoxType * region, void *cl),
00614           int (*found_rectangle) (const BoxType * box, void *cl), void *cl)
00615 {
00616   r_arg arg;
00617 
00618   if (!rtree || rtree->size < 1)
00619     return 0;
00620   if (query)
00621     {
00622 #ifdef SLOW_ASSERTS
00623   assert (__r_tree_is_good (rtree->root));
00624 #endif
00625 #ifdef DEBUG
00626       if (query->X2 <= query->X1 || query->Y2 <= query->Y1)
00627         return 0;
00628 #endif
00629       /* check this box. If it's not touched we're done here */
00630       if (rtree->root->box.X1 >= query->X2 ||
00631           rtree->root->box.X2 <= query->X1 ||
00632           rtree->root->box.Y1 >= query->Y2
00633           || rtree->root->box.Y2 <= query->Y1)
00634         return 0;
00635       arg.check_it = check_region;
00636       arg.found_it = found_rectangle;
00637       arg.closure = cl;
00638       return __r_search (rtree->root, query, &arg);
00639     }
00640   else
00641     {
00642       arg.check_it = check_region;
00643       arg.found_it = found_rectangle;
00644       arg.closure = cl;
00645       return __r_search (rtree->root, &rtree->root->box, &arg);
00646     }
00647 }
00648 
00652 static int
00653 __r_region_is_empty_rect_in_reg (const BoxType * box, void *cl)
00654 {
00655   jmp_buf *envp = (jmp_buf *) cl;
00656   longjmp (*envp, 1);           /* found one! */
00657 }
00658 
00664 int
00665 r_region_is_empty (rtree_t * rtree, const BoxType * region)
00666 {
00667   jmp_buf env;
00668 #ifndef NDEBUG
00669   int r;
00670 #endif
00671 
00672   if (setjmp (env))
00673     return 0;
00674 #ifndef NDEBUG
00675   r =
00676 #endif
00677     r_search (rtree, region, NULL, __r_region_is_empty_rect_in_reg, &env);
00678 #ifndef NDEBUG
00679   assert (r == 0);              /* otherwise longjmp would have been called */
00680 #endif
00681   return 1;                     /* no rectangles found */
00682 }
00683 
00684 struct centroid
00685 {
00686   float x, y, area;
00687 };
00688 
00693 struct rtree_node *
00694 find_clusters (struct rtree_node *node)
00695 {
00696   float total_a, total_b;
00697   float a_X, a_Y, b_X, b_Y;
00698   bool belong[M_SIZE + 1];
00699   struct centroid center[M_SIZE + 1];
00700   int clust_a, clust_b, tries;
00701   int a_manage = 0, b_manage = 0;
00702   int i, old_ax, old_ay, old_bx, old_by;
00703   struct rtree_node *new_node;
00704   BoxType *b;
00705 
00706   for (i = 0; i < M_SIZE + 1; i++)
00707     {
00708       if (node->flags.is_leaf)
00709         b = &(node->u.rects[i].bounds);
00710       else
00711         b = &(node->u.kids[i]->box);
00712       center[i].x = 0.5 * (b->X1 + b->X2);
00713       center[i].y = 0.5 * (b->Y1 + b->Y2);
00714       /* adding 1 prevents zero area */
00715       center[i].area = 1. + (float) (b->X2 - b->X1) * (float) (b->Y2 - b->Y1);
00716     }
00717   /* starting 'A' cluster center */
00718   a_X = center[0].x;
00719   a_Y = center[0].y;
00720   /* starting 'B' cluster center */
00721   b_X = center[M_SIZE].x;
00722   b_Y = center[M_SIZE].y;
00723   /* don't allow the same cluster centers */
00724   if (b_X == a_X && b_Y == a_Y)
00725     {
00726       b_X += 10000;
00727       a_Y -= 10000;
00728     }
00729   for (tries = 0; tries < M_SIZE; tries++)
00730     {
00731       old_ax = (int) a_X;
00732       old_ay = (int) a_Y;
00733       old_bx = (int) b_X;
00734       old_by = (int) b_Y;
00735       clust_a = clust_b = 0;
00736       for (i = 0; i < M_SIZE + 1; i++)
00737         {
00738           float dist1, dist2;
00739 
00740           dist1 = SQUARE (a_X - center[i].x) + SQUARE (a_Y - center[i].y);
00741           dist2 = SQUARE (b_X - center[i].x) + SQUARE (b_Y - center[i].y);
00742           if (dist1 * (clust_a + M_SIZE / 2) < dist2 * (clust_b + M_SIZE / 2))
00743             {
00744               belong[i] = true;
00745               clust_a++;
00746             }
00747           else
00748             {
00749               belong[i] = false;
00750               clust_b++;
00751             }
00752         }
00753       /* kludge to fix degenerate cases */
00754       if (clust_a == M_SIZE + 1)
00755         belong[M_SIZE / 2] = false;
00756       else if (clust_b == M_SIZE + 1)
00757         belong[M_SIZE / 2] = true;
00758       /* compute new center of gravity of clusters */
00759       total_a = total_b = 0;
00760       a_X = a_Y = b_X = b_Y = 0;
00761       for (i = 0; i < M_SIZE + 1; i++)
00762         {
00763           if (belong[i])
00764             {
00765               a_X += center[i].x * center[i].area;
00766               a_Y += center[i].y * center[i].area;
00767               total_a += center[i].area;
00768             }
00769           else
00770             {
00771               b_X += center[i].x * center[i].area;
00772               b_Y += center[i].y * center[i].area;
00773               total_b += center[i].area;
00774             }
00775         }
00776       a_X /= total_a;
00777       a_Y /= total_a;
00778       b_X /= total_b;
00779       b_Y /= total_b;
00780       if (old_ax == (int) a_X && old_ay == (int) a_Y &&
00781           old_bx == (int) b_X && old_by == (int) b_Y)
00782         break;
00783     }
00784   /* Now 'belong' has the partition map */
00785   new_node = (struct rtree_node *)calloc (1, sizeof (*new_node));
00786   new_node->parent = node->parent;
00787   new_node->flags.is_leaf = node->flags.is_leaf;
00788   clust_a = clust_b = 0;
00789   if (node->flags.is_leaf)
00790     {
00791       int flag, a_flag, b_flag;
00792       flag = a_flag = b_flag = 1;
00793       for (i = 0; i < M_SIZE + 1; i++)
00794         {
00795           if (belong[i])
00796             {
00797               node->u.rects[clust_a++] = node->u.rects[i];
00798               if (node->flags.manage & flag)
00799                 a_manage |= a_flag;
00800               a_flag <<= 1;
00801             }
00802           else
00803             {
00804               new_node->u.rects[clust_b++] = node->u.rects[i];
00805               if (node->flags.manage & flag)
00806                 b_manage |= b_flag;
00807               b_flag <<= 1;
00808             }
00809           flag <<= 1;
00810         }
00811     }
00812   else
00813     {
00814       for (i = 0; i < M_SIZE + 1; i++)
00815         {
00816           if (belong[i])
00817             node->u.kids[clust_a++] = node->u.kids[i];
00818           else
00819             {
00820               node->u.kids[i]->parent = new_node;
00821               new_node->u.kids[clust_b++] = node->u.kids[i];
00822             }
00823         }
00824     }
00825   node->flags.manage = a_manage;
00826   new_node->flags.manage = b_manage;
00827   assert (clust_a != 0);
00828   assert (clust_b != 0);
00829   if (node->flags.is_leaf)
00830     for (; clust_a < M_SIZE + 1; clust_a++)
00831       node->u.rects[clust_a].bptr = NULL;
00832   else
00833     for (; clust_a < M_SIZE + 1; clust_a++)
00834       node->u.kids[clust_a] = NULL;
00835   adjust_bounds (node);
00836   sort_node (node);
00837   adjust_bounds (new_node);
00838   sort_node (new_node);
00839   return (new_node);
00840 }
00841 
00845 static void
00846 split_node (struct rtree_node *node)
00847 {
00848   int i;
00849   struct rtree_node *new_node;
00850 
00851   assert (node);
00852   assert (node->flags.is_leaf ? (void *) node->u.rects[M_SIZE].
00853           bptr : (void *) node->u.kids[M_SIZE]);
00854   new_node = find_clusters (node);
00855   if (node->parent == NULL)     /* split root node */
00856     {
00857       struct rtree_node *second;
00858 
00859       second = (struct rtree_node *)calloc (1, sizeof (*second));
00860       *second = *node;
00861       if (!second->flags.is_leaf)
00862         for (i = 0; i < M_SIZE; i++)
00863           if (second->u.kids[i])
00864             second->u.kids[i]->parent = second;
00865       node->flags.is_leaf = 0;
00866       node->flags.manage = 0;
00867       second->parent = new_node->parent = node;
00868       node->u.kids[0] = new_node;
00869       node->u.kids[1] = second;
00870       for (i = 2; i < M_SIZE + 1; i++)
00871         node->u.kids[i] = NULL;
00872       adjust_bounds (node);
00873       sort_node (node);
00874 #ifdef SLOW_ASSERTS
00875       assert (__r_tree_is_good (node));
00876 #endif
00877       return;
00878     }
00879   for (i = 0; i < M_SIZE; i++)
00880     if (!node->parent->u.kids[i])
00881       break;
00882   node->parent->u.kids[i] = new_node;
00883 #ifdef SLOW_ASSERTS
00884   assert (__r_node_is_good (node));
00885   assert (__r_node_is_good (new_node));
00886 #endif
00887   if (i < M_SIZE)
00888     {
00889 #ifdef SLOW_ASSERTS
00890       assert (__r_node_is_good (node->parent));
00891 #endif
00892       sort_node (node->parent);
00893       return;
00894     }
00895   split_node (node->parent);
00896 }
00897 
00898 static inline int
00899 contained (struct rtree_node *node, const BoxType * query)
00900 {
00901   if (node->box.X1 > query->X1 || node->box.X2 < query->X2 ||
00902       node->box.Y1 > query->Y1 || node->box.Y2 < query->Y2)
00903     return 0;
00904   return 1;
00905 }
00906 
00907 
00913 static inline double
00914 penalty (struct rtree_node *node, const BoxType * query)
00915 {
00916   double score;
00917 
00918   score  = (MAX (node->box.X2, query->X2) - MIN (node->box.X1, query->X1));
00919   score *= (MAX (node->box.Y2, query->Y2) - MIN (node->box.Y1, query->Y1));
00920   score -=
00921     (double)(node->box.X2 - node->box.X1) *
00922     (double)(node->box.Y2 - node->box.Y1);
00923   return score;
00924 }
00925 
00926 static void
00927 __r_insert_node (struct rtree_node *node, const BoxType * query,
00928                  int manage, bool force)
00929 {
00930 
00931 #ifdef SLOW_ASSERTS
00932   assert (__r_node_is_good (node));
00933 #endif
00934   /* Ok, at this point we must already enclose the query or we're forcing
00935    * this node to expand to enclose it, so if we're a leaf, simply store
00936    * the query here
00937    */
00938 
00939   if (node->flags.is_leaf)
00940     {
00941       register int i;
00942 
00943       if (UNLIKELY (manage))
00944         {
00945           register int flag = 1;
00946 
00947           for (i = 0; i < M_SIZE; i++)
00948             {
00949               if (!node->u.rects[i].bptr)
00950                 break;
00951               flag <<= 1;
00952             }
00953           node->flags.manage |= flag;
00954         }
00955       else
00956         {
00957           for (i = 0; i < M_SIZE; i++)
00958             if (!node->u.rects[i].bptr)
00959               break;
00960         }
00961       /* the node always has an extra space available */
00962       node->u.rects[i].bptr = query;
00963       node->u.rects[i].bounds = *query;
00964       /* first entry in node determines initial bounding box */
00965       if (i == 0)
00966         node->box = *query;
00967       else if (force)
00968         {
00969           MAKEMIN (node->box.X1, query->X1);
00970           MAKEMAX (node->box.X2, query->X2);
00971           MAKEMIN (node->box.Y1, query->Y1);
00972           MAKEMAX (node->box.Y2, query->Y2);
00973         }
00974       if (i < M_SIZE)
00975         {
00976           sort_node (node);
00977           return;
00978         }
00979       /* we must split the node */
00980       split_node (node);
00981       return;
00982     }
00983   else
00984     {
00985       int i;
00986       struct rtree_node *best_node;
00987       double score, best_score;
00988 
00989       if (force)
00990         {
00991           MAKEMIN (node->box.X1, query->X1);
00992           MAKEMAX (node->box.X2, query->X2);
00993           MAKEMIN (node->box.Y1, query->Y1);
00994           MAKEMAX (node->box.Y2, query->Y2);
00995         }
00996 
00997       /* this node encloses it, but it's not a leaf, so descend the tree */
00998 
00999       /* First check if any children actually encloses it */
01000       assert (node->u.kids[0]);
01001       for (i = 0; i < M_SIZE; i++)
01002         {
01003           if (!node->u.kids[i])
01004             break;
01005           if (contained (node->u.kids[i], query))
01006             {
01007               __r_insert_node (node->u.kids[i], query, manage, false);
01008               sort_node (node);
01009               return;
01010             }
01011         }
01012 
01013       /* see if there is room for a new leaf node */
01014       if (node->u.kids[0]->flags.is_leaf && i < M_SIZE)
01015         {
01016           struct rtree_node *new_node;
01017           new_node = (struct rtree_node *)calloc (1, sizeof (*new_node));
01018           new_node->parent = node;
01019           new_node->flags.is_leaf = true;
01020           node->u.kids[i] = new_node;
01021           new_node->u.rects[0].bptr = query;
01022           new_node->u.rects[0].bounds = *query;
01023           new_node->box = *query;
01024           if (UNLIKELY (manage))
01025             new_node->flags.manage = 1;
01026           sort_node (node);
01027           return;
01028         }
01029 
01030       /* Ok, so we're still here - look for the best child to push it into */
01031       best_score = penalty (node->u.kids[0], query);
01032       best_node = node->u.kids[0];
01033       for (i = 1; i < M_SIZE; i++)
01034         {
01035           if (!node->u.kids[i])
01036             break;
01037           score = penalty (node->u.kids[i], query);
01038           if (score < best_score)
01039             {
01040               best_score = score;
01041               best_node = node->u.kids[i];
01042             }
01043         }
01044       __r_insert_node (best_node, query, manage, true);
01045       sort_node (node);
01046       return;
01047     }
01048 }
01049 
01050 void
01051 r_insert_entry (rtree_t * rtree, const BoxType * which, int man)
01052 {
01053   assert (which);
01054   assert (which->X1 <= which->X2);
01055   assert (which->Y1 <= which->Y2);
01056   /* recursively search the tree for the best leaf node */
01057   assert (rtree->root);
01058   __r_insert_node (rtree->root, which, man,
01059                    rtree->root->box.X1 > which->X1
01060                    || rtree->root->box.X2 < which->X2
01061                    || rtree->root->box.Y1 > which->Y1
01062                    || rtree->root->box.Y2 < which->Y2);
01063   rtree->size++;
01064 }
01065 
01066 bool
01067 __r_delete (struct rtree_node *node, const BoxType * query)
01068 {
01069   int i, flag, mask, a;
01070 
01071   /* the tree might be inconsistent during delete */
01072   if (query->X1 < node->box.X1 || query->Y1 < node->box.Y1
01073       || query->X2 > node->box.X2 || query->Y2 > node->box.Y2)
01074     return false;
01075   if (!node->flags.is_leaf)
01076     {
01077       for (i = 0; i < M_SIZE; i++)
01078         {
01079           /* if this is us being removed, free and copy over */
01080           if (node->u.kids[i] == (struct rtree_node *) query)
01081             {
01082               free ((void *) query);
01083               for (; i < M_SIZE; i++)
01084                 {
01085                   node->u.kids[i] = node->u.kids[i + 1];
01086                   if (!node->u.kids[i])
01087                     break;
01088                 }
01089               /* nobody home here now ? */
01090               if (!node->u.kids[0])
01091                 {
01092                   if (!node->parent)
01093                     {
01094                       /* wow, the root is empty! */
01095                       node->flags.is_leaf = 1;
01096                       /* changing type of node, be sure it's all zero */
01097                       for (i = 1; i < M_SIZE + 1; i++)
01098                         node->u.rects[i].bptr = NULL;
01099                       return true;
01100                     }
01101                   return (__r_delete (node->parent, &node->box));
01102                 }
01103               else
01104                 /* propegate boundary adjust upward */
01105                 while (node)
01106                   {
01107                     adjust_bounds (node);
01108                     node = node->parent;
01109                   }
01110               return true;
01111             }
01112           if (node->u.kids[i])
01113             {
01114               if (__r_delete (node->u.kids[i], query))
01115                 return true;
01116             }
01117           else
01118             break;
01119         }
01120       return false;
01121     }
01122   /* leaf node here */
01123   mask = 0;
01124   a = 1;
01125   for (i = 0; i < M_SIZE; i++)
01126     {
01127 #ifdef DELETE_BY_POINTER
01128       if (!node->u.rects[i].bptr || node->u.rects[i].bptr == query)
01129 #else
01130       if (node->u.rects[i].bounds.X1 == query->X1 &&
01131           node->u.rects[i].bounds.X2 == query->X2 &&
01132           node->u.rects[i].bounds.Y1 == query->Y1 &&
01133           node->u.rects[i].bounds.Y2 == query->Y2)
01134 #endif
01135         break;
01136       mask |= a;
01137       a <<= 1;
01138     }
01139   if (!node->u.rects[i].bptr)
01140     return false;               /* not at this leaf */
01141   if (node->flags.manage & a)
01142     {
01143       free ((void *) node->u.rects[i].bptr);
01144       node->u.rects[i].bptr = NULL;
01145     }
01146   /* squeeze the manage flags together */
01147   flag = node->flags.manage & mask;
01148   mask = (~mask) << 1;
01149   node->flags.manage = flag | ((node->flags.manage & mask) >> 1);
01150   /* remove the entry */
01151   for (; i < M_SIZE; i++)
01152     {
01153       node->u.rects[i] = node->u.rects[i + 1];
01154       if (!node->u.rects[i].bptr)
01155         break;
01156     }
01157   if (!node->u.rects[0].bptr)
01158     {
01159       if (node->parent)
01160         __r_delete (node->parent, &node->box);
01161       return true;
01162     }
01163   else
01164     /* propagate boundary adjustment upward */
01165     while (node)
01166       {
01167         adjust_bounds (node);
01168         node = node->parent;
01169       }
01170   return true;
01171 }
01172 
01173 bool
01174 r_delete_entry (rtree_t * rtree, const BoxType * box)
01175 {
01176   bool r;
01177 
01178   assert (box);
01179   assert (rtree);
01180   r = __r_delete (rtree->root, box);
01181   if (r)
01182     rtree->size--;
01183 #ifdef SLOW_ASSERTS
01184   assert (__r_tree_is_good (rtree->root));
01185 #endif
01186   return r;
01187 }