Completed
Push — issue_187 ( fb1b49...8952f9 )
by Doug
158:46 queued 155:58
created

PackedBox   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 189
Duplicated Lines 0 %

Test Coverage

Coverage 50%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 37
c 2
b 0
f 0
dl 0
loc 189
ccs 25
cts 50
cp 0.5
rs 10
wmc 22

16 Methods

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