@@ -25,11 +25,9 @@ struct ActrQuadTree
25
25
{
26
26
int root ;
27
27
struct ActrQuadTreeBounds * bounds ;
28
- struct ActrQuadTree * one ;
29
- struct ActrQuadTree * two ;
30
- struct ActrQuadTree * three ;
31
- struct ActrQuadTree * four ;
32
28
struct ActrVector * items ;
29
+ struct ActrVector * stuck ;
30
+ struct ActrQuadTree * * branch ;
33
31
};
34
32
35
33
struct ActrQuadTreeBounds * _actr_quad_tree_bounds (long top , long right , long bottom , long left )
@@ -41,7 +39,7 @@ struct ActrQuadTreeBounds *_actr_quad_tree_bounds(long top, long right, long bot
41
39
bounds -> left = left ;
42
40
return bounds ;
43
41
}
44
- struct ActrQuadTreeLeaf * _actr_quad_tree_leaf (long top , long right , long bottom , long left , void * item )
42
+ struct ActrQuadTreeLeaf * actr_quad_tree_leaf (long top , long right , long bottom , long left , void * item )
45
43
{
46
44
struct ActrQuadTreeLeaf * leaf = actr_malloc (sizeof (struct ActrQuadTreeLeaf ));
47
45
leaf -> bounds = _actr_quad_tree_bounds (top , right , bottom , left );
@@ -51,11 +49,12 @@ struct ActrQuadTreeLeaf *_actr_quad_tree_leaf(long top, long right, long bottom,
51
49
52
50
// 1 2
53
51
// 4 3
54
- struct ActrQuadTree * actr_quad_tree_init ()
52
+ struct ActrQuadTree * actr_quad_tree_init (int root , int top , int right , int bottom , int left )
55
53
{
54
+
56
55
struct ActrQuadTree * result = actr_malloc (sizeof (struct ActrQuadTree ));
57
- result -> root = 1 ;
58
- result -> bounds = _actr_quad_tree_bounds (0 , 64 , 64 , 0 );
56
+ result -> root = root ;
57
+ result -> bounds = _actr_quad_tree_bounds (top , right , bottom , left );
59
58
return result ;
60
59
}
61
60
int _actr_quad_tree_bounds_contains (struct ActrQuadTreeBounds * bounds , struct ActrQuadTreeBounds * other )
@@ -98,103 +97,138 @@ void _actr_quad_tree_grow(struct ActrQuadTree *tree)
98
97
long grow = (size ) / 2 ;
99
98
actr_debug ("grow grow" , grow );
100
99
struct ActrQuadTree * new ;
101
- if (tree -> one )
102
- {
103
- // becomes 1.3
104
- new = actr_quad_tree_init ();
105
- new -> root = 0 ;
106
- new -> bounds -> top = tree -> bounds -> top - grow ;
107
- new -> bounds -> right = tree -> one -> bounds -> right ;
108
- new -> bounds -> bottom = tree -> one -> bounds -> bottom ;
109
- new -> bounds -> left = tree -> bounds -> left - grow ;
110
- new -> three = tree -> one ;
111
- tree -> one = new ;
112
- }
113
- if (tree -> two )
114
- {
115
- // 1 2
116
- // 4 3
117
- // becomes 2.4
118
- new = actr_quad_tree_init ();
119
- new -> root = 0 ;
120
- // 2
121
- new -> bounds -> top = tree -> bounds -> top - grow ;
122
- new -> bounds -> right = tree -> bounds -> right + grow ;
123
- new -> bounds -> bottom = tree -> two -> bounds -> bottom ;
124
- new -> bounds -> left = tree -> two -> bounds -> left ;
125
- new -> four = tree -> two ;
126
- tree -> two = new ;
127
- }
128
- if (tree -> three )
129
- {
130
- // 1 2
131
- // 4 3
132
- // becomes 3.1
133
- new = actr_quad_tree_init ();
134
- new -> root = 0 ;
135
- // 3
136
- new -> bounds -> top = tree -> three -> bounds -> top ;
137
- new -> bounds -> right = tree -> bounds -> right + grow ;
138
- new -> bounds -> bottom = tree -> bounds -> bottom + grow ;
139
- new -> bounds -> left = tree -> three -> bounds -> left ;
140
- new -> one = tree -> three ;
141
- tree -> three = new ;
142
- }
143
- if (tree -> four )
100
+ if (tree -> branch )
144
101
{
145
- // 1 2
146
- // 4 3
147
- // becomes 4.2
148
- new = actr_quad_tree_init ();
149
- new -> root = 0 ;
150
- // 4
151
- new -> bounds -> top = tree -> four -> bounds -> top ;
152
- new -> bounds -> right = tree -> four -> bounds -> right ;
153
- new -> bounds -> bottom = tree -> bounds -> bottom + grow ;
154
- new -> bounds -> left = tree -> bounds -> left - grow ;
155
- new -> two = tree -> four ;
156
- tree -> four = new ;
102
+ if (tree -> branch [0 ])
103
+ {
104
+ // becomes 1.3
105
+ new = actr_quad_tree_init (0 , tree -> bounds -> top - grow , tree -> branch [0 ]-> bounds -> right , tree -> branch [0 ]-> bounds -> bottom , tree -> bounds -> left - grow );
106
+ new -> branch [2 ] = tree -> branch [0 ];
107
+ tree -> branch [0 ] = new ;
108
+ }
109
+ if (tree -> branch [1 ])
110
+ {
111
+ // 1 2
112
+ // 4 3
113
+ // becomes 2.4
114
+ new = actr_quad_tree_init (0 , tree -> bounds -> top - grow , tree -> bounds -> right + grow , tree -> branch [1 ]-> bounds -> bottom , tree -> branch [1 ]-> bounds -> left );
115
+ // 2
116
+ new -> branch [3 ] = tree -> branch [1 ];
117
+ tree -> branch [1 ] = new ;
118
+ }
119
+ if (tree -> branch [2 ])
120
+ {
121
+ // 1 2
122
+ // 4 3
123
+ // becomes 3.1
124
+ new = actr_quad_tree_init (0 , tree -> branch [2 ]-> bounds -> top , tree -> bounds -> right + grow , tree -> bounds -> bottom + grow , tree -> branch [2 ]-> bounds -> left );
125
+ // 3
126
+ new -> branch [0 ] = tree -> branch [2 ];
127
+ tree -> branch [2 ] = new ;
128
+ }
129
+ if (tree -> branch [3 ])
130
+ {
131
+ // 1 2
132
+ // 4 3
133
+ // becomes 4.2
134
+ new = actr_quad_tree_init (0 , tree -> branch [3 ]-> bounds -> top , tree -> branch [3 ]-> bounds -> right , tree -> bounds -> bottom + grow , tree -> bounds -> left - grow );
135
+ // 4
136
+ new -> branch [1 ] = tree -> branch [3 ];
137
+ tree -> branch [3 ] = new ;
138
+ }
157
139
}
158
140
tree -> bounds -> top -= grow ;
159
141
tree -> bounds -> right += grow ;
160
142
tree -> bounds -> bottom += grow ;
161
143
tree -> bounds -> left -= grow ;
144
+ // actr_debug("qt grew width", tree->bounds->right - tree->bounds->left);
145
+ // actr_debug("qt grew height", tree->bounds->bottom - tree->bounds->top);
162
146
}
163
147
int _actr_quad_tree_index (struct ActrQuadTree * tree , struct ActrQuadTreeBounds * bounds )
164
148
{
165
149
// 1 2
166
150
// 4 3
167
151
long ymid = tree -> bounds -> top + (tree -> bounds -> bottom - tree -> bounds -> top ) / 2 ;
168
152
long xmid = tree -> bounds -> left + (tree -> bounds -> right - tree -> bounds -> left ) / 2 ;
153
+
154
+ actr_debug ("top" , tree -> bounds -> top );
155
+ actr_debug ("right" , tree -> bounds -> right );
156
+ actr_debug ("bottom" , tree -> bounds -> bottom );
157
+ actr_debug ("left" , tree -> bounds -> left );
158
+ actr_debug ("xmid" , xmid );
159
+ actr_debug ("ymid" , ymid );
160
+
169
161
if (bounds -> bottom < ymid )
170
162
{
163
+ // top half
171
164
if (bounds -> right < xmid )
172
165
{
166
+ // left half
167
+ return 0 ;
168
+ }
169
+ if (bounds -> left >= xmid )
170
+ {
171
+ // right half
173
172
return 1 ;
174
173
}
175
- return 2 ;
176
174
}
177
- if (bounds -> right < xmid )
175
+ else if (bounds -> top >= ymid )
178
176
{
179
- return 4 ;
177
+ // bottom half
178
+ if (bounds -> right < xmid )
179
+ {
180
+ // left half
181
+ return 3 ;
182
+ }
183
+ if (bounds -> left >= xmid )
184
+ {
185
+ // right half
186
+ return 2 ;
187
+ }
180
188
}
181
- return 3 ;
189
+ return -1 ;
190
+ }
191
+
192
+ void _actr_quad_tree_draw_bounds (struct ActrQuadTreeBounds * bounds )
193
+ {
194
+ actr_canvas2d_stroke_rect (bounds -> left , bounds -> top , bounds -> right - bounds -> left , bounds -> bottom - bounds -> top );
182
195
}
183
196
void actr_quad_tree_draw (struct ActrQuadTree * tree )
184
197
{
185
198
struct ActrQuadTreeLeaf * leaf ;
186
199
if (tree -> items )
187
200
{
188
- for (int i = 0 ; i < tree -> items -> pointer ; i ++ )
201
+ actr_canvas2d_stroke_style (0 , 255 , 255 , 50 );
202
+ for (int i = 0 ; i < tree -> items -> count ; i ++ )
189
203
{
190
- leaf = * (struct ActrQuadTreeLeaf * * )(tree -> items -> head + i * sizeof (void * ));
191
- actr_canvas2d_stroke_rect (leaf -> bounds -> left - 0.5 , leaf -> bounds -> top - 0.5 , leaf -> bounds -> right - leaf -> bounds -> left , leaf -> bounds -> bottom - leaf -> bounds -> top );
204
+ leaf = (struct ActrQuadTreeLeaf * )(tree -> items -> head [i ]);
205
+ _actr_quad_tree_draw_bounds (leaf -> bounds );
206
+ // actr_canvas2d_stroke_rect(leaf->bounds->left + 0.5, leaf->bounds->top + 0.5, leaf->bounds->right - leaf->bounds->left, leaf->bounds->bottom - leaf->bounds->top);
192
207
}
193
208
}
209
+ if (tree -> stuck ) {
210
+ actr_canvas2d_stroke_style (200 , 200 , 200 , 50 );
211
+ for (int i = 0 ; i < tree -> stuck -> count ; i ++ )
212
+ {
213
+ leaf = (struct ActrQuadTreeLeaf * )(tree -> stuck -> head [i ]);
214
+ _actr_quad_tree_draw_bounds (leaf -> bounds );
215
+ // actr_canvas2d_stroke_rect(leaf->bounds->left + 0.5, leaf->bounds->top + 0.5, leaf->bounds->right - leaf->bounds->left, leaf->bounds->bottom - leaf->bounds->top);
216
+ }
217
+ }
218
+
219
+ for (int i = 0 ; i < 4 ; i ++ )
220
+ {
221
+ if (tree -> branch [i ])
222
+ {
223
+ actr_quad_tree_draw (tree -> branch [i ]);
224
+ }
225
+ }
226
+
227
+ actr_canvas2d_stroke_style (0 , 255 , 0 , 50 );
228
+ _actr_quad_tree_draw_bounds (tree -> bounds );
194
229
}
195
- void actr_quad_tree_insert (struct ActrQuadTree * tree , long top , long right , long bottom , long left , void * item )
230
+ void actr_quad_tree_insert (struct ActrQuadTree * tree , struct ActrQuadTreeLeaf * leaf )
196
231
{
197
- struct ActrQuadTreeLeaf * leaf = _actr_quad_tree_leaf (top , right , bottom , left , item );
198
232
if (tree -> root )
199
233
{
200
234
while (!_actr_quad_tree_bounds_contains (tree -> bounds , leaf -> bounds ))
@@ -204,26 +238,66 @@ void actr_quad_tree_insert(struct ActrQuadTree *tree, long top, long right, long
204
238
}
205
239
if (!tree -> items )
206
240
{
207
- tree -> items = actr_malloc (sizeof (struct ActrVector ));
208
- actr_vector_add (tree -> items , leaf );
209
- return ;
210
- } else if (tree -> items ) {
211
- actr_vector_add (tree -> items , leaf );
212
- }
213
- int index = _actr_quad_tree_index (tree , leaf -> bounds );
214
-
215
- if (index == 1 )
216
- {
241
+ tree -> items = actr_vector_init (4 , 0 );
217
242
}
218
- else if (index == 2 )
219
- {
220
- }
221
- else if (index == 3 )
243
+ actr_vector_add (tree -> items , leaf );
244
+ actr_debug ("vec add count" , tree -> items -> count );
245
+ if (tree -> items -> count < 4 )
222
246
{
247
+ return ;
223
248
}
224
- else if ( index == 4 )
249
+ for ( int i = 0 ; i < 4 ; i ++ )
225
250
{
251
+ leaf = tree -> items -> head [i ];
252
+ // todo push items
253
+ int index = _actr_quad_tree_index (tree , leaf -> bounds );
254
+ if (index < 0 )
255
+ {
256
+ if (!tree -> stuck )
257
+ {
258
+ tree -> stuck = actr_vector_init (4 , 4 );
259
+ }
260
+ actr_vector_add (tree -> stuck , leaf );
261
+ continue ;
262
+ }
263
+ if (!tree -> branch )
264
+ {
265
+ tree -> branch = actr_malloc (4 * sizeof (void * ));
266
+ }
267
+
268
+ if (!tree -> branch [index ])
269
+ {
270
+ int width = (tree -> bounds -> right - tree -> bounds -> left ) / 2 ;
271
+ int height = (tree -> bounds -> bottom - tree -> bounds -> top ) / 2 ;
272
+ int top , right , bottom , left ;
273
+ if (index < 2 )
274
+ {
275
+ top = tree -> bounds -> top ;
276
+ bottom = top + height ;
277
+ }
278
+ else
279
+ {
280
+ bottom = tree -> bounds -> bottom ;
281
+ top = bottom - height ;
282
+ }
283
+ if (index == 0 || index == 3 )
284
+ {
285
+ left = tree -> bounds -> left ;
286
+ right = left + width ;
287
+ }
288
+ else
289
+ {
290
+ right = tree -> bounds -> right ;
291
+ left = right - width ;
292
+ }
293
+
294
+ tree -> branch [index ] = actr_quad_tree_init (0 , top , right , bottom , left );
295
+ }
296
+
297
+ actr_quad_tree_insert (tree -> branch [index ], leaf );
298
+
299
+ actr_debug ("qt insert index" , index );
226
300
}
227
- actr_debug ( "qt insert index" , index ) ;
301
+ tree -> items -> count = 0 ;
228
302
}
229
303
#endif
0 commit comments