Passed
Push — master ( 1c55d1...03216d )
by Dan
02:01
created

Box::serialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 6
cts 6
cp 1
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace SixtyNine\DataTypes;
4
5
/**
6
 * An axis-aligned rectangle with collision detection
7
 */
8
class Box
9
{
10
    /** @var float */
11
    protected $x;
12
13
    /** @var float */
14
    protected $y;
15
16
    /** @var float */
17
    protected $width;
18
19
    /** @var float */
20
    protected $height;
21
22
    /** @var float */
23
    protected $top;
24
25
    /** @var float */
26
    protected $bottom;
27
28
    /** @var float */
29
    protected $left;
30
31
    /** @var float */
32
    protected $right;
33
34
    /**
35
     * Constructor
36
     * @param float $x
37
     * @param float $y
38
     * @param float $width
39
     * @param float $height
40
     */
41 26
    public function __construct($x, $y, $width, $height)
42
    {
43 26
        $this->x = $x;
44 26
        $this->y = $y;
45 26
        $this->width = $width;
46 26
        $this->height = $height;
47
48 26
        $this->update();
49 26
    }
50
51
    /**
52
     * Factory method.
53
     * @param float $x
54
     * @param float $y
55
     * @param float $width
56
     * @param float $height
57
     * @return Box
58
     */
59 5
    public static function create($x, $y, $width, $height) : Box
60
    {
61 5
        return new self($x, $y, $width, $height);
62
    }
63
64
    /**
65
     * Update the left, right, top, and bottom coordinates.
66
     */
67 26
    public function update()
68
    {
69 26
        $this->left = $this->x;
70 26
        $this->right = $this->x + $this->width;
71 26
        $this->top = $this->y;
72 26
        $this->bottom = $this->y + $this->height;
73 26
    }
74
75
    /**
76
     * Detect box collision
77
     * This algorithm only works with Axis-Aligned boxes!
78
     * @param Box $box The other rectangle to test collision with
79
     * @param bool $strict If true, boxes "touching" each other are not intersecting, otherwise they are
80
     * @return boolean True is the boxes collide, false otherwise
81
     */
82
    public function intersects(Box $box, $strict = true) : bool
83
    {
84 9
        $comparator = function ($x, $y) {
85 7
            return $x < $y;
86 9
        };
87
88 9
        if (!$strict) {
89 2
            $comparator = function ($x, $y) {
90 2
                return $x <= $y;
91 2
            };
92
        }
93
94 9
        return $comparator($this->getLeft(), $box->getRight())
95 9
            && $comparator($box->getLeft(), $this->getRight())
96 9
            && $comparator($this->getTop(), $box->getBottom())
97 9
            && $comparator($box->getTop(), $this->getBottom());
98
    }
99
100
    /**
101
     * @param Box $box
102
     * @return bool
103
     */
104 2
    public function inside(Box $box) : bool
105
    {
106 2
        return ($this->getLeft() >= $box->getLeft()
107 2
            && $this->getRight() <= $box->getRight()
108 2
            && $this->getTop() >= $box->getTop()
109 2
            && $this->getBottom() <= $box->getBottom()
110
        );
111
    }
112
113
    /**
114
     * @param float $deltaX
115
     * @param float $deltaY
116
     * @return Box
117
     */
118 1
    public function move($deltaX, $deltaY) : Box
119
    {
120 1
        return new self($this->getX() + $deltaX, $this->getY() + $deltaY, $this->getWidth(), $this->getHeight());
121
    }
122
123
    /**
124
     * @param int $increment
125
     * @return Box
126
     */
127 1
    public function resize($increment) : Box
128
    {
129 1
        return new self(
130 1
            $this->getX() - $increment,
131 1
            $this->getY() - $increment,
132 1
            $this->getWidth() + 2 * $increment,
133 1
            $this->getHeight() + 2 * $increment
134
        );
135
    }
136
137
    /**
138
     * @return float
139
     */
140 12
    public function getBottom() : float
141
    {
142 12
        return $this->bottom;
143
    }
144
145
    /**
146
     * @return float
147
     */
148 19
    public function getHeight() : float
149
    {
150 19
        return $this->height;
151
    }
152
153
    /**
154
     * @return float
155
     */
156 16
    public function getLeft() : float
157
    {
158 16
        return $this->left;
159
    }
160
161
    /**
162
     * @return float
163
     */
164 15
    public function getRight() : float
165
    {
166 15
        return $this->right;
167
    }
168
169
    /**
170
     * @return float
171
     */
172 12
    public function getTop() : float
173
    {
174 12
        return $this->top;
175
    }
176
177
    /**
178
     * @return float
179
     */
180 19
    public function getWidth() : float
181
    {
182 19
        return $this->width;
183
    }
184
185
    /**
186
     * @return float
187
     */
188 21
    public function getX() : float
189
    {
190 21
        return $this->x;
191
    }
192
193
    /**
194
     * @return float
195
     */
196 21
    public function getY() : float
197
    {
198 21
        return $this->y;
199
    }
200
201
    /**
202
     * @return Vector
203
     */
204 1
    public function getPosition() : Vector
205
    {
206 1
        return new Vector($this->getX(), $this->getY());
207
    }
208
209
    /**
210
     * @return Vector
211
     */
212 1
    public function getDimensions() : Vector
213
    {
214 1
        return new Vector($this->getWidth(), $this->getHeight());
215
    }
216
217
    /**
218
     * @return Vector
219
     */
220 18
    public function getCenter() : Vector
221
    {
222 18
        return new Vector(
223 18
            $this->x + $this->width / 2,
224 18
            $this->y + $this->height / 2
225
        );
226
    }
227
228
    /**
229
     * @return string
230
     */
231 1
    public function __toString() : string
232
    {
233 1
        return sprintf('[%s, %s] x [%s, %s]', $this->x, $this->y, $this->width, $this->height);
234
    }
235
236 1
    public function serialize(): string
237
    {
238 1
        return json_encode([
239 1
            'x' => $this->x,
240 1
            'y' => $this->y,
241 1
            'width' => $this->width,
242 1
            'height' => $this->height,
243
        ]);
244
    }
245
}
246