quadtree experiment
This commit is contained in:
parent
018a60790d
commit
d74e8185f5
BIN
quadtree/a.out
Executable file
BIN
quadtree/a.out
Executable file
Binary file not shown.
122
quadtree/main.c
Normal file
122
quadtree/main.c
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#include <raylib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
35
quadtree/naive.c
Normal file
35
quadtree/naive.c
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in a new issue