- double dx, dy, x, y, distance, fraction;
- int i;
-
- /* Anchor object constraint. */
- if (model->anchor_object != NULL) {
- model->anchor_object->position.x = model->anchor_position.x;
- model->anchor_object->position.y = model->anchor_position.y;
- model->anchor_object->previous_position.x = model->anchor_position.x;
- model->anchor_object->previous_position.y = model->anchor_position.y;
- }
-
- /* FIXME: this should be "is point inside box" test instead. Figure
- * out from previous_position which edge the point has passed
- * through and reflect in that. */
- for (i = 0; i < model->num_objects; i++) {
- x = model->objects[i].position.x;
- y = model->objects[i].position.y;
- if (box_top - edge_fuzz <= y &&
- model->objects[i].previous_position.y <= box_top + edge_fuzz &&
- x < box_left) {
- model->objects[i].position.y = box_top - (y - box_top) * elasticity;
- model->objects[i].previous_position.y =
- box_top - (model->objects[i].previous_position.y - box_top) * elasticity;
- }
- }
-
- /* Ground collision detection constraints. This puts a ground level
- * in to make sure the points don't fall off the screen. */
- for (i = 0; i < model->num_objects; i++) {
- x = model->objects[i].position.x;
- y = model->objects[i].position.y;
-
- if (model->objects[i].position.y > ground_level) {
- model->objects[i].position.y =
- ground_level - (model->objects[i].position.y - ground_level) * elasticity;
- model->objects[i].previous_position.y =
- ground_level - (model->objects[i].previous_position.y - ground_level) * elasticity;
-
- /* Friction on impact */
- model->objects[i].position.x =
- model->objects[i].position.x * (1 - ground_friction) +
- model->objects[i].previous_position.x * ground_friction;
- }
- }
-
- /* Offset constraints. */
- for (i = 0; i < model->num_offsets; i++) {
- x = (model->offsets[i].a->position.x + model->offsets[i].b->position.x) / 2;
- y = (model->offsets[i].a->position.y + model->offsets[i].b->position.y) / 2;
- model->offsets[i].a->position.x = x - model->offsets[i].dx / 2;
- model->offsets[i].a->position.y = y - model->offsets[i].dy / 2;
- model->offsets[i].b->position.x = x + model->offsets[i].dx / 2;
- model->offsets[i].b->position.y = y + model->offsets[i].dy / 2;
- }
-
-#if 1
- /* Stick constraints. */
- for (i = 0; i < model->num_sticks; i++) {
- x = model->sticks[i].a->position.x;
- y = model->sticks[i].a->position.y;
- dx = model->sticks[i].b->position.x - x;
- dy = model->sticks[i].b->position.y - y;
- distance = sqrt (dx * dx + dy * dy);
- fraction = (distance - model->sticks[i].length) / distance / 2;
- model->sticks[i].a->position.x = x + dx * fraction;
- model->sticks[i].a->position.y = y + dy * fraction;
- model->sticks[i].b->position.x = x + dx * (1 - fraction);
- model->sticks[i].b->position.y = y + dy * (1 - fraction);
- }
-#else
- /* Stick constraints, without square roots. */
- squared = stick_length * stick_length;
- for (i = 0; i < model->num_objects - 1; i++) {
- j = i + 1;
- x = model->objects[i].position.x;
- y = model->objects[i].position.y;
- dx = model->objects[j].position.x - x;
- dy = model->objects[j].position.y - y;
- fraction = squared / (dx * dx + dy * dy + squared) - 0.5;
- model->objects[i].position.x = x + dx * fraction;
- model->objects[i].position.y = y + dy * fraction;
- model->objects[j].position.x = x + dx * (1 - fraction);
- model->objects[j].position.y = y + dy * (1 - fraction);
- }
-#endif