- 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
+ double dx, dy, length;
+ int i, j;
+ va_list ap;
+
+ /* Polygons are defined counter-clock-wise in a coordinate system
+ * with the y-axis pointing down. */
+
+ va_start (ap, num_points);
+ p->num_points = num_points;
+ p->points = g_new (Point, num_points);
+ p->enclosing = enclosing;
+
+ for (i = 0; i < num_points; i++) {
+ p->points[i].x = va_arg (ap, double);
+ p->points[i].y = va_arg (ap, double);
+ }
+ va_end (ap);
+
+ p->normals = g_new (Vector, p->num_points);
+ /* Compute outward pointing normals. p->normals[i] is the normal
+ * for the edged between p->points[i] and p->points[i + 1]. */
+ for (i = 0; i < p->num_points; i++) {
+ j = (i + 1) % p->num_points;
+ dx = p->points[j].x - p->points[i].x;
+ dy = p->points[j].y - p->points[i].y;
+ length = sqrt (dx * dx + dy * dy);
+ p->normals[i].x = -dy / length;
+ p->normals[i].y = dx / length;
+ }