deleted as no longer used modified accordingly
2008-02-27 Jim Huang <jserv.tw@gmail.com> * src/core/spring-model.[ch]: deleted as no longer used * src/Makefile.am: modified accordingly svn path=/trunk/; revision=3607
This commit is contained in:
parent
85631aec0f
commit
f8a5ef7c9f
@ -1,3 +1,7 @@
|
|||||||
|
2008-02-27 Jim Huang <jserv.tw@gmail.com>
|
||||||
|
|
||||||
|
* src/core/spring-model.[ch]: deleted as no longer used
|
||||||
|
* src/Makefile.am: modified accordingly
|
||||||
2008-02-27 Thomas Thurman <tthurman@gnome.org>
|
2008-02-27 Thomas Thurman <tthurman@gnome.org>
|
||||||
|
|
||||||
Lots of tiny fixes to make sure we compile with
|
Lots of tiny fixes to make sure we compile with
|
||||||
|
@ -53,8 +53,6 @@ metacity_SOURCES= \
|
|||||||
core/screen.h \
|
core/screen.h \
|
||||||
core/session.c \
|
core/session.c \
|
||||||
core/session.h \
|
core/session.h \
|
||||||
core/spring-model.c \
|
|
||||||
core/spring-model.h \
|
|
||||||
core/stack.c \
|
core/stack.c \
|
||||||
core/stack.h \
|
core/stack.h \
|
||||||
core/util.c \
|
core/util.c \
|
||||||
|
@ -1,418 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
#include "spring-model.h"
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
struct XYPair
|
|
||||||
{
|
|
||||||
double x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define GRID_WIDTH 4
|
|
||||||
#define GRID_HEIGHT 4
|
|
||||||
|
|
||||||
#define MODEL_MAX_OBJECTS (GRID_WIDTH * GRID_HEIGHT)
|
|
||||||
#define MODEL_MAX_SPRINGS (MODEL_MAX_OBJECTS * 2)
|
|
||||||
|
|
||||||
#define DEFAULT_SPRING_K 5.0
|
|
||||||
#define DEFAULT_FRICTION 1.4
|
|
||||||
|
|
||||||
struct Spring {
|
|
||||||
Object *a;
|
|
||||||
Object *b;
|
|
||||||
/* Spring position at rest, from a to b:
|
|
||||||
offset = b.position - a.position
|
|
||||||
*/
|
|
||||||
Vector offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Object {
|
|
||||||
Vector force;
|
|
||||||
|
|
||||||
Point position;
|
|
||||||
Vector velocity;
|
|
||||||
|
|
||||||
double mass;
|
|
||||||
double theta;
|
|
||||||
|
|
||||||
int immobile;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Model {
|
|
||||||
int num_objects;
|
|
||||||
Object objects[MODEL_MAX_OBJECTS];
|
|
||||||
|
|
||||||
int num_springs;
|
|
||||||
Spring springs[MODEL_MAX_SPRINGS];
|
|
||||||
|
|
||||||
Object *anchor_object;
|
|
||||||
Vector anchor_offset;
|
|
||||||
|
|
||||||
double friction;/* Friction constant */
|
|
||||||
double k;/* Spring constant */
|
|
||||||
|
|
||||||
double last_time;
|
|
||||||
double steps;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
object_init (Object *object,
|
|
||||||
double position_x, double position_y,
|
|
||||||
double velocity_x, double velocity_y, double mass)
|
|
||||||
{
|
|
||||||
object->position.x = position_x;
|
|
||||||
object->position.y = position_y;
|
|
||||||
|
|
||||||
object->velocity.x = velocity_x;
|
|
||||||
object->velocity.y = velocity_y;
|
|
||||||
|
|
||||||
object->mass = mass;
|
|
||||||
|
|
||||||
object->force.x = 0;
|
|
||||||
object->force.y = 0;
|
|
||||||
|
|
||||||
object->immobile = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
spring_init (Spring *spring,
|
|
||||||
Object *object_a, Object *object_b,
|
|
||||||
double offset_x, double offset_y)
|
|
||||||
{
|
|
||||||
spring->a = object_a;
|
|
||||||
spring->b = object_b;
|
|
||||||
spring->offset.x = offset_x;
|
|
||||||
spring->offset.y = offset_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
model_add_spring (Model *model,
|
|
||||||
Object *object_a, Object *object_b,
|
|
||||||
double offset_x, double offset_y)
|
|
||||||
{
|
|
||||||
Spring *spring;
|
|
||||||
|
|
||||||
g_assert (model->num_springs < MODEL_MAX_SPRINGS);
|
|
||||||
|
|
||||||
spring = &model->springs[model->num_springs];
|
|
||||||
model->num_springs++;
|
|
||||||
|
|
||||||
spring_init (spring, object_a, object_b, offset_x, offset_y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
object_apply_force (Object *object, double fx, double fy)
|
|
||||||
{
|
|
||||||
object->force.x += fx;
|
|
||||||
object->force.y += fy;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The model here can be understood as a rigid body of the spring's
|
|
||||||
* rest shape, centered on the vector between the two object
|
|
||||||
* positions. This rigid body is then connected by linear-force
|
|
||||||
* springs to each object. This model does degnerate into a simple
|
|
||||||
* spring for linear displacements, and does something reasonable for
|
|
||||||
* rotation.
|
|
||||||
*
|
|
||||||
* There are other possibilities for handling the rotation of the
|
|
||||||
* spring, and it might be interesting to explore something which has
|
|
||||||
* better length-preserving properties. For example, with the current
|
|
||||||
* model, an initial 180 degree rotation of the spring results in the
|
|
||||||
* spring collapsing down to 0 size before expanding back to it's
|
|
||||||
* natural size again.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
spring_exert_forces (Spring *spring, double k)
|
|
||||||
{
|
|
||||||
Vector da, db;
|
|
||||||
Vector a, b;
|
|
||||||
|
|
||||||
a = spring->a->position;
|
|
||||||
b = spring->b->position;
|
|
||||||
|
|
||||||
/* A nice vector diagram would likely help here, but my ASCII-art
|
|
||||||
* skills aren't up to the task. Here's how to make your own
|
|
||||||
* diagram:
|
|
||||||
*
|
|
||||||
* Draw a and b, and the vector AB from a to b
|
|
||||||
* Find the center of AB
|
|
||||||
* Draw spring->offset so that its center point is on the center of AB
|
|
||||||
* Draw da from a to the initial point of spring->offset
|
|
||||||
* Draw db from b to the final point of spring->offset
|
|
||||||
*
|
|
||||||
* The math below should be easy to verify from the diagram.
|
|
||||||
*/
|
|
||||||
|
|
||||||
da.x = 0.5 * (b.x - a.x - spring->offset.x);
|
|
||||||
da.y = 0.5 * (b.y - a.y - spring->offset.y);
|
|
||||||
|
|
||||||
db.x = 0.5 * (a.x - b.x + spring->offset.x);
|
|
||||||
db.y = 0.5 * (a.y - b.y + spring->offset.y);
|
|
||||||
|
|
||||||
object_apply_force (spring->a, k * da.x, k * da.y);
|
|
||||||
object_apply_force (spring->b, k * db.x, k * db.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
model_step_object (Model *model, Object *object)
|
|
||||||
{
|
|
||||||
Vector acceleration;
|
|
||||||
|
|
||||||
object->theta += 0.05;
|
|
||||||
|
|
||||||
/* Slow down due to friction. */
|
|
||||||
object->force.x -= model->friction * object->velocity.x;
|
|
||||||
object->force.y -= model->friction * object->velocity.y;
|
|
||||||
|
|
||||||
acceleration.x = object->force.x / object->mass;
|
|
||||||
acceleration.y = object->force.y / object->mass;
|
|
||||||
|
|
||||||
if (object->immobile)
|
|
||||||
{
|
|
||||||
object->velocity.x = 0;
|
|
||||||
object->velocity.y = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
object->velocity.x += acceleration.x;
|
|
||||||
object->velocity.y += acceleration.y;
|
|
||||||
|
|
||||||
object->position.x += object->velocity.x;
|
|
||||||
object->position.y += object->velocity.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
object->force.x = 0.0;
|
|
||||||
object->force.y = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
model_init_grid (Model *model, MetaRectangle *rect, gboolean expand)
|
|
||||||
{
|
|
||||||
int x, y, i, v_x, v_y;
|
|
||||||
int hpad, vpad;
|
|
||||||
|
|
||||||
model->num_objects = MODEL_MAX_OBJECTS;
|
|
||||||
|
|
||||||
model->num_springs = 0;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
if (expand)
|
|
||||||
{
|
|
||||||
hpad = rect->width / 3;
|
|
||||||
vpad = rect->height / 3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hpad = rect->width / 6;
|
|
||||||
vpad = rect->height / 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define EXPAND_DELTA 4
|
|
||||||
|
|
||||||
for (y = 0; y < GRID_HEIGHT; y++)
|
|
||||||
for (x = 0; x < GRID_WIDTH; x++)
|
|
||||||
{
|
|
||||||
if (expand)
|
|
||||||
{
|
|
||||||
if (y == 0)
|
|
||||||
v_y = - EXPAND_DELTA * g_random_double();
|
|
||||||
else if (y == GRID_HEIGHT - 1)
|
|
||||||
v_y = EXPAND_DELTA * g_random_double();
|
|
||||||
else
|
|
||||||
v_y = 2 * EXPAND_DELTA * g_random_double() - EXPAND_DELTA;
|
|
||||||
|
|
||||||
if (x == 0)
|
|
||||||
v_x = - EXPAND_DELTA * g_random_double();
|
|
||||||
else if (x == GRID_WIDTH - 1)
|
|
||||||
v_x = EXPAND_DELTA * g_random_double();
|
|
||||||
else
|
|
||||||
v_x = 2 * EXPAND_DELTA * g_random_double() - EXPAND_DELTA;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
v_x = v_y = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (expand)
|
|
||||||
object_init (&model->objects[i],
|
|
||||||
rect->x + x * rect->width / 6 + rect->width / 4,
|
|
||||||
rect->y + y * rect->height / 6 + rect->height / 4,
|
|
||||||
v_x, v_y, 20);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
g_print ("obj: %d %d\n", rect->x + x * rect->width / 3,
|
|
||||||
rect->y + y * rect->height / 3);
|
|
||||||
#endif
|
|
||||||
object_init (&model->objects[i],
|
|
||||||
rect->x + x * rect->width / 3,
|
|
||||||
rect->y + y * rect->height / 3,
|
|
||||||
v_x, v_y, 15);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x > 0)
|
|
||||||
model_add_spring (model,
|
|
||||||
&model->objects[i - 1],
|
|
||||||
&model->objects[i],
|
|
||||||
hpad, 0);
|
|
||||||
|
|
||||||
if (y > 0)
|
|
||||||
model_add_spring (model,
|
|
||||||
&model->objects[i - GRID_WIDTH],
|
|
||||||
&model->objects[i],
|
|
||||||
0, vpad);
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
model_init (Model *model, MetaRectangle *rect, gboolean expand)
|
|
||||||
{
|
|
||||||
model->anchor_object = NULL;
|
|
||||||
|
|
||||||
model->k = DEFAULT_SPRING_K;
|
|
||||||
model->friction = DEFAULT_FRICTION;
|
|
||||||
|
|
||||||
model_init_grid (model, rect, expand);
|
|
||||||
model->steps = 0;
|
|
||||||
model->last_time = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Model *
|
|
||||||
model_new (MetaRectangle *rect, gboolean expand)
|
|
||||||
{
|
|
||||||
Model *model = g_new0 (Model, 1);
|
|
||||||
|
|
||||||
model_init (model, rect, expand);
|
|
||||||
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
static double
|
|
||||||
object_distance (Object *object, double x, double y)
|
|
||||||
{
|
|
||||||
double dx, dy;
|
|
||||||
|
|
||||||
dx = object->position.x - x;
|
|
||||||
dy = object->position.y - y;
|
|
||||||
|
|
||||||
return sqrt (dx*dx + dy*dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Object *
|
|
||||||
model_find_nearest (Model *model, double x, double y)
|
|
||||||
{
|
|
||||||
Object *object = &model->objects[0];
|
|
||||||
double distance, min_distance = 0.0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
model_begin_move (Model *model, int x, int y)
|
|
||||||
{
|
|
||||||
if (model->anchor_object)
|
|
||||||
model->anchor_object->immobile = 0;
|
|
||||||
|
|
||||||
model->anchor_object = model_find_nearest (model, x, y);
|
|
||||||
|
|
||||||
model->anchor_offset.x = x - model->anchor_object->position.x;
|
|
||||||
model->anchor_offset.y = y - model->anchor_object->position.y;
|
|
||||||
|
|
||||||
g_print ("ypos: %f %f\n", model->anchor_object->position.y,
|
|
||||||
model->anchor_object->position.x);
|
|
||||||
|
|
||||||
g_print ("anchor offset: %f %f\n",
|
|
||||||
model->anchor_offset.x,
|
|
||||||
model->anchor_offset.y);
|
|
||||||
|
|
||||||
model->anchor_object->immobile = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
model_set_anchor (Model *model,
|
|
||||||
int x,
|
|
||||||
int y)
|
|
||||||
{
|
|
||||||
if (model->anchor_object)
|
|
||||||
model->anchor_object->immobile = 0;
|
|
||||||
|
|
||||||
model->anchor_object = model_find_nearest (model, x, y);
|
|
||||||
model->anchor_offset.x = model->anchor_object->position.x - x;
|
|
||||||
model->anchor_offset.y = model->anchor_object->position.y - y;
|
|
||||||
|
|
||||||
model->anchor_object->immobile = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
model_update_move (Model *model, int x, int y)
|
|
||||||
{
|
|
||||||
model->anchor_object->position.x = x - model->anchor_offset.x;
|
|
||||||
model->anchor_object->position.y = y - model->anchor_offset.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define EPSILON 0.02
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
model_is_calm (Model *model)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < model->num_objects; i++)
|
|
||||||
{
|
|
||||||
if (model->objects[i].velocity.x > EPSILON ||
|
|
||||||
model->objects[i].velocity.y > EPSILON ||
|
|
||||||
model->objects[i].velocity.x < - EPSILON ||
|
|
||||||
model->objects[i].velocity.y < - EPSILON)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
model_step (Model *model)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < model->num_springs; i++)
|
|
||||||
spring_exert_forces (&model->springs[i], model->k);
|
|
||||||
|
|
||||||
for (i = 0; i < model->num_objects; i++)
|
|
||||||
model_step_object (model, &model->objects[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
model_destroy (Model *model)
|
|
||||||
{
|
|
||||||
g_free (model);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
model_get_position (Model *model,
|
|
||||||
int i,
|
|
||||||
int j,
|
|
||||||
double *x,
|
|
||||||
double *y)
|
|
||||||
{
|
|
||||||
if (x)
|
|
||||||
*x = model->objects[j * 4 + i].position.x;
|
|
||||||
|
|
||||||
if (y)
|
|
||||||
*y = model->objects[j * 4 + i].position.y;
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
||||||
|
|
||||||
#include "window.h"
|
|
||||||
|
|
||||||
typedef struct XYPair Point;
|
|
||||||
typedef struct XYPair Vector;
|
|
||||||
typedef struct Spring Spring;
|
|
||||||
typedef struct Object Object;
|
|
||||||
typedef struct Model Model;
|
|
||||||
|
|
||||||
Model *model_new (MetaRectangle *rectangle,
|
|
||||||
gboolean expand);
|
|
||||||
void model_destroy (Model *model);
|
|
||||||
void
|
|
||||||
model_get_position (Model *model,
|
|
||||||
int i,
|
|
||||||
int j,
|
|
||||||
double *x,
|
|
||||||
double *y);
|
|
||||||
void
|
|
||||||
model_step (Model *model);
|
|
||||||
void
|
|
||||||
model_destroy (Model *model);
|
|
||||||
gboolean
|
|
||||||
model_is_calm (Model *model);
|
|
||||||
void
|
|
||||||
model_set_anchor (Model *model,
|
|
||||||
int x,
|
|
||||||
int y);
|
|
||||||
void
|
|
||||||
model_begin_move (Model *model, int x, int y);
|
|
||||||
void
|
|
||||||
model_update_move (Model *model, int x, int y);
|
|
Loading…
Reference in New Issue
Block a user