diff options
Diffstat (limited to 'experimental/tectonics/world.c')
-rw-r--r-- | experimental/tectonics/world.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/experimental/tectonics/world.c b/experimental/tectonics/world.c new file mode 100644 index 0000000..cfc5d14 --- /dev/null +++ b/experimental/tectonics/world.c @@ -0,0 +1,105 @@ +#include <stdio.h> +#include <math.h> + +#include "tectonics.h" + +struct centroid_t { + double x, y; + int updates; +}; + +static int closest_point(struct world_t *world, double x, double y) +{ + double dist = 1e9; + int closest = -1; + for (int i=0; i<world->n_points; i++) { + struct point_t *pt = world->points + i; + double d = distance(x, y, pt->x, pt->y); + if (d <= dist) { + dist = d; + closest = i; + } + } + return closest; +} + +static void relax_points(struct world_t *world, int iterations) +{ + struct centroid_t *centroid = + malloc(sizeof(struct centroid_t) * world->n_points); + + for (int i=0; i<world->n_points; i++) { + struct point_t *pt = world->points + i; + struct centroid_t *c = centroid + i; + c->x = pt->x; + c->y = pt->y; + c->updates = 1; + } + + for (int i=0; i<iterations; i++) { + printf("%02f%%\n", 100*((double)i+1)/iterations); + double x = rand01(); + double y = rand01(); + int closest = closest_point(world, x, y); + + int t = centroid[closest].updates; + centroid[closest].x = (t*centroid[closest].x + x)/(t+1); + centroid[closest].y = (t*centroid[closest].y + y)/(t+1); + centroid[closest].updates += 1; + } + + for (int i=0; i<world->n_points; i++) { + struct point_t *pt = world->points + i; + struct centroid_t *c = centroid + i; + pt->x = c->x; + pt->y = c->y; + } +} + +void create_world(struct world_t *world, int n_points) +{ + world->n_points = n_points; + world->points = malloc(sizeof(struct point_t) * n_points); + if (world->points == NULL) { + fprintf(stderr, + "ERROR: failed to allocate %d points\n", + n_points); + return; + } + + struct point_t center = { 0.5, 0.5 }; + world->tree = new_node(center, 0.5); + + for (int i=0; i<n_points; i++) { + struct point_t *pt = world->points + i; + pt->x = rand01(); + pt->y = rand01(); + + insert(&(world->tree), world->points, i); + } +} + + +void free_world(struct world_t *world) +{ + free(world->points); +} + + +void render_world(cairo_t *cr, struct world_t *world) +{ + int width, height; + get_cairo_size(cr, &width, &height); + double r = ((double)width) / (100*sqrt(world->n_points)); + cairo_set_source_rgba(cr, 1, 0, 0, 1); + + for (int i=0; i<world->n_points; i++) { + struct point_t *pt = world->points + i; + double xc = pt->x * width; + double yc = pt->y * height; + cairo_arc(cr, xc, yc, r, 0, 2*M_PI); + cairo_stroke(cr); + } + + draw_quadtree(cr, &(world->tree)); +} |