summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2006-05-23 14:45:31 -0400
committerKristian Høgsberg <krh@dinky.bitplanet.net>2006-05-23 14:45:31 -0400
commite1406efa6e1f29a8a72ddaa2db18f250fdf2ec42 (patch)
tree0b49abab6b5f2ff7be55fa60419b698b74d087ec
parent4d57fbbcfb5e364daab875ad1ff2a3f7fc2e1bb1 (diff)
Add new OffsetSpring force and implement a wobbly patch.
-rw-r--r--akamaru.c131
1 files 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 <math.h>
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;
@@ -750,6 +832,31 @@ draw_springs (cairo_t *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)
{
Polygon *p;
@@ -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;