#include #include #include #include "maths.cpp" struct Shape { v2f* points; int count; Shape(std::initializer_list 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 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{ 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; }