#include "include/geom.h" #include #include 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; } 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; }