Test Failed
Push — master ( 1655fb...18f60e )
by Doug
04:26 queued 02:43
created

src/PackedBox.php (1 issue)

Severity
1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem).
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace DVDoug\BoxPacker;
10
11
use function is_null;
12
use function max;
13
use function round;
14
15
/**
16
 * A "box" with items.
17
 *
18
 * @author Doug Wright
19
 */
20
class PackedBox
21
{
22
    /**
23
     * Box used.
24
     *
25
     * @var Box
26
     */
27
    protected $box;
28
29
    /**
30
     * Items in the box.
31
     *
32
     * @var PackedItemList
33
     */
34
    protected $items;
35
36
    /**
37
     * Total weight of items in the box.
38
     *
39
     * @var int
40
     */
41
    protected $itemWeight;
42
43
    /**
44
     * Get box used.
45
     *
46
     * @return Box
47
     */
48 7
    public function getBox(): Box
49
    {
50 7
        return $this->box;
51
    }
52
53
    /**
54
     * Get items packed.
55
     *
56
     * @return PackedItemList
57
     */
58 23
    public function getItems(): PackedItemList
59
    {
60 23
        return $this->items;
61
    }
62
63
    /**
64
     * Get packed weight.
65
     *
66
     * @return int weight in grams
67
     */
68 2
    public function getWeight(): int
69
    {
70 2
        return $this->box->getEmptyWeight() + $this->getItemWeight();
71
    }
72
73
    /**
74
     * Get packed weight of the items only.
75
     *
76
     * @return int weight in grams
77
     */
78 3
    public function getItemWeight(): int
79
    {
80 3
        if (!is_null($this->itemWeight)) {
0 ignored issues
show
The condition is_null($this->itemWeight) is always false.
Loading history...
81 2
            return $this->itemWeight;
82
        }
83
84 3
        $this->itemWeight = 0;
85
        /** @var PackedItem $item */
86 3
        foreach ($this->items as $item) {
87 3
            $this->itemWeight += $item->getItem()->getWeight();
88
        }
89
90 3
        return $this->itemWeight;
91
    }
92
93
    /**
94
     * Get remaining width inside box for another item.
95
     *
96
     * @return int
97
     */
98 1
    public function getRemainingWidth(): int
99
    {
100 1
        return $this->box->getInnerWidth() - $this->getUsedWidth();
101
    }
102
103
    /**
104
     * Get remaining length inside box for another item.
105
     *
106
     * @return int
107
     */
108 1
    public function getRemainingLength(): int
109
    {
110 1
        return $this->box->getInnerLength() - $this->getUsedLength();
111
    }
112
113
    /**
114
     * Get remaining depth inside box for another item.
115
     *
116
     * @return int
117
     */
118 1
    public function getRemainingDepth(): int
119
    {
120 1
        return $this->box->getInnerDepth() - $this->getUsedDepth();
121
    }
122
123
    /**
124
     * Used width inside box for packing items.
125
     *
126
     * @return int
127
     */
128 1
    public function getUsedWidth(): int
129
    {
130 1
        $maxWidth = 0;
131
132
        /** @var PackedItem $item */
133 1
        foreach ($this->items as $item) {
134 1
            $maxWidth = max($maxWidth, $item->getX() + $item->getWidth());
135
        }
136
137 1
        return $maxWidth;
138
    }
139
140
    /**
141
     * Used length inside box for packing items.
142
     *
143
     * @return int
144
     */
145 1
    public function getUsedLength(): int
146
    {
147 1
        $maxLength = 0;
148
149
        /** @var PackedItem $item */
150 1
        foreach ($this->items as $item) {
151 1
            $maxLength = max($maxLength, $item->getY() + $item->getLength());
152
        }
153
154 1
        return $maxLength;
155
    }
156
157
    /**
158
     * Used depth inside box for packing items.
159
     *
160
     * @return int
161
     */
162 1
    public function getUsedDepth(): int
163
    {
164 1
        $maxDepth = 0;
165
166
        /** @var PackedItem $item */
167 1
        foreach ($this->items as $item) {
168 1
            $maxDepth = max($maxDepth, $item->getZ() + $item->getDepth());
169
        }
170
171 1
        return $maxDepth;
172
    }
173
174
    /**
175
     * Get remaining weight inside box for another item.
176
     *
177
     * @return int
178
     */
179 1
    public function getRemainingWeight(): int
180
    {
181 1
        return $this->box->getMaxWeight() - $this->getWeight();
182
    }
183
184
    /**
185
     * @return int
186
     */
187 3
    public function getInnerVolume(): int
188
    {
189 3
        return $this->box->getInnerWidth() * $this->box->getInnerLength() * $this->box->getInnerDepth();
190
    }
191
192
    /**
193
     * Get used volume of the packed box.
194
     *
195
     * @return int
196
     */
197 1
    public function getUsedVolume(): int
198
    {
199 1
        $volume = 0;
200
201
        /** @var PackedItem $item */
202 1
        foreach ($this->items as $item) {
203 1
            $volume += ($item->getWidth() * $item->getLength() * $item->getDepth());
204
        }
205
206 1
        return $volume;
207
    }
208
209
    /**
210
     * Get unused volume of the packed box.
211
     *
212
     * @return int
213
     */
214 1
    public function getUnusedVolume(): int
215
    {
216 1
        return $this->getInnerVolume() - $this->getUsedVolume();
217
    }
218
219
    /**
220
     * Get volume utilisation of the packed box.
221
     *
222
     * @return float
223
     */
224 1
    public function getVolumeUtilisation(): float
225
    {
226 1
        return round($this->getUsedVolume() / $this->getInnerVolume() * 100, 1);
227
    }
228
229
    /**
230
     * Constructor.
231
     *
232
     * @param Box            $box
233
     * @param PackedItemList $packedItemList
234
     */
235 25
    public function __construct(Box $box, PackedItemList $packedItemList)
236
    {
237 25
        $this->box = $box;
238 25
        $this->items = $packedItemList;
239 25
    }
240
}
241