#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(); }