From: Kristian Høgsberg Date: Fri, 9 Jun 2006 16:49:14 +0000 (-0400) Subject: Add new Spacer constraint and a 'dock' model. X-Git-Url: https://git.cworth.org/git?p=akamaru;a=commitdiff_plain;h=ac886f983a984a951187fae89c530858013ef118 Add new Spacer constraint and a 'dock' model. --- diff --git a/akamaru.c b/akamaru.c index 22b2477..ae01a27 100644 --- a/akamaru.c +++ b/akamaru.c @@ -68,6 +68,14 @@ offset_spring_init (OffsetSpring *spring, Object *a, Object *b, spring->dy = dy; } +void +spacer_init (Spacer *spacer, Object *a, Object *b, double length) +{ + spacer->a = a; + spacer->b = b; + spacer->length = length; +} + void polygon_init (Polygon *p, int num_points, ...) { @@ -91,7 +99,7 @@ polygon_init (Polygon *p, int num_points, ...) 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++) { + 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; @@ -131,6 +139,7 @@ model_fini (Model *model) g_free (model->offsets[i].objects); g_free (model->springs); g_free (model->offset_springs); + g_free (model->spacers); for (i = 0; i < model->num_polygons; i++) g_free (model->polygons[i].points); g_free (model->polygons); @@ -359,6 +368,22 @@ model_constrain (Model *model) model->strings[i].b->position.y = y + dy * (1 - fraction); } + /* Spacer constraints. */ + for (i = 0; i < model->num_spacers; i++) { + x = model->spacers[i].a->position.x; + y = model->spacers[i].a->position.y; + dx = model->spacers[i].b->position.x - x; + dy = model->spacers[i].b->position.y - y; + distance = estimate_distance (dx, dy, model->spacers[i].length); + if (distance > model->spacers[i].length) + continue; + fraction = (distance - model->spacers[i].length) / distance / 2; + model->spacers[i].a->position.x = x + dx * fraction; + model->spacers[i].a->position.y = y + dy * fraction; + model->spacers[i].b->position.x = x + dx * (1 - fraction); + model->spacers[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; @@ -389,7 +414,7 @@ model_step (Model *model, double delta_t) model_accumulate_forces (model); model_integrate (model, delta_t); - for (i = 0; i < 50; i++) + for (i = 0; i < 2; i++) model_constrain (model); model->theta += delta_t; diff --git a/akamaru.h b/akamaru.h index 9b544ae..1646a34 100644 --- a/akamaru.h +++ b/akamaru.h @@ -12,6 +12,7 @@ typedef struct _Stick Stick; typedef struct _String String; typedef struct _Spring Spring; typedef struct _OffsetSpring OffsetSpring; +typedef struct _Spacer Spacer; typedef struct _Polygon Polygon; typedef struct _Offset Offset; typedef struct _Model Model; @@ -53,6 +54,11 @@ struct _OffsetSpring { int dx, dy; }; +struct _Spacer { + Object *a, *b; + int length; +}; + struct _Polygon { int num_points; Point *points; @@ -73,6 +79,8 @@ struct _Model { Spring *springs; int num_offset_springs; OffsetSpring *offset_springs; + int num_spacers; + Spacer *spacers; int num_polygons; Polygon *polygons; double k; @@ -90,6 +98,7 @@ void offset_spring_init (OffsetSpring *spring, void spring_init (Spring *spring, Object *a, Object *b, double length); void stick_init (Stick *stick, Object *a, Object *b, double length); void string_init (String *string, Object *a, Object *b, double length); +void spacer_init (Spacer *spacer, Object *a, Object *b, double length); void polygon_init (Polygon *p, int num_points, ...); void polygon_init_diamond (Polygon *polygon, double x, double y); diff --git a/main.c b/main.c index 2423b4f..39cb5ad 100644 --- a/main.c +++ b/main.c @@ -261,6 +261,53 @@ model_init_wobbly (Model *model) } } +static void +model_init_dock (Model *model) +{ + const int num_objects = 8; + const int num_spacers = (num_objects - 1) * (num_objects - 2) / 2; + const int num_springs = num_objects - 1; + const int distance = 30; + double x, y; + int i, j; + Object *object; + Spring *spring; + Spacer *spacer; + + memset (model, 0, sizeof *model); + model->objects = g_new (Object, num_objects); + model->num_objects = num_objects; + model->springs = g_new (Spring, num_springs); + model->num_springs = num_springs; + model->spacers = g_new (Spacer, num_spacers); + model->num_spacers = num_spacers; + model->k = 0.1; + + model_init_polygons (model); + model->polygons = g_new (Polygon, 1); + polygon_init_rectangle (&model->polygons[0], -400, 300, 1400, 350); + model->num_polygons = 1; + + + object = model->objects; + spring = model->springs; + spacer = model->spacers; + for (i = 0; i < num_objects; i++, object++) { + x = 200 + i * distance / 3; + y = 40; + object_init (object, x, y, 1); + if (i == 0) + continue; + spring_init (spring++, + &model->objects[0], + &model->objects[i], + distance); + for (j = 1; j < num_objects - i; j++) { + spacer_init (spacer++, object, object + j, distance); + } + } +} + typedef struct _Color Color; struct _Color { double red, green, blue; @@ -554,7 +601,8 @@ create_model_store (void) { "Curtain", model_init_curtain }, { "Grid", model_init_grid }, { "Molecule", model_init_molecule }, - { "Wobbly", model_init_wobbly } + { "Wobbly", model_init_wobbly }, + { "Dock", model_init_dock } }; GtkTreeIter iter;