Passed
Push — 1.x-dev ( 8f914b...081a6e )
by Doug
04:31
created

OrientatedItem   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Test Coverage

Coverage 84.38%

Importance

Changes 5
Bugs 4 Features 0
Metric Value
eloc 29
dl 0
loc 141
ccs 27
cts 32
cp 0.8438
rs 10
c 5
b 4
f 0
wmc 12

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getDepth() 0 3 1
A getWidth() 0 3 1
A getSurfaceFootprint() 0 3 1
A getItem() 0 3 1
A getTippingPoint() 0 12 3
A jsonSerialize() 0 7 1
A __construct() 0 6 1
A getLength() 0 3 1
A isStable() 0 3 1
A __toString() 0 3 1
1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem).
4
 *
5
 * @author Doug Wright
6
 */
7
8
namespace DVDoug\BoxPacker;
9
10
use JsonSerializable;
11
12
/**
13
 * An item to be packed.
14
 *
15
 * @author Doug Wright
16
 */
17
class OrientatedItem implements JsonSerializable
18
{
19
    /**
20
     * @var Item
21
     */
22
    protected $item;
23
24
    /**
25
     * @var int
26
     */
27
    protected $width;
28
29
    /**
30
     * @var int
31
     */
32
    protected $length;
33
34
    /**
35
     * @var int
36
     */
37
    protected $depth;
38
39
    /**
40
     * @var float[]
41
     */
42
    protected static $tippingPointCache = [];
43
44
    /**
45
     * Constructor.
46
     *
47
     * @param Item $item
48
     * @param int  $width
49
     * @param int  $length
50
     * @param int  $depth
51
     */
52 19
    public function __construct(Item $item, $width, $length, $depth)
53
    {
54 19
        $this->item = $item;
55 19
        $this->width = $width;
56 19
        $this->length = $length;
57 19
        $this->depth = $depth;
58 19
    }
59
60
    /**
61
     * Item.
62
     *
63
     * @return Item
64
     */
65 19
    public function getItem()
66
    {
67 19
        return $this->item;
68
    }
69
70
    /**
71
     * Item width in mm in it's packed orientation.
72
     *
73
     * @return int
74
     */
75 19
    public function getWidth()
76
    {
77 19
        return $this->width;
78
    }
79
80
    /**
81
     * Item length in mm in it's packed orientation.
82
     *
83
     * @return int
84
     */
85 19
    public function getLength()
86
    {
87 19
        return $this->length;
88
    }
89
90
    /**
91
     * Item depth in mm in it's packed orientation.
92
     *
93
     * @return int
94
     */
95 19
    public function getDepth()
96
    {
97 19
        return $this->depth;
98
    }
99
100
    /**
101
     * Calculate the surface footprint of the current orientation.
102
     *
103
     * @return int
104
     */
105 1
    public function getSurfaceFootprint()
106
    {
107 1
        return $this->width * $this->length;
108
    }
109
110
    /**
111
     * @return float
112
     */
113 19
    public function getTippingPoint()
114
    {
115 19
        $cacheKey = $this->width . '|' . $this->length . '|' . $this->depth;
116
117 19
        if (isset(static::$tippingPointCache[$cacheKey])) {
118 17
            $tippingPoint = static::$tippingPointCache[$cacheKey];
119
        } else {
120 17
            $tippingPoint = atan(min($this->length, $this->width) / ($this->depth ?: 1));
121 17
            static::$tippingPointCache[$cacheKey] = $tippingPoint;
122
        }
123
124 19
        return $tippingPoint;
125
    }
126
127
    /**
128
     * Is this item stable (low centre of gravity), calculated as if the tipping point is >15 degrees.
129
     *
130
     * N.B. Assumes equal weight distribution.
131
     *
132
     * @return bool
133
     */
134 19
    public function isStable()
135
    {
136 19
        return $this->getTippingPoint() > 0.261;
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     */
142
    public function jsonSerialize()
143
    {
144
        return [
145
            'item' => $this->item,
146
            'width' => $this->width,
147
            'length' => $this->length,
148
            'depth' => $this->depth,
149
        ];
150
    }
151
152
    /**
153
     * @return string
154
     */
155 19
    public function __toString()
156
    {
157 19
        return $this->width . '|' . $this->length . '|' . $this->depth;
158
    }
159
}
160