6 static void _trap(int line)
9 printf("Trapped from line %d, use debugger to get backtrace\n",
16 #define trap() _trap(__LINE__)
18 static int quadtree_compare_coord(const struct vector *a,
19 const struct vector *b)
35 static int quadtree_compare(const struct quadtree *a, const struct quadtree *b)
37 return quadtree_compare_coord(&a->pos, &b->pos);
40 static void validate_subtree(const struct quadtree *node)
47 printf("Attempted to validate a null pointer\n");
52 for (i = 0; i < 4; i++) {
56 if (node->child[i]->parent != node) {
57 printf("%s:%d Fatal! Tree inconsistency detected at "
58 "child %d %p in node %p, incorrent parent %p\n",
59 __func__, __LINE__, i, node->child[i], node,
60 node->child[i]->parent);
66 if (node->child[i] == node->parent) {
67 printf("%s:%d Fatal! Tree loop detected "
68 "at child %d in node %p\n",
69 __func__, __LINE__, i, node);
75 dir = quadtree_compare(node, node->child[i]);
78 printf("%s:%d Fatal! Spatial inconsistency detected "
79 "at child %d in node %p\n"
80 "parent: (%f %f), child (%f %f), "
82 __func__, __LINE__, i, node,
83 node->pos.x, node->pos.y,
84 node->child[i]->pos.x, node->child[i]->pos.y,
90 children += node->child[i]->children + 1;
92 validate_subtree(node->child[i]);
95 if (node->depth < 0) {
96 printf("%s:%d Tree statistics inconsistency detected! "
97 "Negative depth: %ld\n",
98 __func__, __LINE__, node->depth);
101 if (node->children != children) {
102 printf("%s:%d Tree statistics inconsistency detected! "
103 "child count mismatch. Expected %ld, got %ld\n",
104 __func__, __LINE__, children, node->children);
109 for (i = 0; i < 4 && node->children; i++) {
113 if (node->depth == node->child[i]->depth + 1)
116 if (node->child[i]->depth > node->depth) {
117 printf("%s:%d Tree statistics inconsistency detected! "
118 "child depth mismatch %ld > %ld\n",
119 __func__, __LINE__, node->child[i]->depth,
125 printf("%s:%d Tree statistics inconsistency detected! "
126 "child depth mismatch.",
133 static void validate_tree(const struct quadtree *node)
141 return validate_subtree(node);
143 for (i = 0; i < 4; i++)
144 if (node->parent->child[i] == node)
148 printf("%s:%d Tree inconsistency detected! "
149 "Wrong parent %p for node %p\n",
150 __func__, __LINE__, node->parent, node);
155 validate_tree(node->parent);
158 void _quadtree_validate_tree(const struct quadtree *node)
163 static struct quadtree *_quadtree_add(struct quadtree *parent,
164 struct quadtree *new)
168 ret = quadtree_compare(parent, new);
170 if (ret < 0 || ret >= 4) {
171 printf("Invalid comparison result of %d\n", ret);
175 if (parent->child[ret])
176 return _quadtree_add(parent->child[ret], new);
178 parent->child[ret] = new;
179 new->parent = parent;
180 for (i = 0; i < 4; i++)
187 * quadtree_add - add a node to a quadtree
188 * @parent: parent node
189 * @new: the new node to be added
191 * Add a node to a quadtree. The tree is kept in order, the new node
192 * is placed in the end of appropriate branch.
194 * The case of nodes sharing identical coordinates is not taken into
198 struct quadtree *quadtree_add(struct quadtree *parent, struct quadtree *new,
199 struct quadtree_ops *ops)
204 validate_tree(parent);
206 _quadtree_add(parent, new);
209 printf("adding node %p to parent %p\n", new, parent);
213 quadtree_recalculate_parent_stats(new, ops);
220 static double max_by_dir(double a, double b, int direction)
235 static double maxv_by_dir(struct quadtree *a, int direction)
250 static double quadtree_get_max_dimension(struct quadtree *node, int direction)
252 struct quadtree *ch1 = NULL, *ch2 = NULL;
257 ch1 = node->child[0];
258 ch2 = node->child[1];
261 ch1 = node->child[1];
262 ch2 = node->child[3];
265 ch1 = node->child[2];
266 ch2 = node->child[3];
269 ch1 = node->child[0];
270 ch2 = node->child[2];
277 a = quadtree_get_max_dimension(ch1, direction);
278 b = quadtree_get_max_dimension(ch2, direction);
279 return max_by_dir(a, b, direction);
283 a = quadtree_get_max_dimension(ch1, direction);
284 b = maxv_by_dir(ch1, direction);
285 return max_by_dir(a, b, direction);
288 a = quadtree_get_max_dimension(ch2, direction);
289 b = maxv_by_dir(ch2, direction);
290 return max_by_dir(a, b, direction);
293 return maxv_by_dir(node, direction);
297 * Stores the lower right and upper left corner coordinates to the
300 static void quadtree_get_tree_dimensions(struct quadtree *node,
301 struct vector *corner)
303 corner[0].y = quadtree_get_max_dimension(node, 2);
304 corner[0].x = quadtree_get_max_dimension(node, 1);
305 corner[1].y = quadtree_get_max_dimension(node, 0);
306 corner[1].x = quadtree_get_max_dimension(node, 3);
309 printf("\nInitial Search rectangle (%f %f) (%f %f), (%f %f)\n",
310 corner[0].x, corner[0].y,
311 corner[1].x, corner[1].y,
312 node->pos.x, node->pos.y);
316 if ((corner[0].x < corner[1].x) ||
317 (corner[0].y < corner[1].y))
321 static int is_within(struct vector *pos, struct vector *corner)
323 if ((pos->x >= corner[1].x) && (pos->x <= corner[0].x) &&
324 (pos->y >= corner[1].y) && (pos->y <= corner[0].y))
329 static int quadrants_to_search(struct quadtree *node, struct vector *corner)
331 int direction = 0, i;
332 int up = 0, left = 0, right = 0, down = 0;
334 for (i = 0; i < 2; i++) {
335 if (corner[i].x <= node->pos.x)
337 else if (corner[i].x >= node->pos.x)
339 if (corner[i].y <= node->pos.y)
341 else if (corner[i].y >= node->pos.y)
346 direction |= QUADTREE_UPLEFT;
348 direction |= QUADTREE_UPRIGHT;
350 direction |= QUADTREE_DOWNLEFT;
352 direction |= QUADTREE_DOWNRIGHT;
357 static struct quadtree *quadtree_find_nearest(struct quadtree *tree,
359 struct vector *corner)
362 struct quadtree *nearest, *node;
363 double distance = 0, dist;
366 if (!is_within(pos, corner)) {
368 printf("No nearest to be found from (%f %f) (%f %f) "
370 corner[0].x, corner[0].y,
371 corner[1].x, corner[1].y,
378 if (is_within(&tree->pos, corner)) {
379 vector_sub(pos, &tree->pos, &tmp);
380 distance = vector_abs(&tmp);
386 directions = quadrants_to_search(tree, corner);
388 for (i = 0; i < 4; i++) {
393 if (!(directions & (1 << i)))
396 node = quadtree_find_nearest(tree->child[i], pos, corner);
401 vector_sub(pos, &node->pos, &tmp);
402 dist = vector_abs(&tmp);
404 if (!nearest || dist < distance) {
411 if (nearest && !is_within(&nearest->pos, corner)) {
413 printf("Node %p (%f %f) is not within "
414 "search window (%f %f) (%f %f)\n",
415 nearest, nearest->pos.x, nearest->pos.y,
416 corner[0].x, corner[0].y,
417 corner[1].x, corner[1].y);
424 static struct quadtree *quadtree_find_nearest_noparent(struct quadtree *tree,
426 struct vector *corner)
428 struct quadtree *nearest;
430 struct quadtree *node;
431 double dist = 0, dist2;
434 nearest = quadtree_find_nearest(tree, pos, corner);
440 printf("Avoiding parent or NULL node %p\n", nearest);
443 * oops, we don't want to pick the parent node, let's choose
447 for (i = 0; i < 4; i++) {
452 nearest = quadtree_find_nearest(tree->child[i], pos,
458 vector_sub(pos, &nearest->pos, &sub);
459 dist = vector_abs(&sub);
462 node = quadtree_find_nearest(tree->child[i],
468 vector_sub(pos, &node->pos, &sub);
469 dist2 = vector_abs(&sub);
481 static void get_middle_point(struct vector *corner, struct vector *middle)
483 middle->x = (corner[0].x + corner[1].x) / (double)2;
484 middle->y = (corner[0].y + corner[1].y) / (double)2;
487 static int quadtree_split_by_node(struct quadtree *node,
488 struct vector *corner, int dir)
490 if (!is_within(&node->pos, corner)) {
492 printf("Not within search rectangle\n");
497 case QUADTREE_UPLEFT:
498 corner[0] = node->pos;
500 case QUADTREE_UPRIGHT:
501 corner[0].y = node->pos.y;
502 corner[1].x = node->pos.x;
504 case QUADTREE_DOWNRIGHT:
505 corner[1] = node->pos;
507 case QUADTREE_DOWNLEFT:
508 corner[0].x = node->pos.x;
509 corner[1].y = node->pos.y;
516 printf("Search rectangle is now (%f %f) (%f %f), (%f %f)\n",
517 corner[0].x, corner[0].y,
518 corner[1].x, corner[1].y,
519 node->pos.x, node->pos.y);
521 if ((corner[0].x < corner[1].x) ||
522 (corner[0].y < corner[1].y))
529 * Quickly detach a node from a tree. Move all child nodes under
532 static int _quadtree_del(struct quadtree *node, struct quadtree *parent)
537 /* Detach from the tree */
539 for (i = 0; i < 4; i++) {
540 if (node->parent->child[i] == node) {
541 node->parent->child[i] = 0;
550 for (i = 0; i < 4; i++) {
555 _quadtree_del(n, parent);
556 _quadtree_add(parent, n);
563 * Move everything under @tree node to @parent node, everything
564 * else except the @tree node itself
566 static int optimally_move_tree(struct quadtree *tree, struct quadtree *parent,
567 struct vector *corner_orig,
568 struct quadtree_ops *ops)
570 struct vector corner[2], mid;
571 struct quadtree *t, *tmp;
574 get_middle_point(corner_orig, &mid);
575 t = quadtree_find_nearest_noparent(tree, &mid, corner_orig);
579 printf("Cannot find nearest node\n");
585 * Now we have the t node which contains the object of the
586 * spatial middle coordinates of the tree.
590 printf("Relocating node %p (%f %f) under parent %p\n", t,
591 t->pos.x, t->pos.y, parent);
592 printf("There are %ld child nodes left\n", tree->children);
595 _quadtree_del(t, tree);
596 quadtree_add(parent, t, ops);
604 * Now split the search rectangle in quadtres and do the same
605 * with all of the quarters.
608 corner[0] = corner_orig[0];
609 corner[1] = corner_orig[1];
610 if (quadtree_split_by_node(t, corner, QUADTREE_UPLEFT))
611 moved += optimally_move_tree(tree, parent, corner, ops);
613 corner[0] = corner_orig[0];
614 corner[1] = corner_orig[1];
615 if (quadtree_split_by_node(t, corner, QUADTREE_UPRIGHT))
616 moved += optimally_move_tree(tree, parent, corner, ops);
618 corner[0] = corner_orig[0];
619 corner[1] = corner_orig[1];
620 if (quadtree_split_by_node(t, corner, QUADTREE_DOWNLEFT))
621 moved += optimally_move_tree(tree, parent, corner, ops);
623 corner[0] = corner_orig[0];
624 corner[1] = corner_orig[1];
625 if (quadtree_split_by_node(t, corner, QUADTREE_DOWNRIGHT))
626 moved += optimally_move_tree(tree, parent, corner, ops);
628 get_middle_point(corner_orig, &mid);
629 tmp = quadtree_find_nearest(tree, &mid, corner_orig);
630 if (tmp && tmp != tree)
635 printf("Now moved %d nodes, %ld left\n", moved, tree->children);
641 * quadtree_del - Detach a node from the tree
643 * Return value: The new root node of the tree. If we are detaching
644 * anything but the root node of the entire tree, the returned root
645 * value will be the original root of the tree.
647 struct quadtree *quadtree_del(struct quadtree *node,
648 struct quadtree_ops *ops)
650 struct quadtree *parent = NULL;
651 struct vector corner[2];
652 int i, children = node->children, moved;
657 printf("Deleting node %p under parent %p\n",
659 printf("Relocating %ld children\n", node->children);
665 * We are deleting the root node. This means we have
666 * to select a new root node and reconstruct the
667 * entire tree under it again.
670 printf("Deleting root node\n");
673 for (i = 0; i < 4; i++) {
677 parent = node->child[i];
678 _quadtree_del(parent, node);
680 quadtree_recalculate_parent_stats(parent, ops);
685 * The node has a parent. Detach the node from it and
686 * relocate the children.
689 for (i = 0; i < 4; i++) {
690 if (node->parent->child[i] == node) {
691 node->parent->child[i] = 0;
698 parent = node->parent;
701 * The sub branch is now detached from the main
702 * tree. Fix the stats.
704 quadtree_recalculate_parent_stats(node->parent, ops);
707 validate_tree(parent);
712 * Now we are ready to prepare for relocating the nodes under
716 quadtree_get_tree_dimensions(node, corner);
717 moved = optimally_move_tree(node, parent, corner, ops);
720 if (moved != children) {
721 printf("Got %d children but %d were moved\n",
723 printf("nearest children left:\n");
724 for (i = 0 ; i < 4; i++)
726 printf(" node %d %p, (%f %f)\n",
728 node->child[i]->pos.x,
729 node->child[i]->pos.y);
733 printf("Delete done, returning parent %p\n", parent);
738 validate_tree(parent);
739 return quadtree_find_parent(parent);
742 static void check_for_crossed_subnodes(struct quadtree *node,
743 struct vector *limit, struct quadtree_ops *ops)
745 int direction = 0, i;
746 int up = 0, left = 0, right = 0, down = 0;
748 for (i = 0; i < 2; i++) {
749 if (limit[i].x < node->pos.x)
753 if (limit[i].y < node->pos.y)
760 direction |= QUADTREE_UPLEFT;
762 direction |= QUADTREE_UPRIGHT;
764 direction |= QUADTREE_DOWNLEFT;
766 direction |= QUADTREE_DOWNRIGHT;
767 if ((left && right) || (up && down))
768 direction |= QUADTREE_SELF;
770 if ((direction & QUADTREE_UPLEFT) && node->child[0])
771 check_for_crossed_subnodes(node->child[0], limit, ops);
773 if ((direction & QUADTREE_UPRIGHT) && node->child[1])
774 check_for_crossed_subnodes(node->child[0], limit, ops);
776 if ((direction & QUADTREE_DOWNLEFT) && node->child[2])
777 check_for_crossed_subnodes(node->child[0], limit, ops);
779 if ((direction & QUADTREE_DOWNRIGHT) && node->child[3])
780 check_for_crossed_subnodes(node->child[0], limit, ops);
782 if (direction & QUADTREE_SELF) {
783 struct quadtree *parent;
785 parent = quadtree_del(node, ops);
786 quadtree_add(parent, node, ops);
790 struct quadtree *quadtree_move(struct quadtree *node, struct vector new_pos,
791 struct quadtree_ops *ops)
793 struct quadtree *parent, *tree_parent;
796 /* Check if we have crossed any of the parents */
797 parent = node->parent;
799 if (node->pos.x < parent->pos.x && new_pos.x > parent->pos.x)
801 if (node->pos.x > parent->pos.x && new_pos.x < parent->pos.x)
803 if (node->pos.y < parent->pos.y && new_pos.y > parent->pos.y)
805 if (node->pos.y > parent->pos.y && new_pos.y < parent->pos.y)
809 parent = parent->parent;
814 * If the node has crossed the boundaries, remove it
815 * from the tree and add it again to it. It is then
816 * guaranteed to be in the correct position of the
819 tree_parent = quadtree_del(node, ops);
821 quadtree_add(tree_parent, node, ops);
825 /* Move the node into its new location */
830 * Now, search the subtree for any children that are
831 * located in wrong place and move them into correct
832 * place within the tree.
834 struct vector limit[2];
836 limit[0] = node->pos;
838 check_for_crossed_subnodes(node, limit, ops);
841 return quadtree_find_parent(node);
845 static int _walk_tree(struct quadtree *head, const struct quadtree_iterator *it)
847 int direction, count = 0;
849 direction = it->direction(head, (struct quadtree_iterator *)it);
851 if ((direction & QUADTREE_UPLEFT) && head->child[0])
852 count += _walk_tree(head->child[0], it);
854 if ((direction & QUADTREE_UPRIGHT) && head->child[1])
855 count += _walk_tree(head->child[1], it);
857 if ((direction & QUADTREE_DOWNLEFT) && head->child[2])
858 count += _walk_tree(head->child[2], it);
860 if ((direction & QUADTREE_DOWNRIGHT) && head->child[3])
861 count += _walk_tree(head->child[3], it);
863 if ((direction & QUADTREE_SELF) && it->callback) {
864 it->callback(head, (struct quadtree_iterator *)it);
871 int walk_quadtree(const struct quadtree_iterator *it)
873 return _walk_tree(it->head, it);