Added bounds checking for triangles.

This commit is contained in:
2025-12-20 10:33:12 -05:00
parent cffc64f3e9
commit 3bf2a7b429
10 changed files with 126 additions and 116 deletions

124
src/gen.c
View File

@@ -1,122 +1,44 @@
#include "include/gen.h"
#include "include/geom.h"
#include <stdlib.h>
#include <time.h>
Vec2 asth[WORLD_SZ][WORLD_SZ] = {
{
(Vec2){.x = 1, .y = 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
},
{
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
},
{
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
},
{
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
},
{
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
},
{
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
},
{
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
},
{
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
(Vec2){1, 2},
},
};
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 < 8) {
if (0 <= idx && idx < WORLD_SZ) {
return (Pt){idx, 0};
} else if (8 <= idx && idx < 16) {
return (Pt){7, idx - 8};
} else if (16 <= idx && idx < 24) {
return (Pt){idx - 16, 0};
} else if (24 <= idx && idx < 32) {
return (Pt){7, idx - 24};
} 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};
}
}
}
void gen_lith() {
srand(time(NULL));
Tri tri1 = {
(Pt){0, 0},
(Pt){0, 7},
(Pt){7, 0},
};
Tri tri2 = {
(Pt){7, 0},
(Pt){0, 7},
(Pt){7, 7},
};
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){.tris = {tri1}};
lith[1] = (Plate){.tris = {tri2}};
lith[0] = (Plate){.col = BLUE, .ntris = 1, .tris = tri1};
lith[1] = (Plate){.col = GREEN, .ntris = 1, .tris = tri2};
}

26
src/geom.c Normal file
View File

@@ -0,0 +1,26 @@
#include "include/geom.h"
Tri* alltris[512];
size_t allsize = 0;
Tri* tri_init(Pt a, Pt b, Pt c) {
Tri* tri = malloc(sizeof(Tri));
*(alltris + allsize) = tri;
allsize++;
*tri = (Tri){a, b, c};
return tri;
}
bool tri_within(Pt pt, Tri* tri) {
double denom =
((tri->b.y - tri->c.y) * (tri->a.x - tri->c.x) +
(tri->c.x - tri->b.x) * (tri->a.y - tri->c.y));
double a = ((tri->b.y - tri->c.y) * (pt.x - tri->c.x) +
(tri->c.x - tri->b.x) * (pt.y - tri->c.y)) /
denom;
double b = ((tri->c.y - tri->a.y) * (pt.x - tri->c.x) +
(tri->a.x - tri->c.x) * (pt.y - tri->c.y)) /
denom;
double c = 1 - a - b;
return 0 <= a && a <= 1 && 0 <= b && b <= 1 && 0 <= c && c <= 1;
}

View File

@@ -5,7 +5,7 @@
#include <stdint.h>
#define WORLD_SZ 8
#define WORLD_SZ 12
#define NPLATES 2
// A two dimensional vector.
@@ -19,6 +19,7 @@ extern Vec2 asth[WORLD_SZ][WORLD_SZ];
// The lithosphere; contians a list of plates.
extern Plate lith[NPLATES];
void gen_asth(void);
void gen_lith(void);
#endif

View File

@@ -1,6 +1,10 @@
#ifndef GEOM_H
#define GEOM_H
#include <stdlib.h>
#include <stdbool.h>
#include <raylib.h>
// The maximum number of Tris in a Plate.
#define NTRI 4
@@ -19,8 +23,19 @@ typedef struct {
Pt c;
} Tri;
extern Tri* alltris[512];
extern size_t allsize;
Tri* tri_init(Pt a, Pt b, Pt c);
void tri_destroy(Tri* tri);
// Check if a point is within the triangle. Uses barycentric coordinate system.
bool tri_within(Pt pt, Tri* tri);
typedef struct {
Tri tris[NTRI];
Color col;
size_t ntris;
Tri* tris;
} Plate;
#endif

View File

@@ -3,8 +3,8 @@
#include "gen.h"
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 800
#define SCREEN_WIDTH (100 * WORLD_SZ)
#define SCREEN_HEIGHT (100 * WORLD_SZ)
#define CELL_SZ (SCREEN_WIDTH / WORLD_SZ)
void render(void);

8
src/include/tect.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef TECT_H
#define TECT_H
#include "gen.h"
Vec2* tect_asth_vals(Plate p);
#endif

9
src/include/util.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef UTIL_H
#define UTIL_H
#define MAX(a, b) a ? a > b : b
#define MAX3(a, b, c) MAX(a, MAX(b, c))
#define MIN(a, b) a ? a < b : b
#define MIN3(a, b, c) MIN(a, MIN(b, c))
#endif

View File

@@ -6,6 +6,7 @@
#include <raylib.h>
int main(int argc, char** argv) {
gen_asth();
gen_lith();
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Terrin");
SetTargetFPS(110);

View File

@@ -1,5 +1,7 @@
#include "include/render.h"
#include "include/gen.h"
#include "include/geom.h"
#include "include/util.h"
#include <raylib.h>
#include <stdio.h>
@@ -18,27 +20,44 @@ Vector2 PointpToVector2(Pt* p) {
return v;
}
void render() {
for (int i = 0; i < NPLATES; i++) {
Plate plate = lith[i];
void draw_tri(Tri* tri) {
DrawTriangleLines(
PointToVector2(plate.tris[0].a), PointToVector2(plate.tris[0].b),
PointToVector2(plate.tris[0].c), RED
);
printf(
">>>>>>>>>>>>>>>>>>%i %i\n", plate.tris[0].a.x, plate.tris[0].a.y
PointToVector2(tri->a), PointToVector2(tri->b), PointToVector2(tri->c),
RED
);
}
// bad.
void draw_tri_inside(Tri* tri, Color col) {
// int maxx = MAX3(tri->a.x, tri->b.x, tri->c.x);
// int maxy = MAX3(tri->a.y, tri->b.y, tri->c.y);
// int minx = MIN3(tri->a.y, tri->b.y, tri->c.y);
// int miny = MIN3(tri->a.y, tri->b.y, tri->c.y);
for (int x = 0; x <= WORLD_SZ; x++) {
for (int y = 0; y < WORLD_SZ; y++) {
if (tri_within((Pt){x, y}, tri)) {
DrawCircleV(PointToVector2((Pt){x, y}), 4.f, col);
}
}
}
}
void render() {
for (int x = 0; x < WORLD_SZ; x++) {
for (int y = 0; y < WORLD_SZ; y++) {
Vector2 v = PointToVector2((Pt){x, y});
DrawCircleV(v, 4.f, WHITE);
DrawLineV(
v, (Vector2){v.x + asth[x][y].x * 8, v.y + asth[x][y].y * 8},
v,
(Vector2){v.x + asth[x][y].x * WORLD_SZ,
v.y + asth[x][y].y * WORLD_SZ},
WHITE
);
}
}
for (int i = 0; i < NPLATES; i++) {
Plate plate = lith[i];
draw_tri(plate.tris);
draw_tri_inside(plate.tris, plate.col);
}
}

9
src/tect.c Normal file
View File

@@ -0,0 +1,9 @@
#include "include/tect.h"
#include "include/gen.h"
#include "include/geom.h"
Vec2* tect_asth_vals(Plate p) {
Vec2 buf[WORLD_SZ * WORLD_SZ];
for (int i = 0; i < p.ntris; i++) {}
return buf;
}