Completed
Push — 2.x-dev ( 03f1cc...530003 )
by Doug
45:33 queued 44:04
created

PackedBox::fromPackedItemList()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 18
cts 18
cp 1
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 18
nc 2
nop 2
crap 2
1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem)
4
 * @package BoxPacker
5
 * @author Doug Wright
6
 */
7
namespace DVDoug\BoxPacker;
8
9
/**
10
 * A "box" with items
11
 * @author Doug Wright
12
 * @package BoxPacker
13
 */
14
class PackedBox
15
{
16
17
    /**
18
     * Box used
19
     * @var Box
20
     */
21
    protected $box;
22
23
    /**
24
     * Items in the box
25
     * @var ItemList
26
     */
27
    protected $items;
28
29
    /**
30
     * Total weight of box
31
     * @var int
32
     */
33
    protected $weight;
34
35
    /**
36
     * Remaining width inside box for another item
37
     * @var int
38
     */
39
    protected $remainingWidth;
40
41
    /**
42
     * Remaining length inside box for another item
43
     * @var int
44
     */
45
    protected $remainingLength;
46
47
    /**
48
     * Remaining depth inside box for another item
49
     * @var int
50
     */
51
    protected $remainingDepth;
52
53
    /**
54
     * Remaining weight inside box for another item
55
     * @var int
56
     */
57
    protected $remainingWeight;
58
59
    /**
60
     * Used width inside box for packing items
61
     * @var int
62
     */
63
    protected $usedWidth;
64
65
    /**
66
     * Used length inside box for packing items
67
     * @var int
68
     */
69
    protected $usedLength;
70
71
    /**
72
     * Used depth inside box for packing items
73
     * @var int
74
     */
75
    protected $usedDepth;
76
77
    /**
78
     * Get box used
79
     * @return Box
80
     */
81 6
    public function getBox()
82
    {
83 6
        return $this->box;
84
    }
85
86
    /**
87
     * Get items packed
88
     * @return ItemList
89
     */
90 35
    public function getItems()
91
    {
92 35
        return $this->items;
93
    }
94
95
    /**
96
     * Get packed weight
97
     * @return int weight in grams
98
     */
99 8
    public function getWeight()
100
    {
101 8
        if (!is_null($this->weight)) {
102 6
            return $this->weight;
103
        }
104
105 8
        $this->weight = $this->box->getEmptyWeight();
106 8
        $items = clone $this->items;
107 8
        foreach ($items as $item) {
108 8
            $this->weight += $item->getWeight();
109
        }
110 8
        return $this->weight;
111
    }
112
113
    /**
114
     * Get remaining width inside box for another item
115
     * @return int
116
     */
117 1
    public function getRemainingWidth()
118
    {
119 1
        return $this->remainingWidth;
120
    }
121
122
    /**
123
     * Get remaining length inside box for another item
124
     * @return int
125
     */
126 1
    public function getRemainingLength()
127
    {
128 1
        return $this->remainingLength;
129
    }
130
131
    /**
132
     * Get remaining depth inside box for another item
133
     * @return int
134
     */
135 1
    public function getRemainingDepth()
136
    {
137 1
        return $this->remainingDepth;
138
    }
139
140
    /**
141
     * Used width inside box for packing items
142
     * @return int
143
     */
144 4
    public function getUsedWidth()
145
    {
146 4
        return $this->usedWidth;
147
    }
148
149
    /**
150
     * Used length inside box for packing items
151
     * @return int
152
     */
153 4
    public function getUsedLength()
154
    {
155 4
        return $this->usedLength;
156
    }
157
158
    /**
159
     * Used depth inside box for packing items
160
     * @return int
161
     */
162 4
    public function getUsedDepth()
163
    {
164 4
        return $this->usedDepth;
165
    }
166
167
    /**
168
     * Get remaining weight inside box for another item
169
     * @return int
170
     */
171 1
    public function getRemainingWeight()
172
    {
173 1
        return $this->remainingWeight;
174
    }
175
176
    /**
177
     * Get volume utilisation of the packed box
178
     * @return float
179
     */
180 1
    public function getVolumeUtilisation()
181
    {
182 1
        $itemVolume = 0;
183
184
        /** @var Item $item */
185 1
        foreach (clone $this->items as $item) {
186 1
            $itemVolume += $item->getVolume();
187
        }
188
189 1
        return round($itemVolume / $this->box->getInnerVolume() * 100, 1);
190
    }
191
192
193
    /**
194
     * Legacy constructor
195
     * @deprecated
196
     *
197
     * @param Box      $box
198
     * @param ItemList $itemList
199
     * @param int      $remainingWidth
200
     * @param int      $remainingLength
201
     * @param int      $remainingDepth
202
     * @param int      $remainingWeight
203
     * @param int      $usedWidth
204
     * @param int      $usedLength
205
     * @param int      $usedDepth
206
     */
207 38
    public function __construct(
208
        Box $box,
209
        ItemList $itemList,
210
        $remainingWidth,
211
        $remainingLength,
212
        $remainingDepth,
213
        $remainingWeight,
214
        $usedWidth,
215
        $usedLength,
216
        $usedDepth
217
    )
218
    {
219 38
        $this->box = $box;
220 38
        $this->items = $itemList;
221 38
        $this->remainingWidth = $remainingWidth;
222 38
        $this->remainingLength = $remainingLength;
223 38
        $this->remainingDepth = $remainingDepth;
224 38
        $this->remainingWeight = $remainingWeight;
225 38
        $this->usedWidth = $usedWidth;
226 38
        $this->usedLength = $usedLength;
227 38
        $this->usedDepth = $usedDepth;
228
    }
229
230
    /**
231
     * The constructor from v3
232
     * @param Box            $box
233
     * @param PackedItemList $packedItems
234
     */
235 34
    public static function fromPackedItemList(Box $box, PackedItemList $packedItems)
236
    {
237 34
        $maxWidth = $maxLength = $maxDepth = $weight = 0;
238
        /** @var PackedItem $item */
239 34
        foreach (clone $packedItems as $item) {
240 34
            $maxWidth = max($maxWidth, $item->getX() + $item->getWidth());
241 34
            $maxLength = max($maxLength, $item->getY() + $item->getLength());
242 34
            $maxDepth = max($maxDepth, $item->getZ() + $item->getDepth());
243 34
            $weight += $item->getItem()->getWeight();
244
        }
245
246 34
        $packedBox = new self(
247 34
            $box,
248 34
            $packedItems->asItemList(),
249 34
            $box->getInnerWidth() - $maxWidth,
250 34
            $box->getInnerLength() - $maxLength,
251 34
            $box->getInnerDepth() - $maxDepth,
252 34
            $box->getMaxWeight() - $box->getEmptyWeight() - $weight,
253 34
            $maxWidth,
254 34
            $maxLength,
255 34
            $maxDepth
256
        );
257
258 34
        return $packedBox;
259
    }
260
}
261