From e1406efa6e1f29a8a72ddaa2db18f250fdf2ec42 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 23 May 2006 14:45:31 -0400 Subject: [PATCH] Add new OffsetSpring force and implement a wobbly patch. --- akamaru.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 120 insertions(+), 11 deletions(-) diff --git a/akamaru.c b/akamaru.c index 17c70e9..2ee99ad 100644 --- a/akamaru.c +++ b/akamaru.c @@ -27,7 +27,7 @@ #include const double ground_level = 500; -const double elasticity = 0.7; +const double elasticity = 0.8; typedef struct _xy_pair Point; typedef struct _xy_pair Vector; @@ -39,6 +39,7 @@ typedef struct _Object Object; typedef struct _Stick Stick; typedef struct _String String; typedef struct _Spring Spring; +typedef struct _OffsetSpring OffsetSpring; typedef struct _Polygon Polygon; typedef struct _Offset Offset; typedef struct _Model Model; @@ -75,6 +76,11 @@ struct _Spring { int length; }; +struct _OffsetSpring { + Object *a, *b; + int dx, dy; +}; + struct _Polygon { int num_points; Point *points; @@ -93,6 +99,8 @@ struct _Model { Offset *offsets; int num_springs; Spring *springs; + int num_offset_springs; + OffsetSpring *offset_springs; int num_polygons; Polygon *polygons; double k; @@ -169,7 +177,6 @@ model_init_polygons (Model *model) polygon_init_rectangle (&model->polygons[4], 300, 320, 400, 350); - model->num_polygons = num_polygons; } @@ -295,13 +302,13 @@ model_init_curtain (Model *model) static void model_init_grid (Model *model) { - const int num_ropes = 10; - const int num_rope_objects = 10; + const int num_ropes = 4; + const int num_rope_objects = 4; const int num_objects = num_ropes * num_rope_objects; const int num_strings = num_ropes * (num_rope_objects - 1) + (num_ropes - 1) * num_rope_objects; - const int string_length = 10; - const int rope_offset = 10; + const int string_length = 20; + const int rope_offset = 20; double x, y; int i, j, index, string_index; @@ -385,6 +392,60 @@ model_init_molecule (Model *model) } } + +static void +model_init_wobbly (Model *model) +{ + const int width = 6, height = 6; + const int num_objects = width * height; + const int num_offset_springs = (width - 1) * height + width * (height - 1); + const int distance = 30; + double x, y; + int i, j, object_index, spring_index; + + memset (model, 0, sizeof *model); + model->objects = g_new (Object, num_objects); + model->num_objects = num_objects; + model->offset_springs = g_new (OffsetSpring, num_offset_springs); + model->num_offset_springs = num_offset_springs; + model->k = 0.6; + + model_init_polygons (model); + + object_index = 0; + spring_index = 0; + for (i = 0; i < width; i++) { + for (j = 0; j < height; j++) { + x = 200 + i * distance; + y = 40 + j * distance; + model->objects[object_index].position.x = x; + model->objects[object_index].position.y = y; + model->objects[object_index].previous_position.x = x; + model->objects[object_index].previous_position.y = y; + model->objects[object_index].mass = 0.3; + + if (i + 1 < width) { + model->offset_springs[spring_index].a = &model->objects[object_index]; + model->offset_springs[spring_index].b = &model->objects[object_index + height]; + model->offset_springs[spring_index].dx = distance; + model->offset_springs[spring_index].dy = 0; + spring_index++; + } + + if (j + 1 < height) { + model->offset_springs[spring_index].a = &model->objects[object_index]; + model->offset_springs[spring_index].b = &model->objects[object_index + 1]; + model->offset_springs[spring_index].dx = 0; + model->offset_springs[spring_index].dy = distance; + spring_index++; + } + + object_index++; + } + } +} + + static void model_fini (Model *model) { @@ -400,6 +461,7 @@ model_accumulate_forces (Model *model) { int i; double x, y, dx, dy, distance, displacement; + Point middle; Vector u; for (i = 0; i < model->num_objects; i++) { @@ -421,6 +483,26 @@ model_accumulate_forces (Model *model) model->springs[i].b->force.x -= u.x * model->k * displacement; model->springs[i].b->force.y -= u.y * model->k * displacement; } + + for (i = 0; i < model->num_offset_springs; i++) { + middle.x = + (model->offset_springs[i].a->position.x + + model->offset_springs[i].b->position.x) / 2; + middle.y = + (model->offset_springs[i].a->position.y + + model->offset_springs[i].b->position.y) / 2; + + x = middle.x - model->offset_springs[i].dx / 2; + y = middle.y - model->offset_springs[i].dy / 2; + + dx = x - model->offset_springs[i].a->position.x; + dy = y - model->offset_springs[i].a->position.y; + + model->offset_springs[i].a->force.x += dx * model->k; + model->offset_springs[i].a->force.y += dy * model->k; + model->offset_springs[i].b->force.x -= dx * model->k; + model->offset_springs[i].b->force.y -= dy * model->k; + } } static void @@ -436,9 +518,9 @@ model_integrate (Model *model, double step) y = o->position.y; o->position.x = - x + 0.8 * (x - o->previous_position.x) + o->force.x * step * step; + x + 0.9 * (x - o->previous_position.x) + o->force.x * step * step; o->position.y = - y + 0.8 * (y - o->previous_position.y) + o->force.y * step * step; + y + 0.9 * (y - o->previous_position.y) + o->force.y * step * step; o->previous_position.x = x; o->previous_position.y = y; @@ -610,7 +692,7 @@ model_step (Model *model, double delta_t) model_accumulate_forces (model); model_integrate (model, delta_t); - for (i = 0; i < 500; i++) + for (i = 0; i < 50; i++) model_constrain (model); model->theta += delta_t; @@ -749,6 +831,31 @@ draw_springs (cairo_t *cr, cairo_stroke (cr); } +static void +draw_offset_springs (cairo_t *cr, + Model *model, + Color *color) +{ + int i; + + cairo_set_source_rgba (cr, color->red, color->green, color->blue, 0.4); + cairo_new_path (cr); + cairo_set_line_width (cr, 2); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + + for (i = 0; i < model->num_offset_springs; i++) { + cairo_move_to (cr, + model->offset_springs[i].a->position.x, + model->offset_springs[i].a->position.y); + cairo_line_to (cr, + model->offset_springs[i].b->position.x, + model->offset_springs[i].b->position.y); + } + + cairo_stroke (cr); +} + static void draw_polygons (cairo_t *cr, Model *model, Color *color) { @@ -812,6 +919,7 @@ draw_model (GtkWidget *widget, Model *model) draw_strings (cr, model, &green); draw_springs (cr, model, &black); draw_offsets (cr, model, &blue); + draw_offset_springs (cr, model, &blue); draw_objects (cr, model, &red); cairo_destroy (cr); @@ -911,7 +1019,8 @@ create_model_store (void) { "Snake", model_init_snake }, { "Curtain", model_init_curtain }, { "Grid", model_init_grid }, - { "Molecule", model_init_molecule } + { "Molecule", model_init_molecule }, + { "Wobbly", model_init_wobbly } }; GtkTreeIter iter; @@ -1087,7 +1196,7 @@ main (int argc, char *argv[]) closure.model = &model; closure.frame_count = 0; gettimeofday (&closure.start, NULL); - g_timeout_add (100, timeout_callback, &closure); + g_timeout_add (40, timeout_callback, &closure); gtk_main (); return 0; -- 2.43.0