Test Failed
Push — master ( b39eb7...589279 )
by Edgar
03:49
created

Packer::translateToMatrix()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
namespace nstdio\svg\util\transform;
3
4
/**
5
 * Class Packer
6
 *
7
 * @package nstdio\svg\util\transform
8
 * @author  Edgar Asatryan <[email protected]>
9
 */
10
class Packer implements PackerInterface
11
{
12
13
    public function pack(array $data)
14
    {
15
        $count = count($data);
16
        if ($count === 1) {
17
            return $data;
18
        }
19
20
        for ($i = 0; $i < $count; $i++) {
21
            list($first, $transform) = $this->transformAndParams($data, $i);
22
23
            if ($i + 1 >= $count) {
24
                break;
25
            }
26
27
            list($second, $transform2) = $this->transformAndParams($data, $i + 1);
28
29
            if ($transform === $transform2) {
30
                $method = "sum" . ucfirst($transform);
31
32
                $data[$i][$transform] = $this->$method($first, $second);
33
34
                unset($data[$i + 1]);
35
                $data = array_values($data);
36
                $count--;
37
                $i--;
38
            }
39
        }
40
41
        return $data;
42
    }
43
44
    /**
45
     * @param array $data
46
     * @param       $idx
47
     *
48
     * @return array
49
     */
50
    private function transformAndParams(array $data, $idx)
51
    {
52
        $first = $data[$idx];
53
        $transform = array_keys($first)[0];
54
        $first = $first[$transform];
55
56
        return [$first, $transform];
57
    }
58
59
    /**
60
     * @param array $data
61
     *
62
     * @return mixed
63
     */
64
    public function toMatrix(array $data)
65
    {
66
        foreach ($data as $key => $transformParams) {
67
            list($params, $transformation) = $this->transformAndParams($data, $key);
68
            if ($transformation === 'matrix') { // we don't need to convert matrix to matrix
69
                continue;
70
            }
71
72
            $method = $transformation . "ToMatrix";
73
            $matrix = $this->$method($params);
74
75
            unset($data[$key][$transformation]);
76
            $data[$key]['matrix'] = $matrix;
77
        }
78
79
        return $data;
80
    }
81
82
    /**
83
     * @param array $scale
84
     *
85
     * @return array
86
     */
87
    private function scaleToMatrix(array $scale)
88
    {
89
        $sx = $scale[0];
90
        $sy = $scale[1] === null ? $sx : $scale[1];
91
92
        return [$sx, 0, 0, $sy, 0, 0];
93
    }
94
95
    private function rotateToMatrix(array $rotate)
96
    {
97
        $angle = deg2rad($rotate[0]);
98
99
        $cos = cos($angle);
100
        $sin = sin($angle);
101
102
        return [$cos, $sin, -$sin, $cos, 0, 0];
103
    }
104
105
    private function skewXToMatrix(array $skewX)
106
    {
107
        $angle = deg2rad($skewX[0]);
108
109
        return [1, 0, tan($angle), 1, 0, 0];
110
    }
111
112
    private function skewYToMatrix(array $skewY)
113
    {
114
        $angle = deg2rad($skewY[0]);
115
116
        return [1, tan($angle), 0, 1, 0, 0];
117
    }
118
119
    private function translateToMatrix(array $translate)
120
    {
121
        $tx = $translate[0];
122
        $ty = $translate[1] === null ? $tx : $translate[1];
123
124
        return [1, 0, 0, 1, $tx, $ty];
125
    }
126
127
    private function sumSkewX(array $first, array $second)
128
    {
129
        return ['skewX' => $this->sumSkew($first, $second)];
130
    }
131
132
    private function sumSkew(array $first, array $second)
133
    {
134
        return $first[0] + $second[0];
135
    }
136
137
    private function sumSkewY(array $first, array $second)
138
    {
139
        return ['skewY' => $this->sumSkew($first, $second)];
140
    }
141
142
    private function sumTranslate(array $first, array $second)
143
    {
144
        $y = null;
145 View Code Duplication
        if ($first[1] !== null || $second[1] !== null) {
0 ignored issues
show
Duplication introduced by
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...
146
            $y = $first[1] + $second[1];
147
        }
148
149
        return [
150
            $first[0] + $second[0],
151
            $y,
152
        ];
153
    }
154
155
    private function sumScale($first, $second)
156
    {
157
        $firstY = $this->scaleY($first);
158
        $secondY = $this->scaleY($second);
159
160
        $resultXScale = $first[0] * $second[0];
161
        $resultYScale = $firstY * $secondY;
162
163
        return [
164
            $resultXScale,
165
            $resultYScale,
166
        ];
167
    }
168
169
    /**
170
     * @param array $scaleParams
171
     *
172
     * @return mixed
173
     */
174
    private function scaleY(array $scaleParams)
175
    {
176
        return $scaleParams[1] === null ? $scaleParams[0] : $scaleParams[1];
177
    }
178
179
    private function sumRotate(array $first, array $second)
180
    {
181
        $sumRotate = $first[0] + $second[0];
182
183
        $rotateCx = null;
184 View Code Duplication
        if ($first[1] !== null || $second[1] !== null) {
0 ignored issues
show
Duplication introduced by
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...
185
            $rotateCx = ($first[1] + $second[1]) / 2;
186
        }
187
188
        $rotateCy = null;
189 View Code Duplication
        if ($first[2] !== null || $second[2] !== null) {
0 ignored issues
show
Duplication introduced by
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...
190
            $rotateCy = ($first[2] + $second[2]) / 2;
191
        }
192
193
        return [
194
            $sumRotate,
195
            $rotateCx,
196
            $rotateCy,
197
        ];
198
    }
199
200
    private function sumMatrix(array $first, array $second)
201
    {
202
        $first = $this->matrixFromVector($first);
203
        $second = $this->matrixFromVector($second);
204
205
        $result = [];
206
        for ($i = 0; $i < 3; $i++) {
207
            for ($j = 0; $j < 3; $j++) {
208
                $t = 0;
209
                for ($k = 0; $k < 3; $k++) {
210
                    $t += $first[$i][$k] * $second[$k][$j];
211
                }
212
                $result[$i][$j] = $t;
213
            }
214
        }
215
216
        return [
217
            $result[0][0], $result[1][0], $result[0][1],
218
            $result[1][1], $result[0][2], $result[1][2],
219
        ];
220
    }
221
222
    private function matrixFromVector(array $vector)
223
    {
224
        return [
225
            [$vector[0], $vector[2], $vector[4]],
226
            [$vector[1], $vector[3], $vector[5]],
227
            [0, 0, 1],
228
        ];
229
    }
230
}