From: Kristian Høgsberg Date: Sat, 20 May 2006 03:46:33 +0000 (-0400) Subject: Add new 'Offset' constraint, new 'curtain' model and clean up drawing code. X-Git-Url: https://git.cworth.org/git?p=akamaru;a=commitdiff_plain;h=199d00194b17db8dfdad622b33f659a55b07b076 Add new 'Offset' constraint, new 'curtain' model and clean up drawing code. --- diff --git a/akamaru.c b/akamaru.c index 1c97fc5..629d01f 100644 --- a/akamaru.c +++ b/akamaru.c @@ -35,6 +35,7 @@ struct _xy_pair { typedef struct _Object Object; typedef struct _Stick Stick; +typedef struct _Offset Offset; typedef struct _Model Model; struct _Object { @@ -53,11 +54,18 @@ struct _Stick { int length; }; +struct _Offset { + Object *a, *b; + int dx, dy; +}; + struct _Model { int num_objects; Object *objects; int num_sticks; Stick *sticks; + int num_offsets; + Offset *offsets; double k; double friction; @@ -78,6 +86,7 @@ model_init_snake (Model *model) model->num_objects = num_objects; model->sticks = g_new (Stick, num_sticks); model->num_sticks = num_sticks; + model->num_offsets = 0; for (i = 0; i < num_objects; i++) { model->objects[i].position.x = random() % 200 + 20; @@ -129,6 +138,54 @@ model_init_rope (Model *model) model->anchor_object = NULL; } +static void +model_init_curtain (Model *model) +{ + const int num_ropes = 5; + const int num_rope_objects = 15; + const int num_objects = num_ropes * num_rope_objects; + const int num_sticks = num_ropes * (num_rope_objects - 1); + const int stick_length = 10; + const int rope_offset = 30; + double x, y; + int i, j, index, stick_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->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; + 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 (j + 1 < num_rope_objects) { + stick_index = 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; + } + } + + 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_accumulate_forces (Model *model) { @@ -165,7 +222,7 @@ model_integrate (Model *model, double step) static void model_constrain (Model *model, double step) { - double dx, dy, x, y, distance, fraction, squared; + double dx, dy, x, y, distance, fraction; int i; /* Anchor object constraint. */ @@ -210,6 +267,16 @@ model_constrain (Model *model, double step) } } + /* 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++) { @@ -250,7 +317,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 < 5; i++) model_constrain (model, delta_t); model->theta += delta_t; @@ -291,41 +358,34 @@ struct _Color { }; static void -draw_star (cairo_t *cr, - gdouble cx, - gdouble cy, - double theta, - Color *color) +draw_sticks (cairo_t *cr, + Model *model, + Color *color) { - const int spike_count = 5; - const int inner_radius = 2; - const int outer_radius = 4; - double x, y; int i; - cairo_set_source_rgba (cr, color->red, color->green, color->blue, 0.5); + cairo_set_source_rgba (cr, color->red, color->green, color->blue, 1); cairo_new_path (cr); - for (i = 0; i < spike_count; i++) { - x = cx + cos ((i * 2) * M_PI / spike_count + theta) * inner_radius; - y = cy + sin ((i * 2) * M_PI / spike_count + theta) * inner_radius; - - if (i == 0) - cairo_move_to (cr, x, y); - else - cairo_line_to (cr, x, y); - - x = cx + cos ((i * 2 + 1) * M_PI / spike_count + theta) * outer_radius; - y = cy + sin ((i * 2 + 1) * M_PI / spike_count + theta) * outer_radius; - - cairo_line_to (cr, x, y); + 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_sticks; i++) { + cairo_move_to (cr, + model->sticks[i].a->position.x, + model->sticks[i].a->position.y); + cairo_line_to (cr, + model->sticks[i].b->position.x, + model->sticks[i].b->position.y); } - cairo_fill (cr); + + cairo_stroke (cr); } static void -draw_lines (cairo_t *cr, - Model *model, - Color *color) +draw_offsets (cairo_t *cr, + Model *model, + Color *color) { int i; @@ -335,13 +395,13 @@ draw_lines (cairo_t *cr, cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); - for (i = 0; i < model->num_sticks; i++) { + for (i = 0; i < model->num_offsets; i++) { cairo_move_to (cr, - model->sticks[i].a->position.x, - model->sticks[i].a->position.y); + model->offsets[i].a->position.x, + model->offsets[i].a->position.y); cairo_line_to (cr, - model->sticks[i].b->position.x, - model->sticks[i].b->position.y); + model->offsets[i].b->position.x, + model->offsets[i].b->position.y); } cairo_stroke (cr); @@ -369,8 +429,19 @@ draw_constraints (cairo_t *cr, cairo_fill (cr); } +static void +draw_objects (cairo_t *cr, Model *model, Color *color) +{ + int i; + + for (i = 0; i < model->num_objects; i++) { + } +} + static Color blue = { 0, 0, 1 }; static Color red = { 1, 0, 0 }; +static Color black = { 0, 0, 0 }; +static Color white = { 1, 1, 1 }; static gboolean sproing_expose_event (GtkWidget *widget, @@ -386,14 +457,9 @@ sproing_expose_event (GtkWidget *widget, cairo_paint (cr); draw_constraints (cr, model, &red); - draw_lines (cr, model, &blue); - -#if 0 - for (i = 0; i < model->num_objects; i++) { - draw_star (widget, model->objects[i].position.x, - model->objects[i].position.y, model->objects[i].theta, &blue); - } -#endif + draw_sticks (cr, model, &black); + draw_offsets (cr, model, &blue); + draw_objects (cr, model, &white); cairo_destroy (cr); @@ -591,7 +657,7 @@ main (int argc, char *argv[]) Model model; gtk_init (&argc, &argv); - model_init_snake (&model); + model_init_curtain (&model); closure.drawing_area = create_window (&model); closure.i = 0; gtk_widget_show_all (gtk_widget_get_toplevel (closure.drawing_area));