]> git.cworth.org Git - akamaru/blobdiff - akamaru.c
Improve initial icon placement.
[akamaru] / akamaru.c
index 8a9e587b40e66da2259011549be4fd2e97820e14..c667c371fade45e09ca49cdd274e177723dc9e1d 100644 (file)
--- a/akamaru.c
+++ b/akamaru.c
  *   corrections at the end instead of meaning as it goes.
  */
 
-#include <gtk/gtk.h>
-#include <cairo.h>
-#include <cairo-xlib.h>
-#include <gdk/gdkx.h>
+#include <glib.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/time.h>
+#include <stdarg.h>
 #include <math.h>
 
 #include "akamaru.h"
 
 const double elasticity = 0.7;
-const double friction = 1;
-const double gravity = 20;
+const double friction = 4;
+const double gravity = 50;
 
 void
-polygon_init (Polygon *p, int num_points, ...)
+object_init (Object *object, double x, double y, double mass)
+{
+  object->position.x = x;
+  object->position.y = y;
+  object->previous_position.x = x;
+  object->previous_position.y = y;
+  object->mass = mass;
+}
+
+void
+spring_init (Spring *spring, Object *a, Object *b, double length)
+{
+  spring->a = a;
+  spring->b = b;
+  spring->length = length;
+}
+
+void
+stick_init (Stick *stick, Object *a, Object *b, double length)
+{
+  stick->a = a;
+  stick->b = b;
+  stick->length = length;
+}
+
+void
+string_init (String *string, Object *a, Object *b, double length)
+{
+  string->a = a;
+  string->b = b;
+  string->length = length;
+}
+
+void
+offset_spring_init (OffsetSpring *spring, Object *a, Object *b,
+                   double dx, double dy)
+{
+  spring->a = a;
+  spring->b = b;
+  spring->dx = dx;
+  spring->dy = dy;
+}
+
+void
+spacer_init (Spacer *spacer, Object *a, Object *b, double length)
+{
+  spacer->a = a;
+  spacer->b = b;
+  spacer->length = length;
+}
+
+void
+anchor_init (Anchor *anchor, Object *object, double x, double y)
+{
+  anchor->object = object;
+  anchor->x = x;
+  anchor->y = y;
+}
+
+void
+polygon_init (Polygon *p, int enclosing, int num_points, ...)
 {
   double dx, dy, length;
   int i, j;
@@ -40,6 +97,7 @@ polygon_init (Polygon *p, int num_points, ...)
   va_start (ap, num_points);
   p->num_points = num_points;
   p->points = g_new (Point, num_points);
+  p->enclosing = enclosing;
 
   for (i = 0; i < num_points; i++) {
     p->points[i].x = va_arg (ap, double);
@@ -50,7 +108,7 @@ polygon_init (Polygon *p, int num_points, ...)
   p->normals = g_new (Vector, p->num_points);
   /* Compute outward pointing normals.  p->normals[i] is the normal
    * for the edged between p->points[i] and p->points[i + 1]. */
- for (i = 0; i < p->num_points; i++) {
 for (i = 0; i < p->num_points; i++) {
     j = (i + 1) % p->num_points;
     dx = p->points[j].x - p->points[i].x;
     dy = p->points[j].y - p->points[i].y;
@@ -63,7 +121,7 @@ polygon_init (Polygon *p, int num_points, ...)
 void
 polygon_init_diamond (Polygon *polygon, double x, double y)
 {
-  return polygon_init (polygon, 5, 
+  return polygon_init (polygon, FALSE, 5, 
                       x, y, 
                       x + 10, y + 40,
                       x + 90, y + 40,
@@ -75,7 +133,14 @@ void
 polygon_init_rectangle (Polygon *polygon, double x0, double y0,
                        double x1, double y1)
 {
-  return polygon_init (polygon, 4, x0, y0, x0, y1, x1, y1, x1, y0);
+  return polygon_init (polygon, FALSE, 4, x0, y0, x0, y1, x1, y1, x1, y0);
+}
+
+void
+polygon_init_enclosing_rectangle (Polygon *polygon, double x0, double y0,
+                               double x1, double y1)
+{
+  return polygon_init (polygon, TRUE, 4, x0, y0, x0, y1, x1, y1, x1, y0);
 }
 
 void
@@ -90,6 +155,7 @@ model_fini (Model *model)
     g_free (model->offsets[i].objects);
   g_free (model->springs);
   g_free (model->offset_springs);
+  g_free (model->spacers);
   for (i = 0; i < model->num_polygons; i++)
     g_free (model->polygons[i].points);
   g_free (model->polygons);
@@ -157,7 +223,7 @@ model_accumulate_forces (Model *model)
       model->objects[i].force.x * model->objects[i].force.x +
       model->objects[i].force.y * model->objects[i].force.y;
 
-    if (f > 1000000)
+    if (f > 100000000)
       abort();
   }
 }
@@ -218,10 +284,10 @@ polygon_contains_point (Polygon *polygon, Point *point)
     dy = point->y - polygon->points[i].y;
 
     if (polygon->normals[i].x * dx + polygon->normals[i].y * dy >= 0)
-      return FALSE;
+      return polygon->enclosing;
   }
 
-  return TRUE;
+  return !polygon->enclosing;
 }
 
 static void
@@ -239,7 +305,6 @@ polygon_reflect_object (Polygon *polygon, Object *object)
     if (d > distance) {
       distance = d;
       edge = i;
-      polygon->edge = i;
       n = &polygon->normals[i];
     }
   }
@@ -266,6 +331,15 @@ model_constrain_polygon (Model *model, Polygon *polygon)
   }
 }
 
+static void
+model_constrain_anchor (Model *model, Anchor *anchor)
+{
+  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)
 {
@@ -294,13 +368,10 @@ model_constrain (Model *model)
   double dx, dy, x, y, distance, fraction;
   int i;
 
-  /* Anchor object constraint. */
-  if (model->anchor_object != NULL) {
-    model->anchor_object->position.x = model->anchor_position.x;
-    model->anchor_object->position.y = model->anchor_position.y;
-    model->anchor_object->previous_position.x = model->anchor_position.x;
-    model->anchor_object->previous_position.y = model->anchor_position.y;
-  }
+  if (model->mouse_anchor.object != NULL)
+    model_constrain_anchor (model, &model->mouse_anchor);
+  for (i = 0; i < model->num_anchors; i++)
+    model_constrain_anchor (model, &model->anchors[i]);
 
   /* String constraints. */
   for (i = 0; i < model->num_strings; i++) {
@@ -318,6 +389,22 @@ model_constrain (Model *model)
     model->strings[i].b->position.y = y + dy * (1 - fraction);
   }
 
+  /* Spacer constraints. */
+  for (i = 0; i < model->num_spacers; i++) {
+    x = model->spacers[i].a->position.x;
+    y = model->spacers[i].a->position.y;
+    dx = model->spacers[i].b->position.x - x;
+    dy = model->spacers[i].b->position.y - y;
+    distance = estimate_distance (dx, dy, model->spacers[i].length);
+    if (distance > model->spacers[i].length)
+      continue;
+    fraction = (distance - model->spacers[i].length) / distance / 2;
+    model->spacers[i].a->position.x = x + dx * fraction;
+    model->spacers[i].a->position.y = y + dy * fraction;
+    model->spacers[i].b->position.x = x + dx * (1 - fraction);
+    model->spacers[i].b->position.y = y + dy * (1 - fraction);
+  }
+
   /* Stick constraints. */
   for (i = 0; i < model->num_sticks; i++) {
     x = model->sticks[i].a->position.x;
@@ -348,7 +435,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 < 20; i++)
     model_constrain (model);
 
   model->theta += delta_t;