return a;
}
+static int planet_search_when_moving(struct quadtree *node,
+ struct quadtree_iterator *itr)
+{
+ struct planet *p = tree_to_planet(node);
+ struct planet_search_iterator *it = qt_itr_to_planet_itr(itr);
+ int direction = 0, i;
+ int up = 0, left = 0, right = 0, down = 0;
+
+ for (i = 0; i < 2; i++) {
+ if (it->limit[i].x < p->pos.x)
+ left = 1;
+ else
+ right = 1;
+ if (it->limit[i].y < p->pos.y)
+ up = 1;
+ else
+ down = 1;
+ }
+
+ if (left || up)
+ direction |= QUADTREE_UPLEFT;
+ if (right || up)
+ direction |= QUADTREE_UPRIGHT;
+ if (left || down)
+ direction |= QUADTREE_DOWNLEFT;
+ if (right || down)
+ direction |= QUADTREE_DOWNRIGHT;
+ if ((left && right) || (up && down))
+ direction |= QUADTREE_SELF;
+
+ return direction;
+}
+
+void planet_move_iterator(struct quadtree *node, struct quadtree_iterator *it)
+{
+ struct quadtree *parent;
+
+ parent = quadtree_del(node, planet_spatial_compare);
+ quadtree_add(parent, node, planet_spatial_compare);
+}
+
struct planet *move_planet(struct planet *p, const double time)
{
struct vector tmp, new_pos;
- struct quadtree *tree_parent;
+ struct quadtree *parent, *tree_parent;
+ struct planet *pa;
struct planet_search_iterator it;
- int ret;
+
+ int modify = 0;
vector_scale(&p->speed, time, &tmp);
vector_add(&p->pos, &tmp, &new_pos);
- vector_scale(&p->speed, pow(0.99, time), &p->speed);
-
- /*
- * Update the quadtree if there are any planets between the
- * old and new position. If there is nothing between the old
- * and new location, there is no need to modify the tree at
- * all.
- */
+
+ /* Check if we have crossed any of the parents */
+ parent = p->tree.parent;
+ while(parent) {
+ pa = tree_to_planet(parent);
+ if (p->pos.x < pa->pos.x && new_pos.x > pa->pos.x)
+ modify = 1;
+ if (p->pos.x > pa->pos.x && new_pos.x < pa->pos.x)
+ modify = 1;
+ if (p->pos.y < pa->pos.y && new_pos.y > pa->pos.y)
+ modify = 1;
+ if (p->pos.y > pa->pos.y && new_pos.y < pa->pos.y)
+ modify = 1;
+
+ if (!modify) {
+ parent = parent->parent;
+ continue;
+ }
+
+ tree_parent = quadtree_del(&p->tree, planet_spatial_compare);
+ p->pos = new_pos;
+ quadtree_add(tree_parent, &p->tree, planet_spatial_compare);
+ return tree_to_planet(tree_parent);
+ }
+
+ it.qt_iterator.head = &p->tree;
it.limit[0] = p->pos;
it.limit[1] = new_pos;
- it.qt_iterator.head = quadtree_find_parent(&p->tree);
- it.qt_iterator.direction = planet_search_rectangular;
- it.qt_iterator.callback = NULL;
+ it.qt_iterator.direction = planet_search_when_moving;
+ it.qt_iterator.callback = planet_move_iterator;
+ walk_quadtree(&it.qt_iterator);
- ret = walk_quadtree(&it.qt_iterator);
p->pos = new_pos;
- if (ret == 0)
- return tree_to_planet(it.qt_iterator.head);
-
- printf("Modify tree\n");
- tree_parent = quadtree_del(&p->tree, planet_spatial_compare);
- quadtree_add(tree_parent, &p->tree, planet_spatial_compare);
- return tree_to_planet(tree_parent);
+ return tree_to_planet(quadtree_find_parent(&p->tree));
}
void print_planet(const struct planet *p)