More things. So many things.
This commit is contained in:
63
src/geom.c
63
src/geom.c
@@ -1,5 +1,8 @@
|
||||
#include "include/geom.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user