diff options
Diffstat (limited to 'akamaru.c')
-rw-r--r-- | akamaru.c | 101 |
1 files changed, 82 insertions, 19 deletions
@@ -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++) { @@ -121,6 +132,8 @@ model_init_rope (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; @@ -156,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; @@ -191,27 +206,29 @@ model_init_curtain (Model *model) static void model_init_grid (Model *model) { - const int num_ropes = 15; - const int num_rope_objects = 15; + const int num_ropes = 4; + const int num_rope_objects = 4; const int num_objects = num_ropes * num_rope_objects; - const int num_sticks = num_ropes * (num_rope_objects - 1) + + const int num_strings = num_ropes * (num_rope_objects - 1) + (num_ropes - 1) * num_rope_objects; - const int stick_length = 10; - const int rope_offset = 10; + const int string_length = 30; + const int rope_offset = 30; double x, y; - int i, j, index, stick_index; + int i, j, index, string_index; 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->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 * stick_length; + y = 40 + j * string_length; index = i * num_rope_objects + j; model->objects[index].position.x = x; model->objects[index].position.y = y; @@ -219,18 +236,18 @@ model_init_grid (Model *model) model->objects[index].previous_position.y = y; if (i + 1 < num_ropes) { - stick_index = i * num_rope_objects + j; - model->sticks[stick_index].a = &model->objects[index]; - model->sticks[stick_index].b = &model->objects[index + num_rope_objects]; - model->sticks[stick_index].length = stick_length; + 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) { - stick_index = + string_index = (num_ropes - 1) * num_rope_objects + i * (num_rope_objects - 1) + j; - model->sticks[stick_index].a = &model->objects[index]; - model->sticks[stick_index].b = &model->objects[index + 1]; - model->sticks[stick_index].length = stick_length; + model->strings[string_index].a = &model->objects[index]; + model->strings[string_index].b = &model->objects[index + 1]; + model->strings[string_index].length = string_length; } } @@ -254,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; @@ -266,7 +286,7 @@ model_accumulate_forces (Model *model) for (i = 0; i < model->num_objects; i++) { model->objects[i].force.x = 0; - model->objects[i].force.y = 2; + model->objects[i].force.y = 3; } } @@ -350,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++) { @@ -390,7 +426,7 @@ model_step (Model *model, double delta_t) model_accumulate_forces (model); model_integrate (model, delta_t); - for (i = 0; i < 15; i++) + for (i = 0; i < 35; i++) model_constrain (model, delta_t); model->theta += delta_t; @@ -456,6 +492,31 @@ draw_sticks (cairo_t *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, Color *color) @@ -512,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 }; @@ -531,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); |