Completed
Push — master ( 5c1190...2f7e26 )
by Dan
03:41
created

QuadTreeTest::testCollides()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 13

Duplication

Lines 5
Ratio 25 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 5
loc 20
rs 9.4285
cc 3
eloc 13
nc 3
nop 0
1
<?php
2
3
namespace SixtyNine\DataTypes\Tests;
4
5
use SixtyNine\DataTypes\Box;
6
use SixtyNine\DataTypes\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
    /**
54
     * @return array
55
     */
56
    public function getIndexProvider()
57
    {
58
        return array(
59
            array(-1, new Box(0, 0, 800, 600)),
60
            array(-1, (new Box(0, 0, 400, 300))->resize(1)),
61
            array(-1, new Box(300, 200, 200, 200)),
62
            array(0, new Box(0, 0, 400, 300)),
63
            array(0, (new Box(0, 0, 400, 300))->resize(-1)),
64
            array(1, new Box(400, 0, 400, 300)),
65
            array(1, new Box(750, 100, 50, 50)),
66
            array(2, new Box(0, 300, 400, 300)),
67
            array(2, new Box(250, 310, 50, 50)),
68
            array(3, new Box(400, 300, 400, 300)),
69
            array(3, new Box(700, 500, 50, 50)),
70
        );
71
    }
72
73
    public function testInsert()
74
    {
75
        $bounds = new Box(0, 0, 800, 600);
76
        $tree = new QuadTree($bounds);
77
78
        for ($i = 0; $i < 10; $i++) {
79
            $tree->insert(new Box(10, $i * 10, 10, 10));
80
            $this->assertEquals($i + 1, $tree->count());
81
        }
82
83
        $this->assertAttributeEquals(false, 'isSplit', $tree);
84
85
        $tree->insert(new Box(10, 110, 10, 10));
86
87
        $this->assertAttributeEquals(true, 'isSplit', $tree);
88
    }
89
90
    public function testRetrieve()
91
    {
92
        $bounds = new Box(0, 0, 80, 80);
93
        $tree = new QuadTree($bounds);
94
95
        for ($i = 0; $i < 80; $i += 10) {
96
            for ($j = 0; $j < 80; $j += 10) {
97
                $tree->insert(new Box($i, $j, 10, 10));
98
            }
99
        }
100
101
        $nodes = $tree->retrieve(new Box(5, 5, 10, 10));
102
        $expectedNodes = array(
103
            new Box(0, 0, 10, 10),
104
            new Box(10, 0, 10, 10),
105
            new Box(0, 10, 10, 10),
106
            new Box(10, 10, 10, 10),
107
        );
108
        $this->assertCount(4, $nodes);
109
110
        for ($i = 0; $i < 4; $i++) {
111
            $this->assertTrue(in_array($nodes[$i], $expectedNodes));
112
        }
113
    }
114
115
    public function testRetrieve1()
116
    {
117
        $count = 1000;
118
        $bounds = new Box(0, 0, 100, 100);
119
        $tree = new QuadTree($bounds);
120
        $this->fillTreeWithRandomBoxes($tree, $count);
121
        $this->assertEquals($count, count($tree->retrieve($bounds)));
122
        $this->assertEquals($tree->getAllObjects(), $tree->retrieve($bounds));
123
    }
124
125
    public function testCollides()
126
    {
127
        $bounds = new Box(0, 0, 80, 80);
128
        $tree = new QuadTree($bounds);
129
130
        for ($i = 0; $i < 80; $i += 10) {
131
            for ($j = 0; $j < 80; $j += 10) {
132
                $tree->insert(new Box($i, $j, 10, 10));
133
            }
134
        }
135
136
        $this->assertTrue($tree->collides(new Box(0, 0, 10, 10)));
137
        $this->assertTrue($tree->collides(new Box(5, 5, 10, 10)));
138
        $this->assertTrue($tree->collides(new Box(25, 25, 10, 10)));
139
        $this->assertTrue($tree->collides(new Box(50, 50, 10, 10)));
140
        $this->assertTrue($tree->collides(new Box(0, 0, 10, 10)));
141
        $this->assertTrue($tree->collides(new Box(70, 0, 10, 10)));
142
143
        $this->assertFalse($tree->collides(new Box(1000, 1000, 10, 10)));
144
    }
145
146
    public function testCollides1()
147
    {
148
        $bounds = new Box(0, 0, 100, 100);
149
        $tree = new QuadTree($bounds);
150
        $tree->insert(new Box(25, 25, 50, 50));
151
152
        $this->assertTrue($tree->collides(new Box(0, 0, 50, 50)));
153
        $this->assertTrue($tree->collides(new Box(25, 25, 10, 10)));
154
        $this->assertTrue($tree->collides(new Box(50, 50, 10, 10)));
155
156
        $this->assertFalse($tree->collides(new Box(0, 0, 10, 10)));
157
        $this->assertFalse($tree->collides(new Box(80, 80, 10, 10)));
158
        $this->assertFalse($tree->collides(new Box(1000, 1000, 10, 10)));
159
    }
160
161
    public function testCount()
162
    {
163
        $bounds = new Box(0, 0, 10000, 10000);
164
        $tree = new QuadTree($bounds);
165
        $this->fillTreeWithRandomBoxes($tree, 1000);
166
        $this->assertEquals(1000, $tree->count());
167
    }
168
169
    public function testGetAllObjects()
170
    {
171
        $bounds = new Box(0, 0, 10000, 10000);
172
        $tree = new QuadTree($bounds);
173
        $this->fillTreeWithRandomBoxes($tree, 1000);
174
        $this->assertCount(1000, $tree->getAllObjects());
175
    }
176
177
    /**
178
     * @param QuadTree $tree
179
     * @param int $count
180
     */
181
    protected function fillTreeWithRandomBoxes(QuadTree $tree, $count)
182
    {
183
        $treeWidth = $tree->getBounds()->getWidth();
184
        $treeHeight = $tree->getBounds()->getHeight();
185
186
        for ($i = 0; $i < $count; $i++) {
187
            $w = rand(0, 10);
188
            $h = rand(0, 10);
189
            $box = new Box(rand(0, $treeWidth - $w), rand(0, $treeHeight - $h), $w, $h);
190
            $tree->insert($box);
191
        }
192
    }
193
}
194