128 lines
3.4 KiB
C
128 lines
3.4 KiB
C
#include "include/gen.h"
|
|
#include "include/geom.h"
|
|
|
|
#include <stddef.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
|
|
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};
|
|
}
|