diff options
Diffstat (limited to 'testsat.cpp')
-rw-r--r-- | testsat.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/testsat.cpp b/testsat.cpp new file mode 100644 index 0000000..45f3891 --- /dev/null +++ b/testsat.cpp @@ -0,0 +1,155 @@ +#include <SDL2/SDL.h> + +#include <assert.h> +#include <stdlib.h> + +#include "maths.cpp" + +struct Shape { + v2f* points; + int count; + + Shape(std::initializer_list<v2f> in) { + int i; + points = (v2f*)malloc(in.size() * sizeof *points); + count = in.size(); + for (i = 0; i < count; i++) + points[i] = *(in.begin() + i); + } + + Shape(const Shape& other) { + int s = other.count * sizeof *points; + count = other.count; + points = (v2f*)malloc(s); + memcpy(points, other.points, s); + } + + ~Shape() { + free(points); + } + + void render(SDL_Renderer* ren) { + int i, c = count; + for (i = 0; i < c; i++) { + v2f a = points[i]; + v2f b = points[(i + 1) % c]; + SDL_RenderDrawLine( + ren, + (int)a.x, + (int)a.y, + (int)b.x, + (int)b.y + ); + } + } + + std::pair<v2f*, int> normals() const { + int c = (count >> 1) + 1, i; + v2f* normals = (v2f*)malloc(c * sizeof *normals); + for (i = 0; i < count; i++) { + v2f a = points[i]; + v2f b = points[(i + 1) % count]; + v2f e = a - b; + v2f n = v2f::normalised(v2f(e.y, -e.x)); + normals[i] = n; + } + return { normals, i }; + } +}; + +bool intersect(Shape& a, Shape& b) { + bool r = true; + int i; + auto[fn, fnc] = a.normals(); + auto[sn, snc] = b.normals(); + auto project = [](const Shape& shape, v2f axis) { + int i; + float mini = INFINITY; + float maxi = -INFINITY; + for (i = 0; i < shape.count; i++) { + v2f p = shape.points[i]; + float d = v2f::dot(p, axis); + if (d < mini) mini = d; + if (d > maxi) maxi = d; + } + return std::pair<float, float>{ mini, maxi }; + }; + for (i = 0; i < fnc; i++) { + v2f axis = fn[i]; + auto [fp1, fp2] = project(a, axis); + auto [sp1, sp2] = project(b, axis); + if (fp2 > sp1 && fp1 > sp2) { + r = false; + goto end; + } + } + for (i = 0; i < snc; i++) { + v2f axis = sn[i]; + auto [fp1, fp2] = project(a, axis); + auto [sp1, sp2] = project(b, axis); + if (fp2 > sp1 && fp1 > sp2) { + r = false; + goto end; + } + } +end: + free(fn); + free(sn); + return r; +} + +int main(int argc, const char** argv) { + int r = 1; + SDL_Window* window; + SDL_Renderer* ren; + SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK); + SDL_CreateWindowAndRenderer( + 800, + 800, + 0, + &window, + &ren + ); + Shape a({ + v2f(300.0f, 300.0f), + v2f(400.0f, 400.0f), + v2f(250.0f, 500.0f), + }); + Shape tri({ + v2f(0.0f, 0.0f), + v2f(50.0f, 200.0f), + v2f(200.0f, 100.0f), + }); + while (r) { + int i; + SDL_Event e; + while (SDL_PollEvent(&e)) { + switch (e.type) { + case SDL_QUIT: + r = 0; + break; + } + } + int mx, my; + SDL_GetMouseState(&mx, &my); + Shape b(tri); + for (i = 0; i < b.count; i++) { + v2f& p = b.points[i]; + p.x += mx; + p.y += my; + } + SDL_SetRenderDrawColor(ren, 0x00, 0x00, 0x00, 0x00); + SDL_RenderClear(ren); + SDL_SetRenderDrawColor(ren, 0xff, 0x00, 0xff, 0xff); + a.render(ren); + if (intersect(a, b)) { + SDL_SetRenderDrawColor(ren, 0xff, 0x00, 0x00, 0xff); + } + b.render(ren); + SDL_RenderPresent(ren); + } + SDL_DestroyRenderer(ren); + SDL_DestroyWindow(window); + SDL_Quit(); + return 0; +} |