summaryrefslogtreecommitdiff
path: root/testhull.cpp
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2025-02-07 00:34:44 +1100
committerquou <quou@disroot.org>2025-02-07 00:34:44 +1100
commit73d7f8325aeb00cbaec89a1c15602b9bd85ff04e (patch)
treefbef9f89fad53a86882aab0b17a2ff2d7290ad41 /testhull.cpp
parent5d09e4f0880b182a2f4c89508744c27823ed554e (diff)
collision yes/no
Diffstat (limited to 'testhull.cpp')
-rw-r--r--testhull.cpp152
1 files changed, 152 insertions, 0 deletions
diff --git a/testhull.cpp b/testhull.cpp
new file mode 100644
index 0000000..d02f17a
--- /dev/null
+++ b/testhull.cpp
@@ -0,0 +1,152 @@
+#include <SDL2/SDL.h>
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "maths.cpp"
+
+struct Shrinkwrap {
+ v2f* points;
+ int count;
+ v2f p0;
+ Shrinkwrap(v2f* src, int src_count):
+ count(0), p0(INFINITY, INFINITY) {
+ int i, top = 0;
+ int stack_size = src_count;
+ v2f* stack = (v2f*)malloc(stack_size * sizeof *stack);
+ points = (v2f*)malloc(src_count * sizeof *points);
+ auto push = [&](v2f p) {
+ assert(top < stack_size);
+ stack[top++] = p;
+ };
+ auto pop = [&]() {
+ assert(top > 0);
+ return stack[--top];
+ };
+ auto peek = [&](int i) {
+ assert(top - 1 - i >= 0);
+ return stack[top - 1 - i];
+ };
+ auto ccw = [](v2f a, v2f b, v2f c) {
+ float angle =
+ (b.y - a.y) * (c.x - b.x) -
+ (b.x - a.x) * (c.y - b.y);
+ return angle > -0.00001f;
+ };
+ for (i = 0; i < src_count; i++) {
+ v2f p = src[i];
+ if (p.y < p0.y || (fabsf(p.y - p0.y) < 0.0001f && p.x < p0.x))
+ p0 = p;
+ }
+ std::sort(
+ src,
+ src + src_count,
+ [this](const v2f& f, const v2f& s) {
+ float a =
+ (f.y - p0.y) * (s.x - f.x) -
+ (f.x - p0.x) * (s.y - f.y);
+ bool colinear = fabsf(a - 0.0f) < 0.001f;
+ if (colinear)
+ return v2f::mag(p0 - s) >= v2f::mag(p0 - f);
+ return a < 0.0f;
+ }
+ );
+ for (i = 0; i < src_count; i++) {
+ v2f p = src[i];
+ while (top > 1 && ccw(peek(1), peek(0), p))
+ pop();
+ push(p);
+ }
+ while (top)
+ points[count++] = pop();
+ free(stack);
+ }
+};
+
+int main(int argc, const char** argv) {
+ int r = 1;
+ float rot = 3.5f;
+ SDL_Window* window;
+ SDL_Renderer* ren;
+ SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
+ SDL_CreateWindowAndRenderer(
+ 800,
+ 800,
+ 0,
+ &window,
+ &ren
+ );
+ v2f points[] = {
+ { 129.0f, 148.0f },
+ { 178.0f, 178.0f },
+ { 146.0f, 146.0f },
+ { 163.0f, 172.0f },
+ { 129.0f, 159.0f },
+ { 102.0f, 151.0f },
+ { 167.0f, 122.0f }
+ };
+ float rots[] = {
+ 0.0f,
+ 1.0f,
+ 1.0f,
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ 0.0f,
+ };
+ constexpr int point_count = sizeof points / sizeof *points;
+ v2f points2[point_count];
+ while (r) {
+ int i;
+ SDL_Event e;
+ while (SDL_PollEvent(&e)) {
+ switch (e.type) {
+ case SDL_QUIT:
+ r = 0;
+ break;
+ }
+ }
+ for (i = 0; i < point_count; i++) {
+ v2f p = points[i];
+ points2[i] = v2f(
+ p.x * 2 + (sinf(rot * rots[i]) * p.x - cosf(rot * rots[i]) * p.y),
+ p.y * 2 + (sinf(rot * rots[i]) * p.x + cosf(rot * rots[i]) * p.y)
+ );
+ }
+ Shrinkwrap s(points2, point_count);
+ SDL_SetRenderDrawColor(ren, 0x00, 0x00, 0x00, 0x00);
+ SDL_RenderClear(ren);
+ for (int i = 0; i < s.count; i++) {
+ v2f a = s.points[i];
+ v2f b = s.points[(i + 1) % s.count];
+ v2f e = a - b;
+ v2f h = e * 0.5f;
+ v2f n = v2f(e.y, -e.x);
+ n = v2f::normalised(n);
+ SDL_SetRenderDrawColor(ren, 0x00, 0x00, 0xff, 0xff);
+ SDL_RenderDrawLine(ren, (int)a.x, (int)a.y, (int)b.x, (int)b.y);
+ SDL_SetRenderDrawColor(ren, 0xff, 0x00, 0xff, 0xff);
+ SDL_RenderDrawLine(
+ ren,
+ (int)(a.x - h.x),
+ (int)(a.y - h.y),
+ (int)((a.x - h.x) + n.x * 32.0f),
+ (int)((a.y - h.y) + n.y * 32.0f)
+ );
+ }
+ SDL_SetRenderDrawColor(ren, 0xff, 0x00, 0x00, 0xff);
+ for (i = 0; i < point_count; i++) {
+ v2f p = points2[i];
+ SDL_RenderDrawPoint(ren, (int)p.x, (int)p.y);
+ }
+ SDL_SetRenderDrawColor(ren, 0x00, 0xff, 0x00, 0xff);
+ SDL_RenderDrawPoint(ren, (int)s.p0.x, (int)s.p0.y);
+ SDL_RenderPresent(ren);
+ free(s.points);
+ rot += 0.0003f;
+ }
+ SDL_DestroyRenderer(ren);
+ SDL_DestroyWindow(window);
+ SDL_Quit();
+ return 0;
+}