1 /*!
2 * \file src/rtree.c
3 *
4 * \brief Implements r-tree structures.
5 *
6 * These should be much faster for the auto-router because the recursive
7 * search is much more efficient and that's where the auto-router spends
8 * all its time.
9 *
10 * \author this file, rtree.c, was written and is Copyright (c) 2004,
11 * harry eaton
12 *
13 * <hr>
14 *
15 * <h1><b>Copyright.</b></h1>\n
16 *
17 * PCB, interactive printed circuit board design
18 *
19 * Copyright (C) 1994,1995,1996 Thomas Nau
20 *
21 * Copyright (C) 1998,1999,2000,2001,2002,2003,2004 harry eaton
22 *
23 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation; either version 2 of the License, or
26 * (at your option) any later version.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License along
34 * with this program; if not, write to the Free Software Foundation, Inc.,
35 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36 *
37 * Contact addresses for paper mail and Email:
38 *
39 * harry eaton, 6697 Buttonhole Ct, Columbia, MD 21044 USA
40 *
41 * haceaton@aplcomm.jhuapl.edu
42 */
43
44 #ifdef HAVE_CONFIG_H
45 #include "config.h"
46 #endif
47
48 #include "global.h"
49
50 #include <assert.h>
51 #include <inttypes.h>
52 #include <setjmp.h>
53
54 #include "mymem.h"
55
56 #include "rtree.h"
57
58 #ifdef HAVE_LIBDMALLOC
59 #include <dmalloc.h>
60 #endif
61
62 #define SLOW_ASSERTS
63 /* All rectangles are closed on the bottom left and open on the
64 * top right. i.e. they contain one corner point, but not the other.
65 * This requires that the corner points not be equal!
66 */
67
68 /* the number of entries in each rtree node
69 * 4 - 7 seem to be pretty good settings
70 */
71 #define M_SIZE 6
72
73 /* it seems that sorting the leaf order slows us down
74 * but sometimes gives better routes
75 */
76 #undef SORT
77 #define SORT_NONLEAF
78
79 #define DELETE_BY_POINTER
80
81 typedef struct
82 {
83 const BoxType *bptr; /* pointer to the box */
84 BoxType bounds; /* copy of the box for locality of reference */
85 } Rentry;
86
87 struct rtree_node
88 {
89 BoxType box; /* bounds rectangle of this node */
90 struct rtree_node *parent; /* parent of this node, NULL = root */
91 struct
92 {
93 unsigned is_leaf:1; /* this is a leaf node */
94 unsigned manage:31; /* true==should free 'rect.bptr' if node is destroyed */
95 }
96 flags;
97 union
98 {
99 struct rtree_node *kids[M_SIZE + 1]; /* when not leaf */
100 Rentry rects[M_SIZE + 1]; /* when leaf */
101 } u;
102 };
103
104 #ifndef NDEBUG
105 #ifdef SLOW_ASSERTS
106 static int
__r_node_is_good(struct rtree_node * node)107 __r_node_is_good (struct rtree_node *node)
108 {
109 int i, flag = 1;
110 int kind = -1;
111 bool last = false;
112
113 if (node == NULL)
114 return 1;
115 for (i = 0; i < M_SIZE; i++)
116 {
117 if (node->flags.is_leaf)
118 {
119 if (!node->u.rects[i].bptr)
120 {
121 last = true;
122 continue;
123 }
124 /* check that once one entry is empty, all the rest are too */
125 if (node->u.rects[i].bptr && last)
126 assert (0);
127 /* check that the box makes sense */
128 if (node->box.X1 > node->box.X2)
129 assert (0);
130 if (node->box.Y1 > node->box.Y2)
131 assert (0);
132 /* check that bounds is the same as the pointer */
133 if (node->u.rects[i].bounds.X1 != node->u.rects[i].bptr->X1)
134 assert (0);
135 if (node->u.rects[i].bounds.Y1 != node->u.rects[i].bptr->Y1)
136 assert (0);
137 if (node->u.rects[i].bounds.X2 != node->u.rects[i].bptr->X2)
138 assert (0);
139 if (node->u.rects[i].bounds.Y2 != node->u.rects[i].bptr->Y2)
140 assert (0);
141 /* check that entries are within node bounds */
142 if (node->u.rects[i].bounds.X1 < node->box.X1)
143 assert (0);
144 if (node->u.rects[i].bounds.X2 > node->box.X2)
145 assert (0);
146 if (node->u.rects[i].bounds.Y1 < node->box.Y1)
147 assert (0);
148 if (node->u.rects[i].bounds.Y2 > node->box.Y2)
149 assert (0);
150 }
151 else
152 {
153 if (!node->u.kids[i])
154 {
155 last = true;
156 continue;
157 }
158 /* make sure all children are the same type */
159 if (kind == -1)
160 kind = node->u.kids[i]->flags.is_leaf;
161 else if (kind != node->u.kids[i]->flags.is_leaf)
162 assert (0);
163 /* check that once one entry is empty, all the rest are too */
164 if (node->u.kids[i] && last)
165 assert (0);
166 /* check that entries are within node bounds */
167 if (node->u.kids[i]->box.X1 < node->box.X1)
168 assert (0);
169 if (node->u.kids[i]->box.X2 > node->box.X2)
170 assert (0);
171 if (node->u.kids[i]->box.Y1 < node->box.Y1)
172 assert (0);
173 if (node->u.kids[i]->box.Y2 > node->box.Y2)
174 assert (0);
175 }
176 flag <<= 1;
177 }
178 /* check that we're completely in the parent's bounds */
179 if (node->parent)
180 {
181 if (node->parent->box.X1 > node->box.X1)
182 assert (0);
183 if (node->parent->box.X2 < node->box.X2)
184 assert (0);
185 if (node->parent->box.Y1 > node->box.Y1)
186 assert (0);
187 if (node->parent->box.Y2 < node->box.Y2)
188 assert (0);
189 }
190 /* make sure overflow is empty */
191 if (!node->flags.is_leaf && node->u.kids[i])
192 assert (0);
193 if (node->flags.is_leaf && node->u.rects[i].bptr)
194 assert (0);
195 return 1;
196 }
197
198 /*!
199 * \brief Check the whole tree from this node down for consistency.
200 */
201 static bool
__r_tree_is_good(struct rtree_node * node)202 __r_tree_is_good (struct rtree_node *node)
203 {
204 int i;
205
206 if (!node)
207 return 1;
208 if (!__r_node_is_good (node))
209 assert (0);
210 if (node->flags.is_leaf)
211 return 1;
212 for (i = 0; i < M_SIZE; i++)
213 {
214 if (!__r_tree_is_good (node->u.kids[i]))
215 return 0;
216 }
217 return 1;
218 }
219 #endif
220 #endif
221
222 #ifndef NDEBUG
223 /*!
224 * \brief Print out the tree.
225 */
226 void
__r_dump_tree(struct rtree_node * node,int depth)227 __r_dump_tree (struct rtree_node *node, int depth)
228 {
229 int i, j;
230 static int count;
231 static double area;
232
233 if (depth == 0)
234 {
235 area = 0;
236 count = 0;
237 }
238 area +=
239 (node->box.X2 - node->box.X1) * (double) (node->box.Y2 - node->box.Y1);
240 count++;
241 for (i = 0; i < depth; i++)
242 printf (" ");
243 if (!node->flags.is_leaf)
244 {
245 printf (
246 "p=0x%p node X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64 ", %" PRIi64
247 ")\n",
248 (void *) node,
249 (int64_t) (node->box.X1),
250 (int64_t) (node->box.X2),
251 (int64_t) (node->box.Y1),
252 (int64_t) (node->box.Y2) );
253 }
254 else
255 {
256 printf (
257 "p=0x%p leaf manage(%02x) X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64
258 ", %" PRIi64 ")\n",
259 (void *) node,
260 node->flags.manage,
261 (int64_t) (node->box.X1),
262 (int64_t) (node->box.X2),
263 (int64_t) (node->box.Y1),
264 (int64_t) (node->box.Y2) );
265 for (j = 0; j < M_SIZE; j++)
266 {
267 if (!node->u.rects[j].bptr)
268 break;
269 area +=
270 (node->u.rects[j].bounds.X2 -
271 node->u.rects[j].bounds.X1) *
272 (double) (node->u.rects[j].bounds.Y2 -
273 node->u.rects[j].bounds.Y1);
274 count++;
275 for (i = 0; i < depth + 1; i++)
276 printf (" ");
277 printf (
278 "entry 0x%p X(%" PRIi64 ", %" PRIi64 ") Y(%" PRIi64 ", "
279 "%" PRIi64 ")\n",
280 (void *) (node->u.rects[j].bptr),
281 (int64_t) (node->u.rects[j].bounds.X1),
282 (int64_t) (node->u.rects[j].bounds.X2),
283 (int64_t) (node->u.rects[j].bounds.Y1),
284 (int64_t) (node->u.rects[j].bounds.Y2) );
285 }
286 return;
287 }
288 for (i = 0; i < M_SIZE; i++)
289 if (node->u.kids[i])
290 __r_dump_tree (node->u.kids[i], depth + 1);
291 if (depth == 0)
292 printf ("average box area is %g\n", area / count);
293 }
294 #endif
295
296 #ifdef SORT
297 /*!
298 * \brief Sort the children or entries of a node according to the
299 * largest side.
300 *
301 * Compare two box coordinates so that the __r_search will fail at the
302 * earliest comparison possible.
303 *
304 * It needs to see the biggest X1 first, then the smallest X2, the
305 * biggest Y1 and smallest Y2.
306 */
307 static int
cmp_box(const BoxType * a,const BoxType * b)308 cmp_box (const BoxType * a, const BoxType * b)
309 {
310 if (a->X1 < b->X1)
311 return 0;
312 if (a->X1 > b->X1)
313 return 1;
314 if (a->X2 > b->X2)
315 return 0;
316 if (a->X2 < b->X2)
317 return 1;
318 if (a->Y1 < b->Y1)
319 return 0;
320 if (a->Y1 > b->Y1)
321 return 1;
322 if (a->Y2 > b->Y2)
323 return 0;
324 return 1;
325 }
326
327 static void
sort_node(struct rtree_node * node)328 sort_node (struct rtree_node *node)
329 {
330 if (node->flags.is_leaf)
331 {
332 register Rentry *r, *i, temp;
333
334 for (r = &node->u.rects[1]; r->bptr; r++)
335 {
336 temp = *r;
337 i = r - 1;
338 while (i >= &node->u.rects[0])
339 {
340 if (cmp_box (&i->bounds, &r->bounds))
341 break;
342 *(i + 1) = *i;
343 i--;
344 }
345 *(i + 1) = temp;
346 }
347 }
348 #ifdef SORT_NONLEAF
349 else
350 {
351 register struct rtree_node **r, **i, *temp;
352
353 for (r = &node->u.kids[1]; *r; r++)
354 {
355 temp = *r;
356 i = r - 1;
357 while (i >= &node->u.kids[0])
358 {
359 if (cmp_box (&(*i)->box, &(*r)->box))
360 break;
361 *(i + 1) = *i;
362 i--;
363 }
364 *(i + 1) = temp;
365 }
366 }
367 #endif
368 }
369 #else
370 #define sort_node(x)
371 #endif
372
373 /*!
374 * \brief Set the node bounds large enough to encompass all of the
375 * children's rectangles.
376 */
377 static void
adjust_bounds(struct rtree_node * node)378 adjust_bounds (struct rtree_node *node)
379 {
380 int i;
381
382 assert (node);
383 assert (node->u.kids[0]);
384 if (node->flags.is_leaf)
385 {
386 node->box = node->u.rects[0].bounds;
387 for (i = 1; i < M_SIZE + 1; i++)
388 {
389 if (!node->u.rects[i].bptr)
390 return;
391 MAKEMIN (node->box.X1, node->u.rects[i].bounds.X1);
392 MAKEMAX (node->box.X2, node->u.rects[i].bounds.X2);
393 MAKEMIN (node->box.Y1, node->u.rects[i].bounds.Y1);
394 MAKEMAX (node->box.Y2, node->u.rects[i].bounds.Y2);
395 }
396 }
397 else
398 {
399 node->box = node->u.kids[0]->box;
400 for (i = 1; i < M_SIZE + 1; i++)
401 {
402 if (!node->u.kids[i])
403 return;
404 MAKEMIN (node->box.X1, node->u.kids[i]->box.X1);
405 MAKEMAX (node->box.X2, node->u.kids[i]->box.X2);
406 MAKEMIN (node->box.Y1, node->u.kids[i]->box.Y1);
407 MAKEMAX (node->box.Y2, node->u.kids[i]->box.Y2);
408 }
409 }
410 }
411
412 /*!
413 * \brief Create an r-tree from an unsorted list of boxes.
414 *
415 * Create an rtree from the list of boxes. If 'manage' is true, then
416 * the tree will take ownership of 'boxlist' and free it when the tree
417 * is destroyed.
418 *
419 * The r-tree will keep pointers into it, so don't free the box list
420 * until you've called r_destroy_tree.
421 *
422 * If you set 'manage' to true, r_destroy_tree will free your boxlist.
423 */
424 rtree_t *
r_create_tree(const BoxType * boxlist[],int N,int manage)425 r_create_tree (const BoxType * boxlist[], int N, int manage)
426 {
427 rtree_t *rtree;
428 struct rtree_node *node;
429 int i;
430
431 assert (N >= 0);
432 rtree = (rtree_t *)calloc (1, sizeof (*rtree));
433 /* start with a single empty leaf node */
434 node = (struct rtree_node *)calloc (1, sizeof (*node));
435 node->flags.is_leaf = 1;
436 node->parent = NULL;
437 rtree->root = node;
438 /* simple, just insert all of the boxes! */
439 for (i = 0; i < N; i++)
440 {
441 assert (boxlist[i]);
442 r_insert_entry (rtree, boxlist[i], manage);
443 }
444 #ifdef SLOW_ASSERTS
445 assert (__r_tree_is_good (rtree->root));
446 #endif
447 return rtree;
448 }
449
450 /*!
451 * \brief Destroy an rtree.
452 */
453 static void
__r_destroy_tree(struct rtree_node * node)454 __r_destroy_tree (struct rtree_node *node)
455 {
456 int i, flag = 1;
457
458 if (node->flags.is_leaf)
459 for (i = 0; i < M_SIZE; i++)
460 {
461 if (!node->u.rects[i].bptr)
462 break;
463 if (node->flags.manage & flag)
464 free ((void *) node->u.rects[i].bptr);
465 flag = flag << 1;
466 }
467 else
468 for (i = 0; i < M_SIZE; i++)
469 {
470 if (!node->u.kids[i])
471 break;
472 __r_destroy_tree (node->u.kids[i]);
473 }
474 free (node);
475 }
476
477 /*!
478 * \brief Free the memory associated with an rtree.
479 */
480 void
r_destroy_tree(rtree_t ** rtree)481 r_destroy_tree (rtree_t ** rtree)
482 {
483
484 __r_destroy_tree ((*rtree)->root);
485 free (*rtree);
486 *rtree = NULL;
487 }
488
489 typedef struct
490 {
491 int (*check_it) (const BoxType * region, void *cl);
492 int (*found_it) (const BoxType * box, void *cl);
493 void *closure;
494 } r_arg;
495
496 /*!
497 * \brief .
498 *
499 * Most of the auto-routing time is spent in this routine so some
500 * careful thought has been given to maximizing the speed.
501 *
502 */
503 int
__r_search(struct rtree_node * node,const BoxType * query,r_arg * arg)504 __r_search (struct rtree_node *node, const BoxType * query, r_arg * arg)
505 {
506 assert (node);
507 /* assert that starting_region is well formed */
508 assert (query->X1 < query->X2 && query->Y1 < query->Y2);
509 assert (node->box.X1 < query->X2 && node->box.X2 > query->X1 &&
510 node->box.Y1 < query->Y2 && node->box.Y2 > query->Y1);
511 #ifdef SLOW_ASSERTS
512 /* assert that node is well formed */
513 assert (__r_node_is_good (node));
514 #endif
515 /* the check for bounds is done before entry. This saves the overhead
516 * of building/destroying the stack frame for each bounds that fails
517 * to intersect, which is the most common condition.
518 */
519 if (node->flags.is_leaf)
520 {
521 register int i;
522 if (arg->found_it) /* test this once outside of loop */
523 {
524 register int seen = 0;
525 for (i = 0; node->u.rects[i].bptr; i++)
526 {
527 if ((node->u.rects[i].bounds.X1 < query->X2) &&
528 (node->u.rects[i].bounds.X2 > query->X1) &&
529 (node->u.rects[i].bounds.Y1 < query->Y2) &&
530 (node->u.rects[i].bounds.Y2 > query->Y1) &&
531 arg->found_it (node->u.rects[i].bptr, arg->closure))
532 seen++;
533 }
534 return seen;
535 }
536 else
537 {
538 register int seen = 0;
539 for (i = 0; node->u.rects[i].bptr; i++)
540 {
541 if ((node->u.rects[i].bounds.X1 < query->X2) &&
542 (node->u.rects[i].bounds.X2 > query->X1) &&
543 (node->u.rects[i].bounds.Y1 < query->Y2) &&
544 (node->u.rects[i].bounds.Y2 > query->Y1))
545 seen++;
546 }
547 return seen;
548 }
549 }
550
551 /* not a leaf, recurse on lower nodes */
552 if (arg->check_it)
553 {
554 int seen = 0;
555 struct rtree_node **n;
556 for (n = &node->u.kids[0]; *n; n++)
557 {
558 if ((*n)->box.X1 >= query->X2 ||
559 (*n)->box.X2 <= query->X1 ||
560 (*n)->box.Y1 >= query->Y2 || (*n)->box.Y2 <= query->Y1 ||
561 !arg->check_it (&(*n)->box, arg->closure))
562 continue;
563 seen += __r_search (*n, query, arg);
564 }
565 return seen;
566 }
567 else
568 {
569 int seen = 0;
570 struct rtree_node **n;
571 for (n = &node->u.kids[0]; *n; n++)
572 {
573 if ((*n)->box.X1 >= query->X2 ||
574 (*n)->box.X2 <= query->X1 ||
575 (*n)->box.Y1 >= query->Y2 || (*n)->box.Y2 <= query->Y1)
576 continue;
577 seen += __r_search (*n, query, arg);
578 }
579 return seen;
580 }
581 }
582
583 /*!
584 * \brief Parameterized search in the rtree.
585 *
586 * Calls found_rectangle for each intersection seen and calls
587 * \c check_region with the current sub-region to see whether deeper
588 * searching is desired.
589 *
590 * Generic search routine.
591 *
592 * \c region_in_search should return true if "what you're looking for"
593 * is within the specified region; regions, like rectangles, are closed
594 * on top and left and open on bottom and right.
595 *
596 * rectangle_in_region should return true if the given rectangle is
597 * "what you're looking for".
598 *
599 * The search will find all rectangles matching the criteria given
600 * by region_in_search and rectangle_in_region and return a count of
601 * how many things rectangle_in_region returned true for.
602 *
603 * Closure is used to abort the search if desired from within
604 * rectangel_in_region.
605 *
606 * Look at the implementation of r_region_is_empty for how to abort the
607 * search if that is the desired behavior.
608 *
609 * \return the number of rectangles found.
610 */
611 int
r_search(rtree_t * rtree,const BoxType * query,int (* check_region)(const BoxType * region,void * cl),int (* found_rectangle)(const BoxType * box,void * cl),void * cl)612 r_search (rtree_t * rtree, const BoxType * query,
613 int (*check_region) (const BoxType * region, void *cl),
614 int (*found_rectangle) (const BoxType * box, void *cl), void *cl)
615 {
616 r_arg arg;
617
618 if (!rtree || rtree->size < 1)
619 return 0;
620 if (query)
621 {
622 #ifdef SLOW_ASSERTS
623 assert (__r_tree_is_good (rtree->root));
624 #endif
625 #ifdef DEBUG
626 if (query->X2 <= query->X1 || query->Y2 <= query->Y1)
627 return 0;
628 #endif
629 /* check this box. If it's not touched we're done here */
630 if (rtree->root->box.X1 >= query->X2 ||
631 rtree->root->box.X2 <= query->X1 ||
632 rtree->root->box.Y1 >= query->Y2
633 || rtree->root->box.Y2 <= query->Y1)
634 return 0;
635 arg.check_it = check_region;
636 arg.found_it = found_rectangle;
637 arg.closure = cl;
638 return __r_search (rtree->root, query, &arg);
639 }
640 else
641 {
642 arg.check_it = check_region;
643 arg.found_it = found_rectangle;
644 arg.closure = cl;
645 return __r_search (rtree->root, &rtree->root->box, &arg);
646 }
647 }
648
649 /*!
650 * \brief r_region_is_empty.
651 */
652 static int
__r_region_is_empty_rect_in_reg(const BoxType * box,void * cl)653 __r_region_is_empty_rect_in_reg (const BoxType * box, void *cl)
654 {
655 jmp_buf *envp = (jmp_buf *) cl;
656 longjmp (*envp, 1); /* found one! */
657 }
658
659 /*!
660 * \brief Special-purpose searches build upon r_search.
661 *
662 * \return 0 if there are any rectangles in the given region.
663 */
664 int
r_region_is_empty(rtree_t * rtree,const BoxType * region)665 r_region_is_empty (rtree_t * rtree, const BoxType * region)
666 {
667 jmp_buf env;
668 #ifndef NDEBUG
669 int r;
670 #endif
671
672 if (setjmp (env))
673 return 0;
674 #ifndef NDEBUG
675 r =
676 #endif
677 r_search (rtree, region, NULL, __r_region_is_empty_rect_in_reg, &env);
678 #ifndef NDEBUG
679 assert (r == 0); /* otherwise longjmp would have been called */
680 #endif
681 return 1; /* no rectangles found */
682 }
683
684 struct centroid
685 {
686 float x, y, area;
687 };
688
689 /*!
690 * \brief Split the node into two nodes putting clusters in each use the
691 * k-means clustering algorithm.
692 */
693 struct rtree_node *
find_clusters(struct rtree_node * node)694 find_clusters (struct rtree_node *node)
695 {
696 float total_a, total_b;
697 float a_X, a_Y, b_X, b_Y;
698 bool belong[M_SIZE + 1];
699 struct centroid center[M_SIZE + 1];
700 int clust_a, clust_b, tries;
701 int a_manage = 0, b_manage = 0;
702 int i, old_ax, old_ay, old_bx, old_by;
703 struct rtree_node *new_node;
704 BoxType *b;
705
706 for (i = 0; i < M_SIZE + 1; i++)
707 {
708 if (node->flags.is_leaf)
709 b = &(node->u.rects[i].bounds);
710 else
711 b = &(node->u.kids[i]->box);
712 center[i].x = 0.5 * (b->X1 + b->X2);
713 center[i].y = 0.5 * (b->Y1 + b->Y2);
714 /* adding 1 prevents zero area */
715 center[i].area = 1. + (float) (b->X2 - b->X1) * (float) (b->Y2 - b->Y1);
716 }
717 /* starting 'A' cluster center */
718 a_X = center[0].x;
719 a_Y = center[0].y;
720 /* starting 'B' cluster center */
721 b_X = center[M_SIZE].x;
722 b_Y = center[M_SIZE].y;
723 /* don't allow the same cluster centers */
724 if (b_X == a_X && b_Y == a_Y)
725 {
726 b_X += 10000;
727 a_Y -= 10000;
728 }
729 for (tries = 0; tries < M_SIZE; tries++)
730 {
731 old_ax = (int) a_X;
732 old_ay = (int) a_Y;
733 old_bx = (int) b_X;
734 old_by = (int) b_Y;
735 clust_a = clust_b = 0;
736 for (i = 0; i < M_SIZE + 1; i++)
737 {
738 float dist1, dist2;
739
740 dist1 = SQUARE (a_X - center[i].x) + SQUARE (a_Y - center[i].y);
741 dist2 = SQUARE (b_X - center[i].x) + SQUARE (b_Y - center[i].y);
742 if (dist1 * (clust_a + M_SIZE / 2) < dist2 * (clust_b + M_SIZE / 2))
743 {
744 belong[i] = true;
745 clust_a++;
746 }
747 else
748 {
749 belong[i] = false;
750 clust_b++;
751 }
752 }
753 /* kludge to fix degenerate cases */
754 if (clust_a == M_SIZE + 1)
755 belong[M_SIZE / 2] = false;
756 else if (clust_b == M_SIZE + 1)
757 belong[M_SIZE / 2] = true;
758 /* compute new center of gravity of clusters */
759 total_a = total_b = 0;
760 a_X = a_Y = b_X = b_Y = 0;
761 for (i = 0; i < M_SIZE + 1; i++)
762 {
763 if (belong[i])
764 {
765 a_X += center[i].x * center[i].area;
766 a_Y += center[i].y * center[i].area;
767 total_a += center[i].area;
768 }
769 else
770 {
771 b_X += center[i].x * center[i].area;
772 b_Y += center[i].y * center[i].area;
773 total_b += center[i].area;
774 }
775 }
776 a_X /= total_a;
777 a_Y /= total_a;
778 b_X /= total_b;
779 b_Y /= total_b;
780 if (old_ax == (int) a_X && old_ay == (int) a_Y &&
781 old_bx == (int) b_X && old_by == (int) b_Y)
782 break;
783 }
784 /* Now 'belong' has the partition map */
785 new_node = (struct rtree_node *)calloc (1, sizeof (*new_node));
786 new_node->parent = node->parent;
787 new_node->flags.is_leaf = node->flags.is_leaf;
788 clust_a = clust_b = 0;
789 if (node->flags.is_leaf)
790 {
791 int flag, a_flag, b_flag;
792 flag = a_flag = b_flag = 1;
793 for (i = 0; i < M_SIZE + 1; i++)
794 {
795 if (belong[i])
796 {
797 node->u.rects[clust_a++] = node->u.rects[i];
798 if (node->flags.manage & flag)
799 a_manage |= a_flag;
800 a_flag <<= 1;
801 }
802 else
803 {
804 new_node->u.rects[clust_b++] = node->u.rects[i];
805 if (node->flags.manage & flag)
806 b_manage |= b_flag;
807 b_flag <<= 1;
808 }
809 flag <<= 1;
810 }
811 }
812 else
813 {
814 for (i = 0; i < M_SIZE + 1; i++)
815 {
816 if (belong[i])
817 node->u.kids[clust_a++] = node->u.kids[i];
818 else
819 {
820 node->u.kids[i]->parent = new_node;
821 new_node->u.kids[clust_b++] = node->u.kids[i];
822 }
823 }
824 }
825 node->flags.manage = a_manage;
826 new_node->flags.manage = b_manage;
827 assert (clust_a != 0);
828 assert (clust_b != 0);
829 if (node->flags.is_leaf)
830 for (; clust_a < M_SIZE + 1; clust_a++)
831 node->u.rects[clust_a].bptr = NULL;
832 else
833 for (; clust_a < M_SIZE + 1; clust_a++)
834 node->u.kids[clust_a] = NULL;
835 adjust_bounds (node);
836 sort_node (node);
837 adjust_bounds (new_node);
838 sort_node (new_node);
839 return (new_node);
840 }
841
842 /*!
843 * \brief Split a node according to clusters.
844 */
845 static void
split_node(struct rtree_node * node)846 split_node (struct rtree_node *node)
847 {
848 int i;
849 struct rtree_node *new_node;
850
851 assert (node);
852 assert (node->flags.is_leaf ? (void *) node->u.rects[M_SIZE].
853 bptr : (void *) node->u.kids[M_SIZE]);
854 new_node = find_clusters (node);
855 if (node->parent == NULL) /* split root node */
856 {
857 struct rtree_node *second;
858
859 second = (struct rtree_node *)calloc (1, sizeof (*second));
860 *second = *node;
861 if (!second->flags.is_leaf)
862 for (i = 0; i < M_SIZE; i++)
863 if (second->u.kids[i])
864 second->u.kids[i]->parent = second;
865 node->flags.is_leaf = 0;
866 node->flags.manage = 0;
867 second->parent = new_node->parent = node;
868 node->u.kids[0] = new_node;
869 node->u.kids[1] = second;
870 for (i = 2; i < M_SIZE + 1; i++)
871 node->u.kids[i] = NULL;
872 adjust_bounds (node);
873 sort_node (node);
874 #ifdef SLOW_ASSERTS
875 assert (__r_tree_is_good (node));
876 #endif
877 return;
878 }
879 for (i = 0; i < M_SIZE; i++)
880 if (!node->parent->u.kids[i])
881 break;
882 node->parent->u.kids[i] = new_node;
883 #ifdef SLOW_ASSERTS
884 assert (__r_node_is_good (node));
885 assert (__r_node_is_good (new_node));
886 #endif
887 if (i < M_SIZE)
888 {
889 #ifdef SLOW_ASSERTS
890 assert (__r_node_is_good (node->parent));
891 #endif
892 sort_node (node->parent);
893 return;
894 }
895 split_node (node->parent);
896 }
897
898 static inline int
contained(struct rtree_node * node,const BoxType * query)899 contained (struct rtree_node *node, const BoxType * query)
900 {
901 if (node->box.X1 > query->X1 || node->box.X2 < query->X2 ||
902 node->box.Y1 > query->Y1 || node->box.Y2 < query->Y2)
903 return 0;
904 return 1;
905 }
906
907
908 /*!
909 * \brief Compute the area penalty for inserting here and return.
910 *
911 * The penalty is the increase in area necessary to include the query.
912 */
913 static inline double
penalty(struct rtree_node * node,const BoxType * query)914 penalty (struct rtree_node *node, const BoxType * query)
915 {
916 double score;
917
918 score = (MAX (node->box.X2, query->X2) - MIN (node->box.X1, query->X1));
919 score *= (MAX (node->box.Y2, query->Y2) - MIN (node->box.Y1, query->Y1));
920 score -=
921 (double)(node->box.X2 - node->box.X1) *
922 (double)(node->box.Y2 - node->box.Y1);
923 return score;
924 }
925
926 static void
__r_insert_node(struct rtree_node * node,const BoxType * query,int manage,bool force)927 __r_insert_node (struct rtree_node *node, const BoxType * query,
928 int manage, bool force)
929 {
930
931 #ifdef SLOW_ASSERTS
932 assert (__r_node_is_good (node));
933 #endif
934 /* Ok, at this point we must already enclose the query or we're forcing
935 * this node to expand to enclose it, so if we're a leaf, simply store
936 * the query here
937 */
938
939 if (node->flags.is_leaf)
940 {
941 register int i;
942
943 if (UNLIKELY (manage))
944 {
945 register int flag = 1;
946
947 for (i = 0; i < M_SIZE; i++)
948 {
949 if (!node->u.rects[i].bptr)
950 break;
951 flag <<= 1;
952 }
953 node->flags.manage |= flag;
954 }
955 else
956 {
957 for (i = 0; i < M_SIZE; i++)
958 if (!node->u.rects[i].bptr)
959 break;
960 }
961 /* the node always has an extra space available */
962 node->u.rects[i].bptr = query;
963 node->u.rects[i].bounds = *query;
964 /* first entry in node determines initial bounding box */
965 if (i == 0)
966 node->box = *query;
967 else if (force)
968 {
969 MAKEMIN (node->box.X1, query->X1);
970 MAKEMAX (node->box.X2, query->X2);
971 MAKEMIN (node->box.Y1, query->Y1);
972 MAKEMAX (node->box.Y2, query->Y2);
973 }
974 if (i < M_SIZE)
975 {
976 sort_node (node);
977 return;
978 }
979 /* we must split the node */
980 split_node (node);
981 return;
982 }
983 else
984 {
985 int i;
986 struct rtree_node *best_node;
987 double score, best_score;
988
989 if (force)
990 {
991 MAKEMIN (node->box.X1, query->X1);
992 MAKEMAX (node->box.X2, query->X2);
993 MAKEMIN (node->box.Y1, query->Y1);
994 MAKEMAX (node->box.Y2, query->Y2);
995 }
996
997 /* this node encloses it, but it's not a leaf, so descend the tree */
998
999 /* First check if any children actually encloses it */
1000 assert (node->u.kids[0]);
1001 for (i = 0; i < M_SIZE; i++)
1002 {
1003 if (!node->u.kids[i])
1004 break;
1005 if (contained (node->u.kids[i], query))
1006 {
1007 __r_insert_node (node->u.kids[i], query, manage, false);
1008 sort_node (node);
1009 return;
1010 }
1011 }
1012
1013 /* see if there is room for a new leaf node */
1014 if (node->u.kids[0]->flags.is_leaf && i < M_SIZE)
1015 {
1016 struct rtree_node *new_node;
1017 new_node = (struct rtree_node *)calloc (1, sizeof (*new_node));
1018 new_node->parent = node;
1019 new_node->flags.is_leaf = true;
1020 node->u.kids[i] = new_node;
1021 new_node->u.rects[0].bptr = query;
1022 new_node->u.rects[0].bounds = *query;
1023 new_node->box = *query;
1024 if (UNLIKELY (manage))
1025 new_node->flags.manage = 1;
1026 sort_node (node);
1027 return;
1028 }
1029
1030 /* Ok, so we're still here - look for the best child to push it into */
1031 best_score = penalty (node->u.kids[0], query);
1032 best_node = node->u.kids[0];
1033 for (i = 1; i < M_SIZE; i++)
1034 {
1035 if (!node->u.kids[i])
1036 break;
1037 score = penalty (node->u.kids[i], query);
1038 if (score < best_score)
1039 {
1040 best_score = score;
1041 best_node = node->u.kids[i];
1042 }
1043 }
1044 __r_insert_node (best_node, query, manage, true);
1045 sort_node (node);
1046 return;
1047 }
1048 }
1049
1050 void
r_insert_entry(rtree_t * rtree,const BoxType * which,int man)1051 r_insert_entry (rtree_t * rtree, const BoxType * which, int man)
1052 {
1053 assert (which);
1054 assert (which->X1 <= which->X2);
1055 assert (which->Y1 <= which->Y2);
1056 /* recursively search the tree for the best leaf node */
1057 assert (rtree->root);
1058 __r_insert_node (rtree->root, which, man,
1059 rtree->root->box.X1 > which->X1
1060 || rtree->root->box.X2 < which->X2
1061 || rtree->root->box.Y1 > which->Y1
1062 || rtree->root->box.Y2 < which->Y2);
1063 rtree->size++;
1064 }
1065
1066 bool
__r_delete(struct rtree_node * node,const BoxType * query)1067 __r_delete (struct rtree_node *node, const BoxType * query)
1068 {
1069 int i, flag, mask, a;
1070
1071 /* the tree might be inconsistent during delete */
1072 if (query->X1 < node->box.X1 || query->Y1 < node->box.Y1
1073 || query->X2 > node->box.X2 || query->Y2 > node->box.Y2)
1074 return false;
1075 if (!node->flags.is_leaf)
1076 {
1077 for (i = 0; i < M_SIZE; i++)
1078 {
1079 /* if this is us being removed, free and copy over */
1080 if (node->u.kids[i] == (struct rtree_node *) query)
1081 {
1082 free ((void *) query);
1083 for (; i < M_SIZE; i++)
1084 {
1085 node->u.kids[i] = node->u.kids[i + 1];
1086 if (!node->u.kids[i])
1087 break;
1088 }
1089 /* nobody home here now ? */
1090 if (!node->u.kids[0])
1091 {
1092 if (!node->parent)
1093 {
1094 /* wow, the root is empty! */
1095 node->flags.is_leaf = 1;
1096 /* changing type of node, be sure it's all zero */
1097 for (i = 1; i < M_SIZE + 1; i++)
1098 node->u.rects[i].bptr = NULL;
1099 return true;
1100 }
1101 return (__r_delete (node->parent, &node->box));
1102 }
1103 else
1104 /* propegate boundary adjust upward */
1105 while (node)
1106 {
1107 adjust_bounds (node);
1108 node = node->parent;
1109 }
1110 return true;
1111 }
1112 if (node->u.kids[i])
1113 {
1114 if (__r_delete (node->u.kids[i], query))
1115 return true;
1116 }
1117 else
1118 break;
1119 }
1120 return false;
1121 }
1122 /* leaf node here */
1123 mask = 0;
1124 a = 1;
1125 for (i = 0; i < M_SIZE; i++)
1126 {
1127 #ifdef DELETE_BY_POINTER
1128 if (!node->u.rects[i].bptr || node->u.rects[i].bptr == query)
1129 #else
1130 if (node->u.rects[i].bounds.X1 == query->X1 &&
1131 node->u.rects[i].bounds.X2 == query->X2 &&
1132 node->u.rects[i].bounds.Y1 == query->Y1 &&
1133 node->u.rects[i].bounds.Y2 == query->Y2)
1134 #endif
1135 break;
1136 mask |= a;
1137 a <<= 1;
1138 }
1139 if (!node->u.rects[i].bptr)
1140 return false; /* not at this leaf */
1141 if (node->flags.manage & a)
1142 {
1143 free ((void *) node->u.rects[i].bptr);
1144 node->u.rects[i].bptr = NULL;
1145 }
1146 /* squeeze the manage flags together */
1147 flag = node->flags.manage & mask;
1148 mask = (~mask) << 1;
1149 node->flags.manage = flag | ((node->flags.manage & mask) >> 1);
1150 /* remove the entry */
1151 for (; i < M_SIZE; i++)
1152 {
1153 node->u.rects[i] = node->u.rects[i + 1];
1154 if (!node->u.rects[i].bptr)
1155 break;
1156 }
1157 if (!node->u.rects[0].bptr)
1158 {
1159 if (node->parent)
1160 __r_delete (node->parent, &node->box);
1161 return true;
1162 }
1163 else
1164 /* propagate boundary adjustment upward */
1165 while (node)
1166 {
1167 adjust_bounds (node);
1168 node = node->parent;
1169 }
1170 return true;
1171 }
1172
1173 bool
r_delete_entry(rtree_t * rtree,const BoxType * box)1174 r_delete_entry (rtree_t * rtree, const BoxType * box)
1175 {
1176 bool r;
1177
1178 assert (box);
1179 assert (rtree);
1180 r = __r_delete (rtree->root, box);
1181 if (r)
1182 rtree->size--;
1183 #ifdef SLOW_ASSERTS
1184 assert (__r_tree_is_good (rtree->root));
1185 #endif
1186 return r;
1187 }
1188