From d6fe969ce89becb1281b3fad4b9a879081a10a62 Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 3 Jan 2026 11:00:55 -0500 Subject: [PATCH] More things. So many things. --- src/gen.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++ src/geom.c | 63 +++++++++++++++++++++++++++++++++++ src/include/gen.h | 8 ++--- src/include/geom.h | 17 ++++++++-- src/main.c | 3 ++ src/render.c | 1 - src/tect.c | 2 +- 7 files changed, 168 insertions(+), 9 deletions(-) diff --git a/src/gen.c b/src/gen.c index 79d3576..9e4118d 100644 --- a/src/gen.c +++ b/src/gen.c @@ -1,6 +1,7 @@ #include "include/gen.h" #include "include/geom.h" +#include #include #include @@ -33,9 +34,91 @@ void gen_asth() { } } +size_t* min_idx(int* a, size_t n, size_t* out_n) { + if (!a || n == 0) return NULL; + + int min_val = a[0]; + for (size_t i = 1; i < n; i++) { + if (a[i] < min_val) min_val = a[i]; + } + + size_t o = 0; + for (size_t i = 0; i < n; i++) { + if (a[i] == min_val) o++; + } + + size_t* idxs = malloc(o * sizeof(size_t)); + if (!idxs) { + *out_n = 0; + return NULL; + } + + size_t k = 0; + for (size_t i = 0; i < n; i++) { + if (a[i] == min_val) idxs[k++] = i; + } + + *out_n = o; + return idxs; +} + void gen_lith() { srand(time(NULL)); + Pt centers[NPLATES]; // The centers of each plate to be generated. + + // Generate random plate centers. + for (int i = 0; i < NPLATES; i++) { + Pt p = (Pt){rand() % WORLD_SZ, rand() % WORLD_SZ}; + centers[i] = p; + } + + Pt* plareas[NPLATES]; + int plareas_count[NPLATES]; + + for (int i = 0; i < NPLATES; i++) { + plareas[i] = (Pt*)malloc( + WORLD_SZ * WORLD_SZ * sizeof(Pt) + ); // Points in the plate area. + plareas_count[i] = 0; // Number of points added to the plate area. + } + + for (int y = 0; y < WORLD_SZ; y++) { + for (int x = 0; x < WORLD_SZ; x++) { + Pt pt = (Pt){x, y}; + int distances[NPLATES]; // Distances from each plate to the current + // point. + for (int i = 0; i < NPLATES; i++) { + distances[i] = pt_cmp(&pt, ¢ers[i]); + } + + size_t n; + size_t* idxs = min_idx( + distances, NPLATES, &n + ); // The index(es) of the closest plate(s) in the centers array. + + for (int i = 0; i < n; i++) { + plareas[idxs[i]][plareas_count[idxs[i]]++] = pt; + } + } + } + + Pt* plhulls[NPLATES]; // The convex hulls of each plate. + size_t plhulls_count[NPLATES]; // The number of points in each hull. + + for (int i = 0; i < NPLATES; i++) { + size_t count; + plhulls[i] = cvx_hull(plareas[i], plareas_count[i], &count); + plhulls_count[i] = count; + } + + Plate pls[NPLATES]; + + for (int i = 0; i < NPLATES; i++) { + Tri* tris = malloc(plhulls_count[i] / 3 + 2); + tris[0] = (Tri){plhulls[i][0], plhulls[i][1], plhulls[i][2]}; + } + Tri* tri1 = tri_init((Pt){0, 0}, (Pt){0, 7}, (Pt){7, 0}); Tri* tri2 = tri_init((Pt){7, 0}, (Pt){0, 7}, (Pt){7, 7}); diff --git a/src/geom.c b/src/geom.c index c33004a..e362fa0 100644 --- a/src/geom.c +++ b/src/geom.c @@ -1,5 +1,8 @@ #include "include/geom.h" +#include +#include + Tri* alltris[512]; size_t allsize = 0; @@ -29,3 +32,63 @@ Pt tri_center(Tri* tri) { return (Pt){(tri->a.x + tri->b.x + tri->c.x) / 3.0, (tri->a.y + tri->b.y + tri->c.y) / 3.0}; } + +int pt_cmp(const void* a, const void* b) { + const Pt* p = (const Pt*)a; + const Pt* q = (const Pt*)b; + + if (p->x != q->x) return p->x - q->x; + return p->y - q->y; +} + +static int pt_cross(const Pt a, const Pt b, const Pt c) { + return ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)); +} + +Pt* cvx_hull(Pt* area, size_t n, size_t* out_n) { + if (!area || n <= 0) return NULL; + + if (n == 1) { + Pt* out = malloc(2 * sizeof(Pt)); + if (n == 1) out[0] = area[0]; + *out_n = 1; + printf("bad things are happening... %s\n", __FUNCTION__); + return out; + } + + Pt* pts = malloc(n * sizeof(Pt)); + for (size_t i = 0; i < n; i++) pts[i] = area[i]; + + // Sort the points. + qsort(pts, n, sizeof(Pt), pt_cmp); + + // Max hull size is 2 * n. + Pt* hull = malloc(2 * n * sizeof(Pt)); + size_t k = 0; + + // Lower hull. + for (size_t i = 0; i < n; i++) { + while (k >= 2 && pt_cross(hull[k - 2], hull[k - 1], pts[i]) <= 0) k--; + + hull[k++] = pts[i]; + } + + // Upper hull. + for (size_t i = n - 1, t = k + 1; i > 0; i--) { + while (k >= t && pt_cross(hull[k - 2], hull[k - 1], pts[i - 1]) <= 0) + k--; + + hull[k++] = pts[i - 1]; + } + + // Remove duplicated end/start point. + k--; + + Pt* out = malloc(k * sizeof(Pt)); + for (size_t i = 0; i < k; i++) { out[i] = hull[i]; } + + *out_n = k; + free(pts); + free(hull); + return out; +} diff --git a/src/include/gen.h b/src/include/gen.h index e118a11..14cb115 100644 --- a/src/include/gen.h +++ b/src/include/gen.h @@ -8,18 +8,16 @@ #define WORLD_SZ 12 #define NPLATES 2 -// A two dimensional vector. -typedef struct { - int x; - int y; -} Vec2; // The asthenosphere; contains a grid of force vectors. extern Vec2 asth[WORLD_SZ][WORLD_SZ]; // The lithosphere; contians a list of plates. extern Plate lith[NPLATES]; +// Generate the motion vectors of the asthenosphere. void gen_asth(void); + +// Generate the plates of the lithosphere. void gen_lith(void); #endif diff --git a/src/include/geom.h b/src/include/geom.h index 7abf65f..cf51849 100644 --- a/src/include/geom.h +++ b/src/include/geom.h @@ -1,13 +1,19 @@ #ifndef GEOM_H #define GEOM_H -#include -#include #include +#include +#include // The maximum number of Tris in a Plate. #define NTRI 4 +// A two dimensional vector. +typedef struct { + int x; + int y; +} Vec2; + typedef struct { int x, y; } Pt; @@ -35,6 +41,13 @@ bool tri_within(Pt pt, Tri* tri); // Get the center point of a Tri. Pt tri_center(Tri* tri); +// Compare two points. +int pt_cmp(const void* a, const void* b); + +// Get the convex hull around the area. Given the points in the area and their +// number. +Pt* cvx_hull(Pt* area, size_t n, size_t* out_n); + typedef struct { Color col; size_t ntris; diff --git a/src/main.c b/src/main.c index 7462e39..5d093a6 100644 --- a/src/main.c +++ b/src/main.c @@ -1,10 +1,13 @@ #include "include/main.h" #include "include/gen.h" +#include "include/geom.h" #include "include/render.h" #include +#include + int main(int argc, char** argv) { gen_asth(); gen_lith(); diff --git a/src/render.c b/src/render.c index ede028e..692c48d 100644 --- a/src/render.c +++ b/src/render.c @@ -4,7 +4,6 @@ #include "include/util.h" #include -#include Vector2 PointToVector2(Pt p) { Vector2 v; diff --git a/src/tect.c b/src/tect.c index ecef087..80a1bf0 100644 --- a/src/tect.c +++ b/src/tect.c @@ -3,7 +3,7 @@ #include "include/geom.h" Vec2* tect_asth_vals(Plate p) { - Vec2 buf[WORLD_SZ * WORLD_SZ]; + Vec2* buf = malloc(WORLD_SZ * WORLD_SZ); for (int i = 0; i < p.ntris; i++) {} return buf; }