- int i, edge;
- double d, distance;
- Vector *n;
-
- distance = -1000;
- for (i = 0; i < polygon->num_points; i++) {
- d = polygon->normals[i].x * (object->position.x - polygon->points[i].x) +
- polygon->normals[i].y * (object->position.y - polygon->points[i].y);
-
- if (d > distance) {
- distance = d;
- edge = i;
- polygon->edge = i;
- n = &polygon->normals[i];
- }
- }
-
- object->position.x -= (1 + elasticity) * distance * n->x;
- object->position.y -= (1 + elasticity) * distance * n->y;
-
- distance =
- n->x * (object->previous_position.x - polygon->points[edge].x) +
- n->y * (object->previous_position.y - polygon->points[edge].y);
-
- object->previous_position.x -= (1 + elasticity) * distance * n->x;
- object->previous_position.y -= (1 + elasticity) * distance * n->y;
-}
-
-static void
-model_constrain_polygon (Model *model, Polygon *polygon)
-{
- int i;
-
- for (i = 0; i < model->num_objects; i++) {
- if (polygon_contains_point (polygon, &model->objects[i].position))
- polygon_reflect_object (polygon, &model->objects[i]);
- }
-}
-
-static void
-model_constrain (Model *model)
-{
- 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;
- }
-
- /* 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;
- }
-
- /* String constraints. */
- for (i = 0; i < model->num_strings; i++) {
- x = model->strings[i].a->position.x;
- y = model->strings[i].a->position.y;
- dx = model->strings[i].b->position.x - x;
- dy = model->strings[i].b->position.y - y;
- distance = estimate_distance (dx, dy, model->strings[i].length);
- if (distance < model->strings[i].length)
- continue;
- fraction = (distance - model->strings[i].length) / distance / 2;
- model->strings[i].a->position.x = x + dx * fraction;
- model->strings[i].a->position.y = y + dy * fraction;
- model->strings[i].b->position.x = x + dx * (1 - fraction);
- model->strings[i].b->position.y = y + dy * (1 - fraction);
- }
-
- /* 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 = estimate_distance (dx, dy, model->sticks[i].length);
- 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);
- }
-
- /* Polygon constraints. */
- for (i = 0; i < model->num_polygons; i++)
- model_constrain_polygon (model, &model->polygons[i]);
-}