From 73d7f8325aeb00cbaec89a1c15602b9bd85ff04e Mon Sep 17 00:00:00 2001 From: quou Date: Fri, 7 Feb 2025 00:34:44 +1100 Subject: collision yes/no --- testhull.cpp | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 testhull.cpp (limited to 'testhull.cpp') 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 + +#include +#include + +#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; +} -- cgit v1.2.3-54-g00ecf