#include "include/gen.h" #include "include/geom.h" #include #include #include Vec2 asth[WORLD_SZ][WORLD_SZ]; Plate lith[NPLATES]; // Find the point for an index to the edge of the world. Pt world_edge_idx_to_pt(int idx) { if (0 <= idx && idx < WORLD_SZ) { return (Pt){idx, 0}; } else if (WORLD_SZ <= idx && idx < 2 * WORLD_SZ) { return (Pt){WORLD_SZ - 1, idx - WORLD_SZ}; } else if (2 * WORLD_SZ <= idx && idx < 3 * WORLD_SZ) { return (Pt){idx - 2 * WORLD_SZ, 0}; } else if (3 * WORLD_SZ <= idx && idx < 4 * WORLD_SZ) { return (Pt){WORLD_SZ - 1, idx - 3 * WORLD_SZ}; } else { exit(122); } } void gen_asth() { srand(time(NULL)); for (int i = 0; i < WORLD_SZ; i++) { for (int j = 0; j < WORLD_SZ; j++) { asth[i][j] = (Vec2){rand() % 7 - 3, rand() % 7 - 3}; } } } 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}); lith[0] = (Plate){.col = BLUE, .ntris = 1, .tris = tri1}; lith[1] = (Plate){.col = GREEN, .ntris = 1, .tris = tri2}; }