summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2006-07-08 05:16:11 -0400
committerKristian Høgsberg <krh@redhat.com>2006-07-08 05:16:11 -0400
commitcde68c08fa0a7cc76900f6218eb972a6cbc660a5 (patch)
treee93d7948f49f84bf7ff9cc99a020bd0fd83540ed
parentf7258dd26ef90de18bfc1b36ea4559342bb600eb (diff)
Make more of the model dynamic, start porting over main.c.
-rw-r--r--akamaru.c159
-rw-r--r--akamaru.h10
-rw-r--r--main.c58
3 files changed, 136 insertions, 91 deletions
diff --git a/akamaru.c b/akamaru.c
index 836e2d9..5a9baa0 100644
--- a/akamaru.c
+++ b/akamaru.c
@@ -109,6 +109,20 @@ stick_init (Stick *stick, Object *a, Object *b, double length)
stick->length = length;
}
+Stick *
+model_add_stick (Model *model, Object *a, Object *b, double length)
+{
+ Stick *stick;
+
+ stick = g_new (Stick, 1);
+ stick->a = a;
+ stick->b = b;
+ stick->length = length;
+ list_append (&model->stick_list, stick);
+
+ return stick;
+}
+
void
string_init (String *string, Object *a, Object *b, double length)
{
@@ -117,6 +131,20 @@ string_init (String *string, Object *a, Object *b, double length)
string->length = length;
}
+String *
+model_add_string (Model *model, Object *a, Object *b, double length)
+{
+ String *string;
+
+ string = g_new (String, 1);
+ string->a = a;
+ string->b = b;
+ string->length = length;
+ list_append (&model->string_list, string);
+
+ return string;
+}
+
void
offset_spring_init (OffsetSpring *spring, Object *a, Object *b,
double dx, double dy)
@@ -267,8 +295,11 @@ model_init (Model *model)
list_init (&model->object_list, G_STRUCT_OFFSET (Object, link));
list_init (&model->spacer_list, G_STRUCT_OFFSET (Spacer, link));
list_init (&model->spring_list, G_STRUCT_OFFSET (Spring, link));
+ list_init (&model->stick_list, G_STRUCT_OFFSET (Stick, link));
+ list_init (&model->string_list, G_STRUCT_OFFSET (String, link));
list_init (&model->anchor_list, G_STRUCT_OFFSET (Anchor, link));
list_init (&model->polygon_list, G_STRUCT_OFFSET (Polygon, link));
+ list_init (&model->offset_list, G_STRUCT_OFFSET (Offset, link));
}
Object *
@@ -508,13 +539,12 @@ model_constrain_anchor (void *element, void *data)
anchor->object->position.x = anchor->x;
anchor->object->position.y = anchor->y;
- anchor->object->previous_position.x = anchor->x;
- anchor->object->previous_position.y = anchor->y;
}
static void
-model_constrain_offset (Model *model, Offset *offset)
+model_constrain_offset (void *element, void *data)
{
+ Offset *offset = element;
double x, y;
int i;
@@ -535,6 +565,29 @@ model_constrain_offset (Model *model, Offset *offset)
}
static void
+model_constrain_string (void *element, void *data)
+{
+ String *string = element;
+ double x, y, dx, dy, distance, fraction;
+
+ x = string->a->position.x;
+ y = string->a->position.y;
+ dx = string->b->position.x - x;
+ dy = string->b->position.y - y;
+ distance = estimate_distance (dx, dy, string->length);
+
+ if (distance < string->length)
+ return;
+
+ fraction = (distance - string->length) / distance / 2;
+ string->a->position.x = x + dx * fraction;
+ string->a->position.y = y + dy * fraction;
+ string->b->position.x = x + dx * (1 - fraction);
+ string->b->position.y = y + dy * (1 - fraction);
+}
+
+
+static void
model_constrain_spacer (void *element, void *data)
{
Spacer *spacer = element;
@@ -556,53 +609,34 @@ model_constrain_spacer (void *element, void *data)
spacer->b->position.y = y + dy * (1 - fraction);
}
-
static void
-model_constrain (Model *model)
+model_constrain_stick (void *element, void *data)
{
- double dx, dy, x, y, distance, fraction;
- int i;
-
- list_for_each (&model->anchor_list, model_constrain_anchor, model);
-
- /* 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 = estimate_distance (dx, dy, model->strings[i].length);
- 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);
- }
+ Stick *stick = element;
+ double x, y, dx, dy, distance, fraction;
- /* Spacer constraints. */
- list_for_each (&model->spacer_list, model_constrain_spacer, model);
+ x = stick->a->position.x;
+ y = stick->a->position.y;
+ dx = stick->b->position.x - x;
+ dy = stick->b->position.y - y;
- /* Stick constraints. */
- for (i = 0; i < model->num_sticks; i++) {
- x = model->sticks[i].a->position.x;
- y = model->sticks[i].a->position.y;
- dx = model->sticks[i].b->position.x - x;
- dy = model->sticks[i].b->position.y - y;
- distance = estimate_distance (dx, dy, model->sticks[i].length);
- fraction = (distance - model->sticks[i].length) / distance / 2;
- model->sticks[i].a->position.x = x + dx * fraction;
- model->sticks[i].a->position.y = y + dy * fraction;
- model->sticks[i].b->position.x = x + dx * (1 - fraction);
- model->sticks[i].b->position.y = y + dy * (1 - fraction);
- }
+ distance = estimate_distance (dx, dy, stick->length);
- /* Offset constraints. */
- for (i = 0; i < model->num_offsets; i++)
- model_constrain_offset (model, &model->offsets[i]);
+ fraction = (distance - stick->length) / distance / 2;
+ stick->a->position.x = x + dx * fraction;
+ stick->a->position.y = y + dy * fraction;
+ stick->b->position.x = x + dx * (1 - fraction);
+ stick->b->position.y = y + dy * (1 - fraction);
+}
- /* Polygon constraints. */
+static void
+model_constrain (Model *model)
+{
+ list_for_each (&model->anchor_list, model_constrain_anchor, model);
+ list_for_each (&model->string_list, model_constrain_string, model);
+ list_for_each (&model->spacer_list, model_constrain_spacer, model);
+ list_for_each (&model->stick_list, model_constrain_stick, model);
+ list_for_each (&model->offset_list, model_constrain_offset, model);
list_for_each (&model->polygon_list, model_constrain_polygon, model);
}
@@ -630,20 +664,35 @@ object_distance (Object *object, double x, double y)
return sqrt (dx*dx + dy*dy);
}
+typedef struct {
+ double x;
+ double y;
+ double distance;
+ Object *object;
+} FindNearestClosure;
+
+static void
+model_update_closest (Object *object, void *data)
+{
+ FindNearestClosure *closure = data;
+ double distance;
+
+ distance = object_distance (object, closure->x, closure->y);
+ if (closure->object == NULL || distance < closure->distance) {
+ closure->distance = distance;
+ closure->object = object;
+ }
+}
+
Object *
model_find_nearest (Model *model, double x, double y)
{
- Object *object;
- double distance, min_distance;
- int i;
+ FindNearestClosure closure;
- for (i = 0; i < model->num_objects; i++) {
- distance = object_distance (&model->objects[i], x, y);
- if (i == 0 || distance < min_distance) {
- min_distance = distance;
- object = &model->objects[i];
- }
- }
+ closure.x = x;
+ closure.y = y;
+ closure.object = NULL;
+ model_for_each_object (model, model_update_closest, &closure);
- return object;
+ return closure.object;
}
diff --git a/akamaru.h b/akamaru.h
index af3f772..b1284b1 100644
--- a/akamaru.h
+++ b/akamaru.h
@@ -53,17 +53,20 @@ struct _Object {
struct _Stick {
Object *a, *b;
int length;
+ Link link;
};
struct _String {
Object *a, *b;
int length;
+ Link link;
};
struct _Offset {
int num_objects;
Object **objects;
int dx, dy;
+ Link link;
};
struct _Spring {
@@ -100,9 +103,12 @@ struct _Polygon {
struct _Model {
List object_list;
List spacer_list;
+ List string_list;
+ List stick_list;
List spring_list;
List anchor_list;
List polygon_list;
+ List offset_list;
int num_objects;
Object *objects;
@@ -129,8 +135,6 @@ struct _Model {
double gravity;
int constrain_iterations;
- Anchor mouse_anchor;
-
double theta;
};
@@ -160,6 +164,8 @@ void model_for_each_object (Model *model, ObjectFunc func, void *data);
Spacer *model_add_spacer (Model *model, Object *a, Object *b, double length);
Spring *model_add_spring (Model *model, Object *a, Object *b, double length);
+Stick *model_add_stick (Model *model, Object *a, Object *b, double length);
+String *model_add_string (Model *model, Object *a, Object *b, double length);
Anchor *model_add_anchor (Model *model, Object *object, double x, double y);
Polygon *model_add_polygon (Model *model, int enclosing, int num_points, ...);
Polygon *model_add_enclosing_rectangle (Model *model, double x0, double y0,
diff --git a/main.c b/main.c
index 5864191..f57adb0 100644
--- a/main.c
+++ b/main.c
@@ -81,27 +81,18 @@ static void
model_init_rope (Model *model)
{
const int num_objects = 20;
- const int num_sticks = num_objects - 1;
const int stick_length = 10;
+ Object *object, *prev;
int i;
- memset (model, 0, sizeof *model);
- 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_init (model);
model_init_constants (model);
model_init_polygons (model);
- for (i = 0; i < num_objects; i++) {
- object_init (&model->objects[i], 200, 40 + i * stick_length, 1);
-
- if (i + 1 < num_objects) {
- model->sticks[i].a = &model->objects[i];
- model->sticks[i].b = &model->objects[i + 1];
- model->sticks[i].length = stick_length;
- }
+ for (i = 0, prev = NULL; i < num_objects; i++, prev = object) {
+ object = model_add_object (model, 200, 40 + i * stick_length, 1, NULL);
+ if (prev != NULL)
+ model_add_stick (model, object, prev, stick_length);
}
}
@@ -117,7 +108,7 @@ model_init_curtain (Model *model)
double x, y;
int i, j, index, stick_index;
- memset (model, 0, sizeof *model);
+ model_init (model);
model->objects = g_new (Object, num_objects);
model->num_objects = num_objects;
model->sticks = g_new (Stick, num_sticks);
@@ -483,17 +474,12 @@ draw_polygons (cairo_t *cr, Model *model, Color *color)
}
static void
-draw_objects (cairo_t *cr, Model *model, Color *color)
+draw_object (Object *object, void *data)
{
- int i;
+ cairo_t *cr = data;
- cairo_set_source_rgba (cr, color->red, color->green, color->blue, 0.4);
- for (i = 0; i < model->num_objects; i++) {
- cairo_arc (cr, model->objects[i].position.x,
- model->objects[i].position.y,
- 3, 0, 2*M_PI);
- cairo_fill (cr);
- }
+ cairo_arc (cr, object->position.x, object->position.y, 3, 0, 2 * M_PI);
+ cairo_fill (cr);
}
static Color blue = { 0, 0, 1 };
@@ -506,6 +492,7 @@ struct _Closure {
GtkWidget *drawing_area;
GtkWidget *fps_label;
Model *model;
+ Anchor *mouse_anchor;
int frame_count;
int i;
struct timeval start;
@@ -527,7 +514,9 @@ draw_model (GtkWidget *widget, Model *model)
draw_springs (cr, model, &black);
draw_offsets (cr, model, &blue);
draw_offset_springs (cr, model, &blue);
- draw_objects (cr, model, &red);
+
+ cairo_set_source_rgba (cr, 1, 0, 0, 0.4);
+ model_for_each_object (model, draw_object, cr);
cairo_destroy (cr);
}
@@ -554,9 +543,9 @@ button_press_event (GtkWidget *widget,
if (event->button != 1)
return TRUE;
- closure->model->mouse_anchor.x = event->x;
- closure->model->mouse_anchor.y = event->y;
- closure->model->mouse_anchor.object =
+ closure->mouse_anchor->x = event->x;
+ closure->mouse_anchor->y = event->y;
+ closure->mouse_anchor->object =
model_find_nearest (closure->model, event->x, event->y);
return TRUE;
@@ -572,7 +561,7 @@ button_release_event (GtkWidget *widget,
if ((event->state & GDK_BUTTON1_MASK) == 0)
return TRUE;
- closure->model->mouse_anchor.object = NULL;
+ closure->mouse_anchor->object = NULL;
return TRUE;
}
@@ -587,9 +576,9 @@ motion_notify_event (GtkWidget *widget,
GdkModifierType state;
gdk_window_get_pointer (event->window, &x, &y, &state);
-
- closure->model->mouse_anchor.x = x + 0.5;
- closure->model->mouse_anchor.y = y + 0.5;
+
+ closure->mouse_anchor->x = x + 0.5;
+ closure->mouse_anchor->y = y + 0.5;
return TRUE;
}
@@ -800,11 +789,12 @@ main (int argc, char *argv[])
model_init_rope (&model);
create_window (&closure);
closure.i = 0;
- gtk_widget_show_all (gtk_widget_get_toplevel (closure.drawing_area));
closure.model = &model;
+ closure.mouse_anchor = model_add_anchor (&model, NULL, 0, 0);
closure.frame_count = 0;
gettimeofday (&closure.start, NULL);
g_timeout_add (40, timeout_callback, &closure);
+ gtk_widget_show_all (gtk_widget_get_toplevel (closure.drawing_area));
gtk_main ();
return 0;