summaryrefslogtreecommitdiff
path: root/experimental/tectonics/world.c
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2022-01-26 02:23:20 -0600
committersanine <sanine.not@pm.me>2022-01-26 02:23:20 -0600
commit672819693ddf1d203c304697b63f44059cff09b6 (patch)
tree258319d46efa5297162bc1179b5c9c34bd3c23c7 /experimental/tectonics/world.c
parentc5fae17327c585ec09ad01066e3f24a4e7be1fed (diff)
refactor: move quadtree and util functions into separate headers and clean up names
Diffstat (limited to 'experimental/tectonics/world.c')
-rw-r--r--experimental/tectonics/world.c68
1 files changed, 45 insertions, 23 deletions
diff --git a/experimental/tectonics/world.c b/experimental/tectonics/world.c
index a1dd4de..5aead24 100644
--- a/experimental/tectonics/world.c
+++ b/experimental/tectonics/world.c
@@ -2,19 +2,17 @@
#include <math.h>
#include "tectonics.h"
-
-struct centroid_t {
- double x, y;
- int updates;
-};
+#include "geometry.h"
+#include "util.h"
static void rebuild_tree(struct world_t *world)
{
+ // remove any existing tree
if (world->tree.nw != NULL) {
- free_tree(world->tree.nw);
- free_tree(world->tree.ne);
- free_tree(world->tree.sw);
- free_tree(world->tree.se);
+ quadtree_free(world->tree.nw);
+ quadtree_free(world->tree.ne);
+ quadtree_free(world->tree.sw);
+ quadtree_free(world->tree.se);
world->tree.nw = NULL;
world->tree.ne = NULL;
world->tree.sw = NULL;
@@ -22,16 +20,28 @@ static void rebuild_tree(struct world_t *world)
}
world->tree.id = -1;
+ // build a new tree
for (int i=0; i<world->n_points; i++) {
- insert(&(world->tree), world->points, i);
+ quadtree_insert(&(world->tree), world->points, i);
}
}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+struct centroid_t {
+ double x, y;
+ int updates;
+};
+
+// monte-carlo lloyd's algorithm
static void relax_points(struct world_t *world, int iterations)
{
+ // centroids to compute
struct centroid_t *centroid =
malloc(sizeof(struct centroid_t) * world->n_points);
-
+
+ // initialize centroids with current locations
for (int i=0; i<world->n_points; i++) {
struct point_t *pt = world->points + i;
struct centroid_t *c = centroid + i;
@@ -40,18 +50,22 @@ static void relax_points(struct world_t *world, int iterations)
c->updates = 1;
}
+ // approximate centroids
for (int i=0; i<iterations; i++) {
printf("%02f%%\n", 100*((double)i+1)/iterations);
+ // generate a random point and find the closest
+ // terrain point
double x = rand01();
double y = rand01();
- int closest = get_closest(&(world->tree),
- world->points,
- (struct point_t){x, y});
+ int closest = quadtree_get_closest(&(world->tree),
+ world->points,
+ (struct point_t){x, y});
if (closest == -1) {
printf("WARN: bad closest point!\n");
}
else {
+ // average the centroid towards that random point
struct centroid_t *c = centroid + closest;
int u = c->updates;
c->x = (u*c->x + x)/(u+1);
@@ -60,6 +74,7 @@ static void relax_points(struct world_t *world, int iterations)
}
}
+ // update positions from centroids
for (int i=0; i<world->n_points; i++) {
struct point_t *pt = world->points + i;
struct centroid_t *c = centroid + i;
@@ -72,6 +87,9 @@ static void relax_points(struct world_t *world, int iterations)
free(centroid);
}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
void create_world(struct world_t *world, int n_points)
{
world->n_points = n_points;
@@ -84,35 +102,39 @@ void create_world(struct world_t *world, int n_points)
}
struct point_t center = { 0.5, 0.5 };
- world->tree = new_node(center, 0.5);
+ world->tree = quadtree_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);
+ //quadtree_insert(&(world->tree), world->points, i);
}
rebuild_tree(world);
- for (int i=0; i<10; i++)
- relax_points(world, 100000);
+ for (int i=0; i<3; i++)
+ relax_points(world, 10*world->n_points);
}
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
void free_world(struct world_t *world)
{
if (world->tree.nw != NULL) {
- free_tree(world->tree.nw);
- free_tree(world->tree.ne);
- free_tree(world->tree.sw);
- free_tree(world->tree.se);
+ quadtree_free(world->tree.nw);
+ quadtree_free(world->tree.ne);
+ quadtree_free(world->tree.sw);
+ quadtree_free(world->tree.se);
}
free(world->points);
}
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
void render_world(cairo_t *cr, struct world_t *world)
{
int width, height;
@@ -128,5 +150,5 @@ void render_world(cairo_t *cr, struct world_t *world)
cairo_stroke(cr);
}
- draw_quadtree(cr, &(world->tree));
+ //draw_quadtree(cr, &(world->tree));
}