Passed
Push — weight_redistributor ( 060e5b...8de9a1 )
by Doug
02:00
created

LayerStabiliser   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 52
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 6
lcom 0
cbo 4
dl 0
loc 52
ccs 19
cts 19
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A stabilise() 0 23 3
A compare() 0 4 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 Psr\Log\LoggerAwareInterface;
12
use Psr\Log\LoggerAwareTrait;
13
use Psr\Log\NullLogger;
14
15
/**
16
 * Applies load stability to generated result.
17
 *
18
 * @author Doug Wright
19
 */
20
class LayerStabiliser implements LoggerAwareInterface
21
{
22
    use LoggerAwareTrait;
23
24
    /**
25
     * Constructor.
26
     */
27 20
    public function __construct()
28
    {
29 20
        $this->logger = new NullLogger();
30 20
    }
31
32
    /**
33
     * @param PackedLayer[] $packedLayers
34
     *
35
     * @return PackedLayer[]
36
     */
37 20
    public function stabilise(array $packedLayers): array
38
    {
39
        // first re-order according to footprint
40 20
        $stabilisedLayers = [];
41 20
        usort($packedLayers, [$this, 'compare']);
42
43
        // then for each item in the layer, re-calculate each item's z position
44 20
        $currentZ = 0;
45 20
        foreach ($packedLayers as $oldZLayer) {
46 20
            $oldZStart = $oldZLayer->getStartDepth();
47 20
            $newZLayer = new PackedLayer();
48 20
            foreach ($oldZLayer->getItems() as $oldZItem) {
49 20
                $newZ = $oldZItem->getZ() - $oldZStart + $currentZ;
50 20
                $newZItem = new PackedItem($oldZItem->getItem(), $oldZItem->getX(), $oldZItem->getY(), $newZ, $oldZItem->getWidth(), $oldZItem->getLength(), $oldZItem->getDepth());
51 20
                $newZLayer->insert($newZItem);
52
            }
53
54 20
            $stabilisedLayers[] = $newZLayer;
55 20
            $currentZ += $newZLayer->getDepth();
56
        }
57
58 20
        return $stabilisedLayers;
59
    }
60
61
    /**
62
     * @param PackedLayer $layerA
63
     * @param PackedLayer $layerB
64
     *
65
     * @return int
66
     */
67 11
    private function compare(PackedLayer $layerA, PackedLayer $layerB): int
68
    {
69 11
        return ($layerB->getFootprint() <=> $layerA->getFootprint()) ?: ($layerB->getDepth() <=> $layerA->getDepth());
70
    }
71
}
72