diff --git a/quadtree/a.out b/quadtree/a.out new file mode 100755 index 0000000..3e0322f Binary files /dev/null and b/quadtree/a.out differ diff --git a/quadtree/main.c b/quadtree/main.c new file mode 100644 index 0000000..0276bdf --- /dev/null +++ b/quadtree/main.c @@ -0,0 +1,122 @@ +#include +#include +#include + +typedef struct Node { + Rectangle bounds; + Vector2 entities[4]; + int entity_count; + struct Node* children[4]; +} Node; + +Node* create_node(Rectangle bounds) { + Node* n = calloc(1, sizeof(Node)); + n->bounds = bounds; + return n; +} + +void split_node(Node* n) { + Rectangle b = n->bounds; + Vector2 half = (Vector2){ b.width / 2.0f, b.height / 2.0f }; + n->children[0] = create_node((Rectangle){ b.x, b.y, half.x, half.y }); + n->children[1] = create_node((Rectangle){ b.x + half.x, b.y, half.x, half.y }); + n->children[2] = create_node((Rectangle){ b.x, b.y + half.y, half.x, half.y }); + n->children[3] = create_node((Rectangle){ b.x + half.x, b.y + half.y, half.x, half.y }); +} + +int inside(Node* n, Vector2 p) { + return p.x > n->bounds.x && p.x < n->bounds.x + n->bounds.width && + p.y > n->bounds.y && p.y < n->bounds.y + n->bounds.height; +} + +int is_leaf(Node* n) { + return + n->children[0] == NULL && + n->children[1] == NULL && + n->children[2] == NULL && + n->children[3] == NULL; +} + +void add(Node* n, Vector2 p) { + if(n->entity_count >= 4) { + if(is_leaf(n)) { + split_node(n); + } + + int added = 0; + + for(int i = 0; i < 4; i++) { + if(inside(n->children[i], p)) { + add(n->children[i], p); + added = 1; + break; + } + } + + if(!added) { + add(n->children[0], p); + } + } else { + n->entities[n->entity_count++] = p; + } +} + +void draw(Vector2 p, Color c) { + DrawCircleV(p, 5.0f, c); +} + +void visualize(Node* n) { + //DrawRectangleLinesEx(n->bounds, 1.0f, RED); + + if(!is_leaf(n)) { + visualize(n->children[0]); + visualize(n->children[1]); + visualize(n->children[2]); + visualize(n->children[3]); + } + + Vector2 m_pos = GetMousePosition(); + + if(inside(n, m_pos)) { + //DrawRectangleLinesEx(n->bounds, 1.0f, BLUE); + for(int i = 0; i < n->entity_count; i++) { + if(CheckCollisionCircles(m_pos, 1.0f, n->entities[i], 5.0f)) { + draw(n->entities[i], GREEN); + } else { + draw(n->entities[i], WHITE); + } + } + } else { + for(int i = 0; i < n->entity_count; i++) { + draw(n->entities[i], WHITE); + } + } +} + +int main() { + const int width = 800; + const int height = 600; + InitWindow(width, height, "quadtree"); + + Node* root = create_node((Rectangle){ 0.0f, 0.0f, width, height }); + + for(int i = 0; i < 5000; i++) { + add(root, (Vector2){ GetRandomValue(0, width), GetRandomValue(0, height) }); + } + + while(!WindowShouldClose()) { + /*if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { + add(root, GetMousePosition()); + }*/ + + BeginDrawing(); + { + ClearBackground(BLACK); + visualize(root); + DrawFPS(10, 10); + } + EndDrawing(); + } + + CloseWindow(); +} diff --git a/quadtree/naive.c b/quadtree/naive.c new file mode 100644 index 0000000..2b06943 --- /dev/null +++ b/quadtree/naive.c @@ -0,0 +1,35 @@ +#include + +int main() { + const int width = 800; + const int height = 600; + InitWindow(width, height, "naive"); + + const int size = 5000; + Vector2 data[size]; + for(int i = 0; i < size; i++) { + data[i] = (Vector2){ GetRandomValue(0, 800), GetRandomValue(0, 600) }; + } + + while(!WindowShouldClose()) { + BeginDrawing(); + { + ClearBackground(BLACK); + + for(int i = 0; i < size; i++) { + if(CheckCollisionCircles(GetMousePosition(), 1.0f, data[i], 5.0f)) { + DrawCircleV(data[i], 5.0f, GREEN); + } else { + DrawCircleV(data[i], 5.0f, WHITE); + } + } + + DrawFPS(10, 10); + } + EndDrawing(); + } + + CloseWindow(); + + return 0; +}