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