X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=akamaru.c;h=fe14d2009e4e7e9c3da3f9630a067ac10ae71250;hb=735b07c387e91b2fd4c39d690f1e6fa91f32d3f5;hp=48a226e93fbdb940a95d2fd9e9ac225c7063b958;hpb=f7a5c852f4b6af4a3b1f489c333e338799d6cb00;p=akamaru diff --git a/akamaru.c b/akamaru.c index 48a226e..fe14d20 100644 --- a/akamaru.c +++ b/akamaru.c @@ -35,6 +35,7 @@ struct _xy_pair { typedef struct _Object Object; typedef struct _Stick Stick; +typedef struct _String String; typedef struct _Offset Offset; typedef struct _Model Model; @@ -54,6 +55,11 @@ struct _Stick { int length; }; +struct _String { + Object *a, *b; + int length; +}; + struct _Offset { Object *a, *b; int dx, dy; @@ -64,6 +70,8 @@ struct _Model { Object *objects; int num_sticks; Stick *sticks; + int num_strings; + String *strings; int num_offsets; Offset *offsets; double k; @@ -86,6 +94,9 @@ model_init_snake (Model *model) model->num_objects = num_objects; model->sticks = g_new (Stick, num_sticks); model->num_sticks = num_sticks; + model->strings = NULL; + model->num_strings = 0; + model->offsets = NULL; model->num_offsets = 0; for (i = 0; i < num_objects; i++) { @@ -114,13 +125,17 @@ model_init_rope (Model *model) { const int num_objects = 20; const int num_sticks = num_objects - 1; - const int stick_length = 20; + const int stick_length = 5; int i; model->objects = g_new (Object, num_objects); model->num_objects = num_objects; model->sticks = g_new (Stick, num_sticks); model->num_sticks = num_sticks; + model->strings = NULL; + model->num_strings = 0; + model->offsets = NULL; + model->num_offsets = 0; for (i = 0; i < num_objects; i++) { model->objects[i].position.x = 200; @@ -154,6 +169,8 @@ model_init_curtain (Model *model) model->num_objects = num_objects; model->sticks = g_new (Stick, num_sticks); model->num_sticks = num_sticks; + model->strings = NULL; + model->num_strings = 0; model->offsets = g_new (Offset, num_ropes - 1); model->num_offsets = num_ropes - 1; @@ -186,6 +203,65 @@ model_init_curtain (Model *model) model->anchor_object = NULL; } +static void +model_init_grid (Model *model) +{ + 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 = 30; + const int rope_offset = 30; + double x, y; + int i, j, index, string_index; + + model->objects = g_new (Object, num_objects); + model->num_objects = num_objects; + model->sticks = NULL; + model->num_sticks = 0; + model->strings = g_new (String, num_strings); + model->num_strings = num_strings; + model->offsets = g_new (Offset, num_ropes - 1); + model->num_offsets = num_ropes - 1; + + for (i = 0; i < num_ropes; i++) { + for (j = 0; j < num_rope_objects; j++) { + x = 200 + i * rope_offset; + y = 40 + j * string_length; + index = i * num_rope_objects + j; + model->objects[index].position.x = x; + model->objects[index].position.y = y; + model->objects[index].previous_position.x = x; + model->objects[index].previous_position.y = y; + + if (i + 1 < num_ropes) { + string_index = i * num_rope_objects + j; + model->strings[string_index].a = &model->objects[index]; + model->strings[string_index].b = &model->objects[index + num_rope_objects]; + model->strings[string_index].length = string_length; + } + + if (j + 1 < num_rope_objects) { + string_index = + (num_ropes - 1) * num_rope_objects + i * (num_rope_objects - 1) + j; + model->strings[string_index].a = &model->objects[index]; + model->strings[string_index].b = &model->objects[index + 1]; + model->strings[string_index].length = string_length; + } + } + + if (i + 1 < num_ropes) { + model->offsets[i].a = &model->objects[i * num_rope_objects]; + model->offsets[i].b = &model->objects[(i + 1) * num_rope_objects]; + model->offsets[i].dx = rope_offset; + model->offsets[i].dy = 0; + } + } + + model->anchor_object = NULL; +} + static void model_fini (Model *model) { @@ -195,6 +271,9 @@ model_fini (Model *model) g_free (model->sticks); model->sticks = NULL; model->sticks = 0; + g_free (model->strings); + model->strings = NULL; + model->strings = 0; g_free (model->offsets); model->offsets = NULL; model->num_offsets = 0; @@ -291,6 +370,22 @@ model_constrain (Model *model, double step) 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 = sqrt (dx * dx + dy * dy); + 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); + } + #if 1 /* Stick constraints. */ for (i = 0; i < model->num_sticks; i++) { @@ -331,7 +426,7 @@ model_step (Model *model, double delta_t) model_accumulate_forces (model); model_integrate (model, delta_t); - for (i = 0; i < 5; i++) + for (i = 0; i < 35; i++) model_constrain (model, delta_t); model->theta += delta_t; @@ -396,6 +491,31 @@ draw_sticks (cairo_t *cr, cairo_stroke (cr); } +static void +draw_strings (cairo_t *cr, + Model *model, + Color *color) +{ + int i; + + cairo_set_source_rgba (cr, color->red, color->green, color->blue, 1); + cairo_new_path (cr); + cairo_set_line_width (cr, 1); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + + for (i = 0; i < model->num_strings; i++) { + cairo_move_to (cr, + model->strings[i].a->position.x, + model->strings[i].a->position.y); + cairo_line_to (cr, + model->strings[i].b->position.x, + model->strings[i].b->position.y); + } + + cairo_stroke (cr); +} + static void draw_offsets (cairo_t *cr, Model *model, @@ -453,6 +573,7 @@ draw_objects (cairo_t *cr, Model *model, Color *color) } static Color blue = { 0, 0, 1 }; +static Color green = { 0, 1, 0 }; static Color red = { 1, 0, 0 }; static Color black = { 0, 0, 0 }; static Color white = { 1, 1, 1 }; @@ -472,6 +593,7 @@ expose_event (GtkWidget *widget, draw_constraints (cr, model, &red); draw_sticks (cr, model, &black); + draw_strings (cr, model, &green); draw_offsets (cr, model, &blue); draw_objects (cr, model, &white); @@ -559,7 +681,8 @@ create_model_store (void) } models[] = { { "Rope", model_init_rope }, { "Snake", model_init_snake }, - { "Curtain", model_init_curtain } + { "Curtain", model_init_curtain }, + { "Grid", model_init_grid } }; GtkTreeIter iter;