游戏服务端用来管理平面对象的四叉树算法
1
2
#include
<
stdlib.h
>
3
#include
<
stdio.h
>
4
#include
<
assert.h
>
5
6
7
8
//
search_box 时候还需要判断是否有叶子节点。没有的话。则不返回该非叶子节点。
9
10
//
delete
11
12
13
14
15
#define
QUAD_SUB_NODE_COUNT 4
16
17
enum
{
18
NE, // 0
19
NW, // 1
20
SW, // 2
21
SE, // 3
22
}
;
23
24
bool
overlap_box (
int
v1_minx,
int
v1_miny,
int
v1_maxx,
int
v1_maxy,
25
int
v2_minx,
int
v2_miny,
int
v2_maxx,
int
v2_maxy)
26
{
27
//return (this->_min._x > rv._max._x || this->_max._x < rv._min._x ||
28
// this->_min._y > rv._max._y || this->_max._y < rv._min._y) ?
29
// false : true;
30
return !(v1_minx > v2_maxx || v1_maxx < v2_minx ||
31
v1_miny >v2_maxy || v1_maxy <v2_miny); // ? false : true;
32
}
33
34
35
bool
at_point (
int
v1_minx,
int
v1_miny,
int
v1_maxx,
int
v1_maxy,
36
int
v2_minx,
int
v2_miny,
int
v2_maxx,
int
v2_maxy)
37
{
38
return (v1_minx == v2_minx && v1_maxx == v2_maxx &&
39
v1_miny == v2_miny && v1_maxy == v2_maxy);
40
}
41
42
43
44
#include
<
list
>
45
46
struct
Node;
47
struct
Leaf_Node
48
{
49
Node * _parent;
50
typedef std::list <void *> List;
51
List data_list;
52
}
;
53
54
struct
Node
55
{
56
void init (Node * parent)
57
{
58
_parent = parent;
59
_leaf_node = 0;
60
_sub[NE] = 0;
61
_sub[NW] = 0;
62
_sub[SW] = 0;
63
_sub[SE] = 0;
64
}
65
66
void set (int min_x, int min_y, int max_x, int max_y)
67
{
68
_min_x = min_x;
69
_min_y = min_y;
70
_max_x = max_x;
71
_max_y = max_y;
72
}
73
74
bool has_child ()
75
{
76
return _sub[NE] != 0;
77
}
78
79
bool is_sub_empty ()
80
{
81
return
82
!(_sub[NE]->_sub[NE] &&
83
//_sub[NE]->_sub[NW] &&
84
//_sub[NE]->_sub[SW] &&
85
//_sub[NE]->_sub[SE] &&
86
87
_sub[NW]->_sub[NE] &&
88
//_sub[NW]->_sub[NW] &&
89
//_sub[NW]->_sub[SW] &&
90
//_sub[NW]->_sub[SE] &&
91
92
_sub[SW]->_sub[NE] &&
93
//_sub[SW]->_sub[NW] &&
94
//_sub[SW]->_sub[SW] &&
95
//_sub[SW]->_sub[SE] &&
96
97
_sub[SE]->_sub[NE] //&&
98
//_sub[SE]->_sub[NW] &&
99
//_sub[SE]->_sub[SW] &&
100
//_sub[SE]->_sub[SE]
101
);
102
}
103
104
void create_child ()
105
{
106
_sub[NE] = (Node *) malloc (sizeof Node);
107
_sub[NW] = (Node *) malloc (sizeof Node);
108
_sub[SW] = (Node *) malloc (sizeof Node);
109
_sub[SE] = (Node *) malloc (sizeof Node);
110
111
_sub[NE]->init (this);
112
_sub[NW]->init (this);
113
_sub[SW]->init (this);
114
_sub[SE]->init (this);
115
116
_sub[NE]->_index_in_parent = NE;
117
_sub[NW]->_index_in_parent = NW;
118
_sub[SW]->_index_in_parent = SW;
119
_sub[SE]->_index_in_parent = SE;
120
121
int center_x = (_max_x + _min_x) >> 1; /**//// 2;
122
int center_y = (_max_y + _min_y) >> 1; /**//// 2;
123
124
_sub[NE]->set (center_x, center_y,
125
_max_x, _max_y);
126
127
_sub[NW]->set (_min_x, center_y,
128
center_x, _max_y);
129
130
_sub[SW]->set (_min_x, _min_y,
131
center_x, center_y);
132
133
_sub[SE]->set (center_x, _min_y,
134
_max_x, center_y);
135
}
136
137
Node * _sub[QUAD_SUB_NODE_COUNT];
138
Node * _parent;
139
int _index_in_parent;
140
Leaf_Node * _leaf_node;
141
int _min_x;
142
int _min_y;
143
int _max_x;
144
int _max_y;
145
//int x;
146
//int y;
147
}
;
148
149
150
//
回调
151
typedef
int
(
*
search_box_callback) (Node
*
node);
152
153
154
class
Quadtree
155
{
156
public:
157
158
Quadtree ()
159
{
160
_root = 0;
161
_depth = 6;
162
}
163
164
// 初始化 四叉树大小
165
void init (int width, int height)
166
{
167
_width = width;
168
_height = height;
169
170
_root = (Node *) malloc (sizeof Node);
171
_root->init (0);
172
_root->set (0, 0, width, height);
173
}
174
175
// 递归销毁
176
void destroy (Node * curr_node)
177
{
178
if (curr_node)
{
179
if (curr_node->has_child())
{
180
destroy (curr_node->_sub[NE]);
181
destroy (curr_node->_sub[NW]);
182
destroy (curr_node->_sub[SW]);
183
destroy (curr_node->_sub[SE]);
184
}
185
free (curr_node);
186
}
187
}
188
189
// 在x, y上插入四叉树
190
void insert (int x, int y)
191
{
192
assert (x <= _width && y <=_height);
193
//int deep = 5;
194
_insert (_root, x, y, 0, 0, _width, _height, _depth);
195
}
196
197
// 判断点在哪个象限,然后再往那个象限细分。
198
void _insert (Node * curr_node, int x, int y,
199
int min_x, int min_y, int max_x, int max_y, int deep)
200
{
201
if (deep <= 0)
{
202
// 到了最深层了。该结束了。
203
if (x >= min_x && x <= max_x && y >= min_y && y <= max_y)
{
204
printf ("add leaf: (%d,%d) (%d,%d)\n", min_x, min_y,
205
max_x, max_y);
206
if (!curr_node->_leaf_node)
{
207
Leaf_Node * leaf = new Leaf_Node;
208
leaf->_parent = curr_node;
209
curr_node->_leaf_node = leaf;
210
}
211
}
212
return ;
213
}
214
215
if (! curr_node->has_child ())
{
216
curr_node->create_child ();
217
}
218
219
int center_x = (max_x + min_x) >> 1; // / 2;
220
int center_y = (max_y + min_y) >> 1; // / 2;
221
222
if (x < center_x)
{
223
if (y < center_y)
{
224
// 设置子节点
225
//curr_node->_sub[SW]->set (min_x, min_y, center_x, center_y);
226
//_insert (curr_node->_sub[SW], x, y,
227
// min_x, min_y, center_x, center_y, -- deep);
228
_insert (curr_node->_sub[SW], x, y,
229
curr_node->_sub[SW]->_min_x,
230
curr_node->_sub[SW]->_min_y,
231
curr_node->_sub[SW]->_max_x,
232
curr_node->_sub[SW]->_max_y,
233
-- deep);
234
printf ("insert SW sub node: (%d, %d), (%d, %d)\n",
235
min_x, min_y, center_x, center_y);
236
237
}
238
else
{
239
//curr_node->_sub[NW]->set (min_x, center_y, center_x, max_y);
240
//_insert (curr_node->_sub[NW], x, y,
241
// min_x, center_y, center_x, max_y, -- deep);
242
_insert (curr_node->_sub[NW], x, y,
243
curr_node->_sub[NW]->_min_x,
244
curr_node->_sub[NW]->_min_y,
245
curr_node->_sub[NW]->_max_x,
246
curr_node->_sub[NW]->_max_y,
247
-- deep);
248
printf ("insert NW sub node: (%d, %d), (%d, %d)\n",
249
min_x, center_y, center_x, max_y);
250
}
251
}
252
else
{
253
if (y < center_y)
{
254
//curr_node->_sub[SE]->set (center_x, min_y, max_x, center_y);
255
//_insert (curr_node->_sub[SE], x, y,
256
// center_x, min_y, max_x, center_y, -- deep);
257
_insert (curr_node->_sub[SE], x, y,
258
curr_node->_sub[SE]->_min_x,
259
curr_node->_sub[SE]->_min_y,
260
curr_node->_sub[SE]->_max_x,
261
curr_node->_sub[SE]->_max_y,
262
-- deep);
263
printf ("insert SE sub node: (%d, %d), (%d, %d)\n",
264
center_x, min_y, max_x, center_y);
265
266
}
267
else
{
268
//curr_node->_sub[NE]->set (center_x, center_y, max_x, max_y);
269
//_insert (curr_node->_sub[NE], x, y,
270
// center_x, center_y, max_x, max_y, -- deep);
271
272
_insert (curr_node->_sub[NE], x, y,
273
curr_node->_sub[NE]->_min_x,
274
curr_node->_sub[NE]->_min_y,
275
curr_node->_sub[NE]->_max_x,
276
curr_node->_sub[NE]->_max_y,
277
-- deep);
278
279
280
printf ("insert NE sub node: (%d, %d), (%d, %d)\n",
281
center_x, center_y, max_x, max_y);
282
}
283
284
}
285
}
286
287
// 搜索的次数还是太多。当一个空节点的时候。
288
void search_box (int x, int y,
289
int dx, int dy,
290
search_box_callback cb)
291
{
292
_search_box (_root, /**//*x, y,*/ x-dx, y-dy, x+dx, y+dy, cb);
293
}
294
295
296
void _search_box (Node * node, /**//*int x, int y,*/
297
int min_x, int min_y, int max_x, int max_y,
298
search_box_callback cb)
299
{
300
printf ("search_box\n");
301
if (overlap_box (min_x, min_y,
302
max_x, max_y,
303
node->_min_x, node->_min_y,
304
node->_max_x, node->_max_y))
{
305
if (node->has_child())
{
306
_search_box (node->_sub[NE], /**//*x, y,*/ min_x, min_y, max_x, max_y, cb);
307
_search_box (node->_sub[NW],/**//* x, y,*/ min_x, min_y, max_x, max_y, cb);
308
_search_box (node->_sub[SW], /**//*x, y,*/ min_x, min_y, max_x, max_y, cb);
309
_search_box (node->_sub[SE], /**//*x, y,*/ min_x, min_y, max_x, max_y, cb);
310
}
311
// 不再有子节点。说明已经是叶子了。可以返回给上一层了。
312
else
{
313
if (node->_leaf_node)
{
314
printf ("search_box finded: ");
315
cb (node);
316
}
317
}
318
}
319
}
320
321
322
323
void search_line (int x, int y,
324
int end_x, int end_y, search_box_callback cb)
325
{
326
int min_x = x < end_x ? x: end_x;
327
int min_y = y < end_y ? y: end_y;
328
int max_x = x > end_x ? x : end_x;
329
int max_y = y > end_y ? y : end_y;
330
331
// 斜率
332
float h = ((float) max_y - (float)min_y) / ((float)max_x - (float)min_x);
333
_search_line (_root, h, x, y, min_x, min_y, max_x, max_y, cb);
334
}
335
336
void _search_line (Node * curr_node, float h, int x, int y, // x, y, h用来算一个点在不在一个直线上
337
int min_x, int min_y, int max_x, int max_y, search_box_callback cb)
338
{
339
printf ("search_line\n");
340
if (overlap_box (min_x, min_y,
341
max_x, max_y,
342
curr_node->_min_x, curr_node->_min_y,
343
curr_node->_max_x, curr_node->_max_y))
{
344
if (curr_node->has_child())
{
345
_search_line (curr_node->_sub[NE], h, x, y, min_x, min_y, max_x, max_y, cb);
346
_search_line (curr_node->_sub[NW], h, x, y, min_x, min_y, max_x, max_y, cb);
347
_search_line (curr_node->_sub[SW], h, x, y, min_x, min_y, max_x, max_y, cb);
348
_search_line (curr_node->_sub[SE], h, x, y, min_x, min_y, max_x, max_y, cb);
349
}
350
// 不再有子节点。说明已经是叶子了。可以返回给上一层了。
351
else
{
352
// 是否在直线内,并且有叶子节点
353
if (abs((float)(curr_node->_min_y) - (float)y - ((float)(curr_node->_min_x) - (float)x) * h) < 0.01f)
{
354
if (curr_node->_leaf_node)
{
355
printf ("search_line finded: ");
356
cb (curr_node);
357
}
358
}
359
360
}
361
}
362
363
}
364
365
void _delete_empty_node (Node * node)
366
{
367
printf ("_delete_empty_node\n");
368
if (_root == node)
{
369
return;
370
}
371
// 上一层的其他子节点没有叶子了。
372
if (!(node->_parent->_sub[NE]->_leaf_node || node->_parent->_sub[NW]->_leaf_node
373
|| node->_parent->_sub[SW]->_leaf_node || node->_parent->_sub[SE]->_leaf_node))
{
374
Node * parent = node->_parent;
375
free (parent->_sub[NE]);
376
free (parent->_sub[NW]);
377
free (parent->_sub[SW]);
378
free (parent->_sub[SE]);
379
380
parent->_sub[NE] = 0;
381
parent->_sub[NW] = 0;
382
parent->_sub[SW] = 0;
383
parent->_sub[SE] = 0;
384
385
_delete_empty_node (parent);
386
}
387
}
388
389
void delete_node (Leaf_Node * leaf/**//*, Node * curr_node*/)
390
{
391
Node * in_node = leaf->_parent;
392
in_node->_leaf_node = 0;
393
delete leaf;
394
395
_delete_empty_node (in_node);
396
397
}
398
399
400
Node * get_node (int x, int y)
401
{
402
return _search (x, y, x+1, y+1, _root);
403
}
404
405
// 搜索的次数还是太多。当一个空节点的时候。
406
Node * _search (int min_x, int min_y, int max_x, int max_y, Node * curr_node)
407
{
408
printf ("_search() \n");
409
if (overlap_box (min_x, min_y, max_x, max_y,
410
curr_node->_min_x, curr_node->_min_y,
411
curr_node->_max_x, curr_node->_max_y))
{
412
413
if (curr_node->_leaf_node)
{
414
if (at_point (min_x, min_y, max_x, max_y,
415
curr_node->_min_x, curr_node->_min_y,
416
curr_node->_max_x, curr_node->_max_y))
{
417
printf ("find! %d %d\n", min_x, min_y);
418
return curr_node;
419
}
420
}
421
422
423
if (curr_node->has_child())
{
424
printf ("serach :(%d,%d):(%d,%d)\n", min_x, min_y, max_x, max_y);
425
426
for (int i = 0; i < QUAD_SUB_NODE_COUNT; i ++)
{
427
Node * ret = _search(min_x, min_y,
428
max_x, max_y, curr_node->_sub[i]);
429
if (ret)
{
430
return ret;
431
}
432
}
433
}
434
}
435
return 0;
436
}
437
438
439
// 递归打印
440
void dump (Node * node, int deep = 0)
441
{
442
if (node)
{
443
for (int i = 0; i < deep; i ++)
{
444
printf ("+");
445
}
446
printf ("minx: %d, miny: %d, maxx: %d, maxy: %d\n",
447
node->_min_x, node->_min_y, node->_max_x, node->_max_y);
448
if (node->has_child())
{
449
dump (node->_sub[NE], ++deep);
450
dump (node->_sub[NW], deep);
451
dump (node->_sub[SW], deep);
452
dump (node->_sub[SE], deep);
453
}
454
}
455
}
456
457
// 获取root
458
Node * root ()
459
{
460
return _root;
461
}
462
463
protected:
464
Node * _root;
465
int _width;
466
int _height;
467
int _depth;
468
}
;
469
470

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

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155



156

157

158

159



160

161

162

163

164

165

166



167

168

169

170

171

172

173

174

175

176

177



178



179



180

181

182

183

184

185

186

187

188

189

190

191



192

193

194

195

196

197

198

199

200



201



202

203



204

205

206



207

208

209

210

211

212

213

214

215



216

217

218

219

220

221

222



223



224

225

226

227

228

229

230

231

232

233

234

235

236

237

238



239

240

241

242

243

244

245

246

247

248

249

250

251

252



253



254

255

256

257

258

259

260

261

262

263

264

265

266

267



268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291



292


293

294

295

296


297

298

299



300

301

302

303

304



305



306


307


308


309


310

311

312



313



314

315

316

317

318

319

320

321

322

323

324

325



326

327

328

329

330

331

332

333

334

335

336

337

338



339

340

341

342

343



344



345

346

347

348

349

350

351



352

353



354



355

356

357

358

359

360

361

362

363

364

365

366



367

368



369

370

371

372

373



374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389


390



391

392

393

394

395

396

397

398

399

400

401



402

403

404

405

406

407



408

409

410

411



412

413



414

415

416



417

418

419

420

421

422

423



424

425

426



427

428

429



430

431

432

433

434

435

436

437

438

439

440

441



442



443



444

445

446

447

448



449

450

451

452

453

454

455

456

457

458

459



460

461

462

463

464

465

466

467

468

469

470
