Test Failed
Push — 2.x-dev ( 5e90af...eccc16 )
by Doug
03:16
created

PackedBox::getBox()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem).
4
 *
5
 * @author Doug Wright
6
 */
7
namespace DVDoug\BoxPacker;
8
9
/**
10
 * A "box" with items.
11
 *
12
 * @author Doug Wright
13
 */
14
class PackedBox
15
{
16
    /**
17
     * Box used.
18
     *
19
     * @var Box
20
     */
21
    protected $box;
22
23
    /**
24
     * Items in the box.
25
     *
26
     * @var ItemList
27
     */
28
    protected $items;
29
30
    /**
31
     * Total weight of box.
32
     *
33
     * @var int
34
     */
35
    protected $weight;
36
37
    /**
38
     * Total weight of items in the box.
39
     *
40
     * @var int
41
     */
42
    protected $itemWeight;
43
44
    /**
45
     * Remaining width inside box for another item.
46
     *
47
     * @var int
48
     */
49
    protected $remainingWidth;
50
51
    /**
52
     * Remaining length inside box for another item.
53
     *
54
     * @var int
55
     */
56
    protected $remainingLength;
57
58
    /**
59
     * Remaining depth inside box for another item.
60
     *
61
     * @var int
62
     */
63
    protected $remainingDepth;
64
65
    /**
66
     * Remaining weight inside box for another item.
67
     *
68
     * @var int
69
     */
70
    protected $remainingWeight;
71
72
    /**
73
     * Used width inside box for packing items.
74
     *
75
     * @var int
76
     */
77
    protected $usedWidth;
78
79
    /**
80
     * Used length inside box for packing items.
81
     *
82
     * @var int
83
     */
84
    protected $usedLength;
85
86
    /**
87
     * Used depth inside box for packing items.
88
     *
89
     * @var int
90
     */
91
    protected $usedDepth;
92
93
    /**
94
     * @var PackedItemList
95
     */
96
    protected $packedItemList;
97
98
    /**
99
     * Get box used.
100
     *
101
     * @return Box
102
     */
103 4
    public function getBox()
104
    {
105 4
        return $this->box;
106
    }
107
108
    /**
109
     * Get items packed.
110
     *
111
     * @return ItemList
112
     */
113 29
    public function getItems()
114
    {
115 29
        return $this->items;
116
    }
117
118
    /**
119
     * Get packed weight.
120
     *
121
     * @return int weight in grams
122
     */
123 1
    public function getWeight()
124
    {
125 1
        return $this->box->getEmptyWeight() + $this->getItemWeight();
126
    }
127
128
    /**
129
     * Get packed weight of the items only.
130
     *
131
     * @return int weight in grams
132
     */
133 2
    public function getItemWeight()
134
    {
135 2
        if (!is_null($this->itemWeight)) {
0 ignored issues
show
introduced by
The condition is_null($this->itemWeight) is always false.
Loading history...
136
            return $this->itemWeight;
137
        }
138 2
        $this->itemWeight = 0;
139
        /** @var Item $item */
140 2
        foreach (clone $this->items as $item) {
141 2
            $this->itemWeight += $item->getWeight();
142
        }
143
144 2
        return $this->itemWeight;
145
    }
146
147
    /**
148
     * Get remaining width inside box for another item.
149
     *
150
     * @return int
151
     */
152 1
    public function getRemainingWidth()
153
    {
154 1
        return $this->remainingWidth;
155
    }
156
157
    /**
158
     * Get remaining length inside box for another item.
159
     *
160
     * @return int
161
     */
162 1
    public function getRemainingLength()
163
    {
164 1
        return $this->remainingLength;
165
    }
166
167
    /**
168
     * Get remaining depth inside box for another item.
169
     *
170
     * @return int
171
     */
172 1
    public function getRemainingDepth()
173
    {
174 1
        return $this->remainingDepth;
175
    }
176
177
    /**
178
     * Used width inside box for packing items.
179
     *
180
     * @return int
181
     */
182 1
    public function getUsedWidth()
183
    {
184 1
        return $this->usedWidth;
185
    }
186
187
    /**
188
     * Used length inside box for packing items.
189
     *
190
     * @return int
191
     */
192 1
    public function getUsedLength()
193
    {
194 1
        return $this->usedLength;
195
    }
196
197
    /**
198
     * Used depth inside box for packing items.
199
     *
200
     * @return int
201
     */
202 1
    public function getUsedDepth()
203
    {
204 1
        return $this->usedDepth;
205
    }
206
207
    /**
208
     * Get remaining weight inside box for another item.
209
     *
210
     * @return int
211
     */
212 1
    public function getRemainingWeight()
213
    {
214 1
        return $this->remainingWeight;
215
    }
216
217
    /**
218
     * @return int
219
     */
220 2
    public function getInnerVolume()
221
    {
222 2
        return $this->box->getInnerWidth() * $this->box->getInnerLength() * $this->box->getInnerDepth();
223
    }
224
225
    /**
226
     * Get used volume of the packed box.
227
     *
228
     * @return int
229
     */
230 1
    public function getUsedVolume()
231
    {
232 1
        $volume = 0;
233
        /** @var PackedItem $item */
234 1
        foreach (clone $this->items as $item) {
235 1
            $volume += $item->getVolume();
236
        }
237
238 1
        return $volume;
239
    }
240
241
    /**
242
     * Get unused volume of the packed box.
243
     *
244
     * @return int
245
     */
246 1
    public function getUnusedVolume()
247
    {
248 1
        return $this->getInnerVolume() - $this->getUsedVolume();
249
    }
250
251
    /**
252
     * Get volume utilisation of the packed box.
253
     *
254
     * @return float
255
     */
256 2
    public function getVolumeUtilisation()
257
    {
258 2
        $itemVolume = 0;
259
260
        /** @var Item $item */
261 2
        foreach (clone $this->items as $item) {
262 2
            $itemVolume += $item->getVolume();
263
        }
264
265 2
        return round($itemVolume / $this->box->getInnerVolume() * 100, 1);
266
    }
267
268
    /**
269
     * @return PackedItemList
270
     */
271 8
    public function getPackedItems()
272
    {
273 8
        if (!$this->packedItemList instanceof PackedItemList) {
0 ignored issues
show
introduced by
$this->packedItemList is always a sub-type of DVDoug\BoxPacker\PackedItemList.
Loading history...
274
            throw new RuntimeException('No PackedItemList was set. Are you using the old constructor?');
0 ignored issues
show
Bug introduced by
The type DVDoug\BoxPacker\RuntimeException was not found. Did you mean RuntimeException? If so, make sure to prefix the type with \.
Loading history...
275
        }
276 8
        return $this->packedItemList;
277
    }
278
279
    /**
280
     * @param PackedItemList $packedItemList
281
     */
282 31
    public function setPackedItems(PackedItemList $packedItemList)
283
    {
284 31
        $this->packedItemList = $packedItemList;
285 31
    }
286
287
    /**
288
     * Legacy constructor.
289
     *
290
     * @deprecated
291
     *
292
     * @param Box      $box
293
     * @param ItemList $itemList
294
     * @param int      $remainingWidth
295
     * @param int      $remainingLength
296
     * @param int      $remainingDepth
297
     * @param int      $remainingWeight
298
     * @param int      $usedWidth
299
     * @param int      $usedLength
300
     * @param int      $usedDepth
301
     */
302 31
    public function __construct(
303
        Box $box,
304
        ItemList $itemList,
305
        $remainingWidth,
306
        $remainingLength,
307
        $remainingDepth,
308
        $remainingWeight,
309
        $usedWidth,
310
        $usedLength,
311
        $usedDepth
312
    ) {
313 31
        $this->box = $box;
314 31
        $this->items = $itemList;
315 31
        $this->remainingWidth = $remainingWidth;
316 31
        $this->remainingLength = $remainingLength;
317 31
        $this->remainingDepth = $remainingDepth;
318 31
        $this->remainingWeight = $remainingWeight;
319 31
        $this->usedWidth = $usedWidth;
320 31
        $this->usedLength = $usedLength;
321 31
        $this->usedDepth = $usedDepth;
322 31
    }
323
324
    /**
325
     * The constructor from v3.
326
     *
327
     * @param Box            $box
328
     * @param PackedItemList $packedItems
329
     *
330
     * @return self
331
     */
332 31
    public static function fromPackedItemList(Box $box, PackedItemList $packedItems)
333
    {
334 31
        $maxWidth = $maxLength = $maxDepth = $weight = 0;
335
        /** @var PackedItem $item */
336 31
        foreach (clone $packedItems as $item) {
337 21
            $maxWidth = max($maxWidth, $item->getX() + $item->getWidth());
338 21
            $maxLength = max($maxLength, $item->getY() + $item->getLength());
339 21
            $maxDepth = max($maxDepth, $item->getZ() + $item->getDepth());
340 21
            $weight += $item->getItem()->getWeight();
341
        }
342
343 31
        $packedBox = new self(
344 31
            $box,
345 31
            $packedItems->asItemList(),
346 31
            $box->getInnerWidth() - $maxWidth,
347 31
            $box->getInnerLength() - $maxLength,
348 31
            $box->getInnerDepth() - $maxDepth,
349 31
            $box->getMaxWeight() - $box->getEmptyWeight() - $weight,
350
            $maxWidth,
351
            $maxLength,
352
            $maxDepth
353
        );
354 31
        $packedBox->setPackedItems($packedItems);
355
356 31
        return $packedBox;
357
    }
358
}
359