-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathquadtree.js
127 lines (112 loc) · 2.84 KB
/
quadtree.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
class Point {
constructor(x, y,name) {
this.x = x;
this.y = y;
this.name=name;
}
}
class Rectangle {
constructor(x, y, w, h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
contains(point) {
return (point.x >= this.x - this.w &&
point.x < this.x + this.w &&
point.y >= this.y - this.h &&
point.y < this.y + this.h);
}
intersects(range) {
return !(range.x - range.w > this.x + this.w ||
range.x + range.w < this.x - this.w ||
range.y - range.h > this.y + this.h ||
range.y + range.h < this.y - this.h);
}
}
class QuadTree {
constructor(boundary, n) {
this.boundary = boundary;
this.capacity = n;
this.points = [];
this.divided = false;
}
subdivide() {
let x = this.boundary.x;
let y = this.boundary.y;
let w = this.boundary.w;
let h = this.boundary.h;
let ne = new Rectangle(x + w / 2, y - h / 2, w / 2, h / 2);
this.northeast = new QuadTree(ne, this.capacity);
let nw = new Rectangle(x - w / 2, y - h / 2, w / 2, h / 2);
this.northwest = new QuadTree(nw, this.capacity);
let se = new Rectangle(x + w / 2, y + h / 2, w / 2, h / 2);
this.southeast = new QuadTree(se, this.capacity);
let sw = new Rectangle(x - w / 2, y + h / 2, w / 2, h / 2);
this.southwest = new QuadTree(sw, this.capacity);
this.divided = true;
}
insert(point) {
// console.log("point name",point.name);
if (!this.boundary.contains(point)) {
return false;
}
if (this.points.length < this.capacity) {
this.points.push(point);
return true;
} else {
if (!this.divided) {
this.subdivide();
}
if (this.northeast.insert(point)) {
return true;
} else if (this.northwest.insert(point)) {
return true;
} else if (this.southeast.insert(point)) {
return true;
} else if (this.southwest.insert(point)) {
return true;
}
}
}
query(range, found) {
if (!found) {
found = [];
}
if (!this.boundary.intersects(range)) {
return;
} else {
for (let p of this.points) {
total_count++;
if (range.contains(p)) {
found.push(p);
}
}
if (this.divided) {
this.northwest.query(range, found);
this.northeast.query(range, found);
this.southwest.query(range, found);
this.southeast.query(range, found);
}
}
return found;
}
show() {
stroke(255);
noFill();
strokeWeight(1);
rectMode(CENTER);
rect(this.boundary.x, this.boundary.y, this.boundary.w * 2, this.boundary.h * 2);
for (let p of this.points) {
strokeWeight(2);
point(p.x, p.y);
}
if (this.divided) {
this.northeast.show();
this.northwest.show();
this.southeast.show();
this.southwest.show();
}
}
}