Passed
Push — 2.x-dev ( 9c54be...ba24d3 )
by Doug
04:59
created

OrientatedItem::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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