1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace SixtyNine\Cloud\Tests\Model; |
4
|
|
|
|
5
|
|
|
use SixtyNine\Cloud\Model\Box; |
6
|
|
|
use SixtyNine\Cloud\Model\QuadTree; |
7
|
|
|
|
8
|
|
|
class QuadTreeTest extends \PHPUnit_Framework_TestCase |
9
|
|
|
{ |
10
|
|
|
public function testConstructor() |
11
|
|
|
{ |
12
|
|
|
$bounds = new Box(0, 0, 800, 600); |
13
|
|
|
$tree = new QuadTree($bounds); |
14
|
|
|
$this->assertInstanceOf(QuadTree::class, $tree); |
15
|
|
|
$this->assertAttributeEquals($bounds, 'bounds', $tree); |
16
|
|
|
$this->assertAttributeEquals(0, 'level', $tree); |
17
|
|
|
$this->assertAttributeEquals(null, 'nodes', $tree); |
18
|
|
|
$this->assertEquals(0, $tree->count()); |
19
|
|
|
} |
20
|
|
|
|
21
|
|
|
public function testSplit() |
22
|
|
|
{ |
23
|
|
|
$bounds = new Box(0, 0, 800, 600); |
24
|
|
|
$tree = new QuadTree($bounds); |
25
|
|
|
$tree->split(); |
26
|
|
|
|
27
|
|
|
$nodes = $this->readAttribute($tree, 'nodes'); |
28
|
|
|
$this->assertInternalType('array', $nodes); |
29
|
|
|
$this->assertCount(4, $nodes); |
30
|
|
|
|
31
|
|
|
foreach ($nodes as $node) { |
32
|
|
|
$this->assertInstanceOf(QuadTree::class, $node); |
33
|
|
|
$this->assertAttributeEquals(null, 'nodes', $node); |
34
|
|
|
$nodeBounds = $this->readAttribute($node, 'bounds'); |
35
|
|
|
$this->assertContains($nodeBounds->getX(), array(0, 400)); |
36
|
|
|
$this->assertContains($nodeBounds->getY(), array(0, 300)); |
37
|
|
|
$this->assertEquals(400, $nodeBounds->getWidth()); |
38
|
|
|
$this->assertEquals(300, $nodeBounds->getHeight()); |
39
|
|
|
} |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @dataProvider getIndexProvider |
44
|
|
|
*/ |
45
|
|
|
public function testGetIndex($expectedIndex, $box) |
46
|
|
|
{ |
47
|
|
|
$bounds = new Box(0, 0, 800, 600); |
48
|
|
|
$tree = new QuadTree($bounds); |
49
|
|
|
|
50
|
|
|
$this->assertEquals($expectedIndex, $tree->getIndex($box)); |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
public function getIndexProvider() |
54
|
|
|
{ |
55
|
|
|
return array( |
56
|
|
|
array(-1, new Box(0, 0, 800, 600)), |
57
|
|
|
array(-1, (new Box(0, 0, 400, 300))->resize(1)), |
58
|
|
|
array(-1, new Box(300, 200, 200, 200)), |
59
|
|
|
array(0, new Box(0, 0, 400, 300)), |
60
|
|
|
array(0, (new Box(0, 0, 400, 300))->resize(-1)), |
61
|
|
|
array(1, new Box(400, 0, 400, 300)), |
62
|
|
|
array(1, new Box(750, 100, 50, 50)), |
63
|
|
|
array(2, new Box(0, 300, 400, 300)), |
64
|
|
|
array(2, new Box(250, 310, 50, 50)), |
65
|
|
|
array(3, new Box(400, 300, 400, 300)), |
66
|
|
|
array(3, new Box(700, 500, 50, 50)), |
67
|
|
|
); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
public function testInsert() |
71
|
|
|
{ |
72
|
|
|
$bounds = new Box(0, 0, 800, 600); |
73
|
|
|
$tree = new QuadTree($bounds); |
74
|
|
|
|
75
|
|
|
for ($i = 0; $i < 10; $i++) { |
76
|
|
|
$tree->insert(new Box(10, $i * 10, 10, 10)); |
77
|
|
|
$this->assertEquals($i + 1, $tree->count()); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
$this->assertAttributeEquals(false, 'isSplited', $tree); |
81
|
|
|
|
82
|
|
|
$tree->insert(new Box(10, 110, 10, 10)); |
83
|
|
|
|
84
|
|
|
$this->assertAttributeEquals(true, 'isSplited', $tree); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
public function testRetrieve() |
88
|
|
|
{ |
89
|
|
|
$bounds = new Box(0, 0, 80, 80); |
90
|
|
|
$tree = new QuadTree($bounds); |
91
|
|
|
|
92
|
|
|
for ($i = 0; $i < 80; $i += 10) { |
93
|
|
|
for ($j = 0; $j < 80; $j += 10) { |
94
|
|
|
$tree->insert(new Box($i, $j, 10, 10)); |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
$nodes = $tree->retrieve(new Box(5, 5, 10, 10)); |
99
|
|
|
$expectedNodes = array( |
100
|
|
|
new Box(0, 0, 10, 10), |
101
|
|
|
new Box(10, 0, 10, 10), |
102
|
|
|
new Box(0, 10, 10, 10), |
103
|
|
|
new Box(10, 10, 10, 10), |
104
|
|
|
); |
105
|
|
|
$this->assertCount(4, $nodes); |
106
|
|
|
|
107
|
|
|
for ($i = 0; $i < 4; $i++) { |
108
|
|
|
$this->assertTrue(in_array($nodes[$i], $expectedNodes)); |
109
|
|
|
} |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
public function testCollides() |
113
|
|
|
{ |
114
|
|
|
$bounds = new Box(0, 0, 80, 80); |
115
|
|
|
$tree = new QuadTree($bounds); |
116
|
|
|
|
117
|
|
|
for ($i = 0; $i < 80; $i += 10) { |
118
|
|
|
for ($j = 0; $j < 80; $j += 10) { |
119
|
|
|
$tree->insert(new Box($i, $j, 10, 10)); |
120
|
|
|
} |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
$this->assertTrue($tree->collides(new Box(0, 0, 10, 10))); |
124
|
|
|
$this->assertTrue($tree->collides(new Box(5, 5, 10, 10))); |
125
|
|
|
$this->assertTrue($tree->collides(new Box(25, 25, 10, 10))); |
126
|
|
|
$this->assertTrue($tree->collides(new Box(50, 50, 10, 10))); |
127
|
|
|
$this->assertTrue($tree->collides(new Box(0, 0, 10, 10))); |
128
|
|
|
$this->assertTrue($tree->collides(new Box(70, 0, 10, 10))); |
129
|
|
|
|
130
|
|
|
$this->assertFalse($tree->collides(new Box(1000, 1000, 10, 10))); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
public function testCollides1() |
134
|
|
|
{ |
135
|
|
|
$bounds = new Box(0, 0, 100, 100); |
136
|
|
|
$tree = new QuadTree($bounds); |
137
|
|
|
$tree->insert(new Box(25, 25, 50, 50)); |
138
|
|
|
|
139
|
|
|
$this->assertTrue($tree->collides(new Box(0, 0, 50, 50))); |
140
|
|
|
$this->assertTrue($tree->collides(new Box(25, 25, 10, 10))); |
141
|
|
|
$this->assertTrue($tree->collides(new Box(50, 50, 10, 10))); |
142
|
|
|
|
143
|
|
|
$this->assertFalse($tree->collides(new Box(0, 0, 10, 10))); |
144
|
|
|
$this->assertFalse($tree->collides(new Box(80, 80, 10, 10))); |
145
|
|
|
$this->assertFalse($tree->collides(new Box(1000, 1000, 10, 10))); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
// public function testRandom() |
|
|
|
|
149
|
|
|
// { |
150
|
|
|
//// $this->markTestSkipped('Makes no sense in "real" tests'); |
151
|
|
|
// |
152
|
|
|
// $bounds = new Box(0, 0, 10000, 10000); |
153
|
|
|
// $tree = new QuadTree($bounds); |
154
|
|
|
// |
155
|
|
|
// for ($i = 0; $i < 1000; $i++) { |
156
|
|
|
// $w = rand(0, 10); |
157
|
|
|
// $h = rand(0, 10); |
158
|
|
|
// $box = new Box(rand(0, 800 - $w), rand(0, 600 - $h), $w, $h); |
159
|
|
|
// $tree->insert($box); |
160
|
|
|
// } |
161
|
|
|
// |
162
|
|
|
// $box = new Box(0, 0, 50, 50); |
163
|
|
|
// |
164
|
|
|
// $list = $tree->retrieve($box); |
165
|
|
|
// echo (string)$box . PHP_EOL; |
166
|
|
|
// |
167
|
|
|
// $noCollision = 0; |
168
|
|
|
// foreach ($list as $object) { |
169
|
|
|
// if ($box->intersects($object)) { |
170
|
|
|
// echo ' Collision: ' . $object . PHP_EOL; |
171
|
|
|
// } else { |
172
|
|
|
// $noCollision++; |
173
|
|
|
// } |
174
|
|
|
// } |
175
|
|
|
// echo ' Boxes count: ' . $tree->count() . PHP_EOL; |
176
|
|
|
// echo ' Total results: ' . count($list) . PHP_EOL; |
177
|
|
|
// echo ' Tests with no collision: ' . $noCollision . PHP_EOL; |
178
|
|
|
// |
179
|
|
|
//// echo (string)$tree; |
180
|
|
|
// } |
181
|
|
|
} |
182
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.