velocity *= pow(distance / radius, 0.2);
- p->pos.x = cos(angle) * distance;
- p->pos.y = sin(angle) * distance;
+ p->tree.pos.x = cos(angle) * distance;
+ p->tree.pos.y = sin(angle) * distance;
p->speed.x = -sin(angle) * velocity;
p->speed.y = cos(angle) * velocity;
float radius = p->radius * cam->zoom;
int i;
- vector_sub(&p->pos, &cam->pos, &pos);
+ vector_sub(&p->tree.pos, &cam->pos, &pos);
vector_scale(&pos, cam->zoom, &pos);
pos.x += screen->w / 2;
pos.y += screen->h / 2;
struct planet *q = tree_to_planet(p->tree.child[i]);
- draw_line(screen, &p->pos, &q->pos,
+ draw_line(screen, &p->tree.pos, &q->tree.pos,
p->r, p->g, p->b, cam);
}
}
struct vector distance, sum;
double dist, f, acc;
- vector_sub(&a->pos, &b->pos, &distance);
+ vector_sub(&a->tree.pos, &b->tree.pos, &distance);
dist = vector_abs(&distance);
mass = a->mass + b->mass;
if (a->mass < b->mass)
- a->pos = b->pos;
+ a->tree.pos = b->tree.pos;
a->r = (a->r * a->mass + b->r * b->mass) / mass;
a->g = (a->g * a->mass + b->g * b->mass) / mass;
int up = 0, left = 0, right = 0, down = 0;
for (i = 0; i < 2; i++) {
- if (it->limit[i].x < p->pos.x)
+ if (it->limit[i].x < p->tree.pos.x)
left = 1;
else
right = 1;
- if (it->limit[i].y < p->pos.y)
+ if (it->limit[i].y < p->tree.pos.y)
up = 1;
else
down = 1;
int modify = 0;
vector_scale(&p->speed, time, &tmp);
- vector_add(&p->pos, &tmp, &new_pos);
+ vector_add(&p->tree.pos, &tmp, &new_pos);
/* 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)
+ if (p->tree.pos.x < pa->tree.pos.x && new_pos.x > pa->tree.pos.x)
modify = 1;
- if (p->pos.x > pa->pos.x && new_pos.x < pa->pos.x)
+ if (p->tree.pos.x > pa->tree.pos.x && new_pos.x < pa->tree.pos.x)
modify = 1;
- if (p->pos.y < pa->pos.y && new_pos.y > pa->pos.y)
+ if (p->tree.pos.y < pa->tree.pos.y && new_pos.y > pa->tree.pos.y)
modify = 1;
- if (p->pos.y > pa->pos.y && new_pos.y < pa->pos.y)
+ if (p->tree.pos.y > pa->tree.pos.y && new_pos.y < pa->tree.pos.y)
modify = 1;
if (!modify) {
}
tree_parent = quadtree_del(&p->tree, &planet_ops);
- p->pos = new_pos;
+ p->tree.pos = new_pos;
quadtree_add(tree_parent, &p->tree, &planet_ops);
return tree_to_planet(tree_parent);
}
* them into correct place within the tree.
*/
it.qt_iterator.head = &p->tree;
- it.limit[0] = p->pos;
+ it.limit[0] = p->tree.pos;
it.limit[1] = new_pos;
it.qt_iterator.direction = planet_search_when_moving;
it.qt_iterator.callback = planet_move_iterator;
walk_quadtree(&it.qt_iterator);
}
- p->pos = new_pos;
+ p->tree.pos = new_pos;
return tree_to_planet(quadtree_find_parent(&p->tree));
}
void print_planet(const struct planet *p)
{
printf("pos: (%f,%f), speed: (%f,%f), mass: %f, radius %f\n",
- p->pos.x, p->pos.y, p->speed.x, p->speed.y, p->mass, p->radius);
-}
-
-int planet_spatial_compare(struct quadtree *ta, struct quadtree *tb)
-{
- struct planet *a, *b;
- int up, left;
- a = tree_to_planet(ta);
- b = tree_to_planet(tb);
-
- up = b->pos.y < a->pos.y;
- left = b->pos.x < a->pos.x;
-
- if (up && left)
- return 0;
- if (up && !left)
- return 1;
- if (left)
- return 2;
- return 3;
+ p->tree.pos.x, p->tree.pos.y, p->speed.x, p->speed.y, p->mass, p->radius);
}
int planet_search_rectangular(struct quadtree *node,
int up = 0, left = 0, right = 0, down = 0;
for (i = 0; i < 2; i++) {
- if (it->limit[i].x < p->pos.x)
+ if (it->limit[i].x < p->tree.pos.x)
left = 1;
else
right = 1;
- if (it->limit[i].y < p->pos.y)
+ if (it->limit[i].y < p->tree.pos.y)
up = 1;
else
down = 1;
c = tree_to_planet(node->child[i]);
p->tree_mass += c->tree_mass;
- vector_sub(&p->pos, &c->pos, &vect);
+ vector_sub(&p->tree.pos, &c->tree.pos, &vect);
dist = vector_abs(&vect);
dist += c->tree_area;
p->tree_area = MAX(p->tree_area, dist);
}
struct quadtree_ops planet_ops = {
- .compare = planet_spatial_compare,
.recalculate_stats = planet_recalculate_stats,
};
validate_subtree(quadtree_find_parent(node));
}
+static int quadtree_compare(struct quadtree *a, struct quadtree *b)
+{
+ int up, left;
+
+ up = b->pos.y < a->pos.y;
+ left = b->pos.x < a->pos.x;
+
+ if (up && left)
+ return 0;
+ if (up && !left)
+ return 1;
+ if (left)
+ return 2;
+ return 3;
+}
+
/**
* quadtree_add - add a node to a quadtree
* @parent: parent node
* @new: the new node to be added
- * @compare: pointer to a comparison function
*
* Add a node to a quadtree. The tree is kept in order, the new node
- * is placed in the end of appropriate branch. The compare function is
- * used to compare the new node against a branch in the tree. The
- * comparison function must have following return value depending on
- * the position of node a compared to the position of node b:
- *
- * 0: upper left
- * 1: upper right
- * 2: lower left
- * 3: lower right
+ * is placed in the end of appropriate branch.
*
* The case of nodes sharing identical coordinates is not taken into
* account at all.
validate_tree(parent);
- ret = ops->compare(parent, new);
+ ret = quadtree_compare(parent, new);
if (ret < 0 || ret >= 4) {
printf("Invalid comparison result of %d\n", ret);