Completed
Push — data_structures ( b3e6cb )
by Doug
18:44
created

PackedBox::getUsedVolume()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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