Completed
Push — master ( 4734ca...53d220 )
by Doug
14:09
created

src/PackedBox.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 4
    public function getBox(): Box
41
    {
42 4
        return $this->box;
43
    }
44
45
    /**
46
     * Get items packed
47
     * @return PackedItemList
48
     */
49 32
    public function getItems(): PackedItemList
50
    {
51 32
        return $this->items;
52
    }
53
54
    /**
55
     * Get packed weight
56
     * @return int weight in grams
57
     */
58 9
    public function getWeight(): int
59
    {
60 9
        if (!is_null($this->weight)) {
61 6
            return $this->weight;
62
        }
63
64 9
        $this->weight = $this->box->getEmptyWeight();
65 9
        $items = clone $this->items;
66
        /** @var PackedItem $item */
67 9
        foreach ($items as $item) {
68 9
            $this->weight += $item->getItem()->getWeight();
69
        }
70 9
        return $this->weight;
71
    }
72
73
    /**
74
     * Get remaining width inside box for another item
75
     * @return int
76
     */
77 1
    public function getRemainingWidth(): int
78
    {
79 1
        return $this->box->getInnerWidth() - $this->getUsedWidth();
80
    }
81
82
    /**
83
     * Get remaining length inside box for another item
84
     * @return int
85
     */
86 1
    public function getRemainingLength(): int
87
    {
88 1
        return $this->box->getInnerLength() - $this->getUsedLength();
89
    }
90
91
    /**
92
     * Get remaining depth inside box for another item
93
     * @return int
94
     */
95 1
    public function getRemainingDepth(): int
96
    {
97 1
        return $this->box->getInnerDepth() - $this->getUsedDepth();
98
    }
99
100
    /**
101
     * Used width inside box for packing items
102
     * @return int
103
     */
104 5
    public function getUsedWidth(): int
105
    {
106 5
        $maxWidth = 0;
107
108
        /** @var PackedItem $item */
109 5
        foreach (clone $this->items as $item) {
110 5
            $maxWidth = max($maxWidth, $item->getX() + $item->getWidth());
111
        }
112
113 5
        return $maxWidth;
114
    }
115
116
    /**
117
     * Used length inside box for packing items
118
     * @return int
119
     */
120 5
    public function getUsedLength(): int
121
    {
122 5
        $maxLength = 0;
123
124
        /** @var PackedItem $item */
125 5
        foreach (clone $this->items as $item) {
126 5
            $maxLength = max($maxLength, $item->getY() + $item->getLength());
127
        }
128
129 5
        return $maxLength;
130
    }
131
132
    /**
133
     * Used depth inside box for packing items
134
     * @return int
135
     */
136 5
    public function getUsedDepth(): int
137
    {
138 5
        $maxDepth = 0;
139
140
        /** @var PackedItem $item */
141 5
        foreach (clone $this->items as $item) {
142 5
            $maxDepth = max($maxDepth, $item->getZ() + $item->getDepth());
143
        }
144
145 5
        return $maxDepth;
146
    }
147
148
    /**
149
     * Get remaining weight inside box for another item
150
     * @return int
151
     */
152 1
    public function getRemainingWeight(): int
153
    {
154 1
        return $this->box->getMaxWeight() - $this->getWeight();
155
    }
156
157
    /**
158
     * @return int
159
     */
160 5
    public function getInnerVolume(): int
161
    {
162 5
        return $this->box->getInnerDepth() * $this->box->getInnerDepth() * $this->box->getInnerDepth();
163
    }
164
165
    /**
166
     * Get volume utilisation of the packed box
167
     * @return float
168
     */
169 1
    public function getVolumeUtilisation(): float
170
    {
171 1
        $itemVolume = 0;
172
173
        /** @var PackedItem $item */
174 1 View Code Duplication
        foreach (clone $this->items as $item) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
175 1
            $itemVolume += ($item->getItem()->getWidth() * $item->getItem()->getLength() * $item->getItem()->getDepth());
176
        }
177
178 1
        return round($itemVolume / $this->getInnerVolume() * 100, 1);
179
    }
180
181
182
    /**
183
     * Constructor
184
     *
185
     * @param Box      $box
186
     * @param PackedItemList $itemList
187
     */
188 35
    public function __construct(Box $box, PackedItemList $itemList)
189
    {
190 35
        $this->box = $box;
191 35
        $this->items = $itemList;
192
    }
193
}
194