12 static void _trap(int line)
15 printf("Trapped from line %d, use debugger to get backtrace\n",
22 #define trap() _trap(__LINE__)
24 static int quadtree_compare_coord(const struct vector *a,
25 const struct vector *b)
41 static int quadtree_compare(const struct quadtree *a, const struct quadtree *b)
43 return quadtree_compare_coord(&a->pos, &b->pos);
46 static void validate_subtree(const struct quadtree *node)
53 printf("Attempted to validate a null pointer\n");
58 for (i = 0; i < 4; i++) {
62 if (node->child[i]->parent != node) {
63 printf("%s:%d Fatal! Tree inconsistency detected at "
64 "child %d %p in node %p, incorrent parent %p\n",
65 __func__, __LINE__, i, node->child[i], node,
66 node->child[i]->parent);
72 if (node->child[i] == node->parent) {
73 printf("%s:%d Fatal! Tree loop detected "
74 "at child %d in node %p\n",
75 __func__, __LINE__, i, node);
81 dir = quadtree_compare(node, node->child[i]);
84 printf("%s:%d Fatal! Spatial inconsistency detected "
85 "at child %d in node %p\n"
86 "parent: (%f %f), child (%f %f), "
88 __func__, __LINE__, i, node,
89 node->pos.x, node->pos.y,
90 node->child[i]->pos.x, node->child[i]->pos.y,
96 children += node->child[i]->children + 1;
98 validate_subtree(node->child[i]);
101 if (node->depth < 0) {
102 printf("%s:%d Tree statistics inconsistency detected! "
103 "Negative depth: %ld\n",
104 __func__, __LINE__, node->depth);
107 if (node->children != children) {
108 printf("%s:%d Tree statistics inconsistency detected! "
109 "child count mismatch. Expected %ld, got %ld\n",
110 __func__, __LINE__, children, node->children);
115 for (i = 0; i < 4 && node->children; i++) {
119 if (node->depth == node->child[i]->depth + 1)
122 if (node->child[i]->depth > node->depth) {
123 printf("%s:%d Tree statistics inconsistency detected! "
124 "child depth mismatch %ld > %ld\n",
125 __func__, __LINE__, node->child[i]->depth,
131 printf("%s:%d Tree statistics inconsistency detected! "
132 "child depth mismatch.",
139 static void validate_tree(const struct quadtree *node)
147 return validate_subtree(node);
149 for (i = 0; i < 4; i++)
150 if (node->parent->child[i] == node)
154 printf("%s:%d Tree inconsistency detected! "
155 "Wrong parent %p for node %p\n",
156 __func__, __LINE__, node->parent, node);
161 validate_tree(node->parent);
164 void _quadtree_validate_tree(const struct quadtree *node)
169 static struct quadtree *_quadtree_add(struct quadtree *parent,
170 struct quadtree *new)
174 ret = quadtree_compare(parent, new);
176 if (ret < 0 || ret >= 4) {
177 printf("Invalid comparison result of %d\n", ret);
181 if (parent->child[ret])
182 return _quadtree_add(parent->child[ret], new);
184 parent->child[ret] = new;
185 new->parent = parent;
186 for (i = 0; i < 4; i++)
192 static void _recalculate_node_area_stats(struct quadtree *node)
194 /* The space covered by the parent node's corner
195 * points needs be as wide as its widest child node's
198 #define CHILD_CORNER_SAFE(node, ch_idx, cor_idx, axis) \
199 ((node)->child[ch_idx] ? \
200 (node)->child[ch_idx]->corner[cor_idx].axis : \
203 node->corner[0].x = MIN(CHILD_CORNER_SAFE(node, 0, 0, x),
204 CHILD_CORNER_SAFE(node, 2, 0, x));
205 node->corner[0].y = MIN(CHILD_CORNER_SAFE(node, 0, 0, y),
206 CHILD_CORNER_SAFE(node, 1, 0, y));
207 node->corner[1].x = MAX(CHILD_CORNER_SAFE(node, 1, 1, x),
208 CHILD_CORNER_SAFE(node, 3, 1, x));
209 node->corner[1].y = MAX(CHILD_CORNER_SAFE(node, 2, 1, y),
210 CHILD_CORNER_SAFE(node, 3, 1, y));
211 #undef CHILD_CORNER_SAFE
214 static void recalculate_parent_area_stats(struct quadtree *node)
216 struct vector old_corner[2];
219 memcpy(&old_corner, &node->corner, sizeof(old_corner));
221 _recalculate_node_area_stats(node);
224 * Stop propagating the changes up in the tree if
225 * nothing has changed
227 if (memcmp(&old_corner, &node->corner, sizeof(old_corner)))
235 * Recursively walk through the tree and propagate changes made to the
236 * given node up until the highest parent.
238 static void quadtree_recalculate_parent_stats(struct quadtree *node,
239 struct quadtree_ops *ops)
247 for (i = 0; i < 4; i++) {
251 node->depth = MAX(node->depth,
252 node->child[i]->depth + 1);
253 node->children += node->child[i]->children + 1;
256 _recalculate_node_area_stats(node);
258 if (ops->recalculate_stats)
259 ops->recalculate_stats(node);
266 * quadtree_add - add a node to a quadtree
267 * @parent: parent node
268 * @new: the new node to be added
270 * Add a node to a quadtree. The tree is kept in order, the new node
271 * is placed in the end of appropriate branch.
273 * The case of nodes sharing identical coordinates is not taken into
277 struct quadtree *quadtree_add(struct quadtree *parent, struct quadtree *new,
278 struct quadtree_ops *ops)
283 validate_tree(parent);
285 _quadtree_add(parent, new);
288 printf("adding node %p to parent %p\n", new, parent);
292 quadtree_recalculate_parent_stats(new, ops);
299 static int is_within(struct vector *pos, struct vector *corner)
301 if ((pos->x >= corner[1].x) && (pos->x <= corner[0].x) &&
302 (pos->y >= corner[1].y) && (pos->y <= corner[0].y))
307 static int rectangle_and_circle_overlap(struct vector *corner,
308 struct vector *pos, double radius)
310 int vertically_overlapping = 0, horizontally_overlapping = 0;
312 if ((pos->x < corner[1].x && pos->x + radius > corner[0].x) ||
313 (pos->x > corner[0].x && pos->x - radius < corner[1].x))
314 horizontally_overlapping = 1;
316 if ((pos->y < corner[1].y && pos->y + radius > corner[0].y) ||
317 (pos->y > corner[0].y && pos->y - radius < corner[1].y))
318 vertically_overlapping = 1;
320 return horizontally_overlapping && vertically_overlapping;
323 static int quadrants_to_search(struct quadtree *node, struct vector *pos,
331 if (node->child[0] &&
332 rectangle_and_circle_overlap(node->child[0]->corner, pos, dist))
333 direction |= QUADTREE_UPLEFT;
335 if (node->child[1] &&
336 rectangle_and_circle_overlap(node->child[1]->corner, pos, dist))
337 direction |= QUADTREE_UPRIGHT;
339 if (node->child[2] &&
340 rectangle_and_circle_overlap(node->child[2]->corner, pos, dist))
341 direction |= QUADTREE_DOWNLEFT;
343 if (node->child[3] &&
344 rectangle_and_circle_overlap(node->child[3]->corner, pos, dist))
345 direction |= QUADTREE_DOWNRIGHT;
350 static struct quadtree *quadtree_find_nearest(struct quadtree *tree,
352 struct vector *corner,
353 struct quadtree *nearest,
357 struct quadtree *node;
358 double distance = 0, dist;
364 vector_sub(&nearest->pos, pos, &tmp);
365 distance = vector_abs_squared(&tmp);
367 if (tree != nearest) {
368 vector_sub(&tree->pos, pos, &tmp);
369 dist = vector_abs_squared(&tmp);
370 if (dist < distance) {
376 if (!is_within(&nearest->pos, corner)) {
378 printf("Discarding nearest %p "
379 "as outside of search window\n", nearest);
384 directions = quadrants_to_search(tree, pos, distance);
386 printf("%d: Directions: %x\n", depth, directions);
387 for (i = 0; i < 4; i++) {
391 if (!(directions & (1 << i)))
395 node = quadtree_find_nearest(tree->child[i], pos, corner,
401 if (node != nearest) {
402 vector_sub(&node->pos, pos, &tmp);
403 dist = vector_abs_squared(&tmp);
404 if (dist < distance || !nearest) {
409 * Update the directions where to search for
410 * since those may not be valid any more
412 directions = quadrants_to_search(tree, pos, distance);
417 if (nearest && !is_within(&nearest->pos, corner)) {
419 printf("%d: Node %p (%f %f) is not within "
420 "search window (%f %f) (%f %f)\n", depth,
421 nearest, nearest->pos.x, nearest->pos.y,
422 corner[0].x, corner[0].y,
423 corner[1].x, corner[1].y);
427 printf("%d: Node %p (%f %f) is nearest node, dist %f\n",
429 nearest ? nearest->pos.x : -1,
430 nearest ? nearest->pos.y : -1,
431 nearest ? distance : -1);
435 static struct quadtree *quadtree_find_nearest_noparent(struct quadtree *tree,
437 struct vector *corner)
439 struct quadtree *nearest = NULL;
441 struct quadtree *node;
442 double dist = 0, dist2;
445 nearest = quadtree_find_nearest(tree, pos, corner, nearest, 0);
451 printf("Avoiding parent or NULL node %p\n", nearest);
454 * oops, we don't want to pick the parent node, let's choose
458 for (i = 0; i < 4; i++) {
463 nearest = quadtree_find_nearest(tree->child[i], pos,
469 vector_sub(pos, &nearest->pos, &sub);
470 dist = vector_abs_squared(&sub);
473 node = quadtree_find_nearest(tree->child[i], pos, corner,
479 vector_sub(pos, &node->pos, &sub);
480 dist2 = vector_abs_squared(&sub);
492 static void get_middle_point(struct vector *corner, struct vector *middle)
494 middle->x = (corner[0].x + corner[1].x) / (double)2;
495 middle->y = (corner[0].y + corner[1].y) / (double)2;
498 static int quadtree_split_by_node(struct quadtree *node,
499 struct vector *corner, int dir)
501 if (!is_within(&node->pos, corner)) {
503 printf("Not within search rectangle\n");
508 printf("Search rectangle was before (%f %f) (%f %f), (%f %f)\n",
509 corner[0].x, corner[0].y,
510 corner[1].x, corner[1].y,
511 node->pos.x, node->pos.y);
514 case QUADTREE_UPLEFT:
515 corner[0] = node->pos;
517 case QUADTREE_UPRIGHT:
518 corner[0].y = node->pos.y;
519 corner[1].x = node->pos.x;
521 case QUADTREE_DOWNRIGHT:
522 corner[1] = node->pos;
524 case QUADTREE_DOWNLEFT:
525 corner[0].x = node->pos.x;
526 corner[1].y = node->pos.y;
533 printf("Search rectangle is now (%f %f) (%f %f), (%f %f)\n",
534 corner[0].x, corner[0].y,
535 corner[1].x, corner[1].y,
536 node->pos.x, node->pos.y);
538 if ((corner[0].x < corner[1].x) ||
539 (corner[0].y < corner[1].y))
546 * Quickly detach a node from a tree. Move all child nodes under
549 static int _quadtree_del(struct quadtree *node, struct quadtree *parent)
554 /* Detach from the tree */
556 for (i = 0; i < 4; i++) {
557 if (node->parent->child[i] == node) {
558 node->parent->child[i] = 0;
566 for (i = 0; i < 4; i++) {
571 _quadtree_del(n, parent);
572 _quadtree_add(parent, n);
573 recalculate_parent_area_stats(n);
580 * Move everything under @tree node to @parent node, everything
581 * else except the @tree node itself
583 static int optimally_move_tree(struct quadtree *tree, struct quadtree *parent,
584 struct vector *corner_orig,
585 struct quadtree_ops *ops)
587 struct vector corner[2], mid;
591 get_middle_point(corner_orig, &mid);
592 t = quadtree_find_nearest_noparent(tree, &mid, corner_orig);
596 printf("Cannot find nearest node\n");
602 * Now we have the t node which contains the object of the
603 * spatial middle coordinates of the tree.
607 printf("Relocating node %p (%f %f) under parent %p\n", t,
608 t->pos.x, t->pos.y, parent);
609 printf("There are %ld child nodes left\n", tree->children);
612 _quadtree_del(t, tree);
613 quadtree_add(parent, t, ops);
621 * Now split the search rectangle in quadtres and do the same
622 * with all of the quarters.
625 corner[0] = corner_orig[0];
626 corner[1] = corner_orig[1];
627 if (quadtree_split_by_node(t, corner, QUADTREE_UPLEFT))
628 moved += optimally_move_tree(tree, parent, corner, ops);
630 corner[0] = corner_orig[0];
631 corner[1] = corner_orig[1];
632 if (quadtree_split_by_node(t, corner, QUADTREE_UPRIGHT))
633 moved += optimally_move_tree(tree, parent, corner, ops);
635 corner[0] = corner_orig[0];
636 corner[1] = corner_orig[1];
637 if (quadtree_split_by_node(t, corner, QUADTREE_DOWNLEFT))
638 moved += optimally_move_tree(tree, parent, corner, ops);
640 corner[0] = corner_orig[0];
641 corner[1] = corner_orig[1];
642 if (quadtree_split_by_node(t, corner, QUADTREE_DOWNRIGHT))
643 moved += optimally_move_tree(tree, parent, corner, ops);
647 printf("Now moved %d nodes, %ld left\n", moved, tree->children);
653 * quadtree_del - Detach a node from the tree
655 * Return value: The new root node of the tree. If we are detaching
656 * anything but the root node of the entire tree, the returned root
657 * value will be the original root of the tree.
659 struct quadtree *quadtree_del(struct quadtree *node,
660 struct quadtree_ops *ops)
662 struct quadtree *parent = NULL;
663 struct vector corner[2];
664 int i, children = node->children, moved;
669 printf("Deleting node %p under parent %p\n",
671 printf("Relocating %ld children\n", node->children);
677 * We are deleting the root node. This means we have
678 * to select a new root node and reconstruct the
679 * entire tree under it again.
682 printf("Deleting root node\n");
685 for (i = 0; i < 4; i++) {
689 parent = node->child[i];
690 _quadtree_del(parent, node);
692 quadtree_recalculate_parent_stats(parent, ops);
697 * The node has a parent. Detach the node from it and
698 * relocate the children.
701 for (i = 0; i < 4; i++) {
702 if (node->parent->child[i] == node) {
703 node->parent->child[i] = 0;
710 parent = node->parent;
714 * The sub branch is now detached from the main
715 * tree. Fix the stats.
717 quadtree_recalculate_parent_stats(parent, ops);
720 validate_tree(parent);
725 * Now we are ready to prepare for relocating the nodes under
729 corner[0] = node->corner[1];
730 corner[1] = node->corner[0];
732 printf("\nInitial Search rectangle (%f %f) (%f %f), (%f %f)\n",
733 corner[0].x, corner[0].y,
734 corner[1].x, corner[1].y,
735 node->pos.x, node->pos.y);
738 moved = optimally_move_tree(node, parent, corner, ops);
741 if (moved != children) {
742 printf("Got %d children but %d were moved\n",
744 printf("nearest children left:\n");
745 for (i = 0 ; i < 4; i++)
747 printf(" node %d %p, (%f %f)\n",
749 node->child[i]->pos.x,
750 node->child[i]->pos.y);
754 printf("Delete done, returning parent %p\n", parent);
759 validate_tree(parent);
760 return quadtree_find_parent(parent);
763 static int check_for_crossed_subnodes(struct quadtree *node,
764 struct quadtree *skip,
765 struct vector *limit, struct quadtree_ops *ops)
767 int direction = 0, i;
768 int up = 0, left = 0, right = 0, down = 0;
771 for (i = 0; i < 2; i++) {
772 if (limit[i].x < node->pos.x)
776 if (limit[i].y < node->pos.y)
783 direction |= QUADTREE_UPLEFT;
785 direction |= QUADTREE_UPRIGHT;
787 direction |= QUADTREE_DOWNLEFT;
789 direction |= QUADTREE_DOWNRIGHT;
790 if ((left && right) || (up && down))
791 direction |= QUADTREE_SELF;
795 * We need to skip the topmost node (the one that was actually
796 * moved), otherwise we would trigger rebalance every time
801 if (direction & QUADTREE_SELF) {
802 struct quadtree *parent;
805 printf("Rebalanced because crossed child %p: "
806 "node (%f %f) limits (%f %f) (%f %f)\n",
808 node->pos.x, node->pos.y,
809 limit[0].x, limit[0].y,
810 limit[1].x, limit[1].y);
812 parent = quadtree_del(node, ops);
813 quadtree_add(parent, node, ops);
817 if ((direction & QUADTREE_UPLEFT) && node->child[0])
818 cross += check_for_crossed_subnodes(node->child[0], skip,
824 if ((direction & QUADTREE_UPRIGHT) && node->child[1])
825 cross += check_for_crossed_subnodes(node->child[1], skip,
831 if ((direction & QUADTREE_DOWNLEFT) && node->child[2])
832 cross += check_for_crossed_subnodes(node->child[2], skip,
838 if ((direction & QUADTREE_DOWNRIGHT) && node->child[3])
839 cross += check_for_crossed_subnodes(node->child[3], skip,
845 struct quadtree *quadtree_move(struct quadtree *node, struct vector new_pos,
846 struct quadtree_ops *ops)
848 struct quadtree *parent, *tree_parent;
850 int parents = 0, all_parents = 0;
853 parent = node->parent;
855 parent = parent->parent;
860 /* Check if we have crossed any of the parents */
861 parent = node->parent;
864 if (node->pos.x < parent->pos.x && new_pos.x > parent->pos.x)
866 if (node->pos.x > parent->pos.x && new_pos.x < parent->pos.x)
868 if (node->pos.y < parent->pos.y && new_pos.y > parent->pos.y)
870 if (node->pos.y > parent->pos.y && new_pos.y < parent->pos.y)
874 parent = parent->parent;
879 printf("Rebalanced because crossed parent: node %p, "
881 "old (%f %f) new (%f %f) parent (%f %f)\n",
882 node, parents, all_parents, modify,
883 node->pos.x, node->pos.y,
884 new_pos.x, new_pos.y,
885 parent->pos.x, parent->pos.y);
887 * If the node has crossed the boundaries, remove it
888 * from the tree and add it again to it. It is then
889 * guaranteed to be in the correct position of the
893 tree_parent = quadtree_del(node, ops);
895 quadtree_add(tree_parent, node, ops);
901 if (node->children) {
903 * Now, search the subtree for any children that are
904 * located in wrong place and move them into correct
905 * place within the tree.
907 struct vector limit[2];
909 limit[0] = node->pos;
911 modify = check_for_crossed_subnodes(node, node, limit, ops);
914 /* Move the node into its new location */
918 tree_parent = quadtree_del(node, ops);
921 recalculate_parent_area_stats(node);
923 quadtree_add(tree_parent, node, ops);
925 return quadtree_find_parent(node);
929 static int _walk_tree(struct quadtree *head, const struct quadtree_iterator *it)
931 int direction, count = 0;
933 direction = it->direction(head, (struct quadtree_iterator *)it);
935 if ((direction & QUADTREE_UPLEFT) && head->child[0])
936 count += _walk_tree(head->child[0], it);
938 if ((direction & QUADTREE_UPRIGHT) && head->child[1])
939 count += _walk_tree(head->child[1], it);
941 if ((direction & QUADTREE_DOWNLEFT) && head->child[2])
942 count += _walk_tree(head->child[2], it);
944 if ((direction & QUADTREE_DOWNRIGHT) && head->child[3])
945 count += _walk_tree(head->child[3], it);
947 if ((direction & QUADTREE_SELF) && it->callback) {
948 it->callback(head, (struct quadtree_iterator *)it);
955 int walk_quadtree(const struct quadtree_iterator *it)
957 return _walk_tree(it->head, it);