Passed
Push — master ( 8f5e6a...061d3e )
by Felipe
03:26
created

Contour   C

Complexity

Total Complexity 64

Size/Duplication

Total Lines 381
Duplicated Lines 15.75 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 60
loc 381
rs 5.8364
c 0
b 0
f 0
wmc 64
lcom 1
cbo 1

12 Methods

Rating   Name   Duplication   Size   Complexity  
C __construct() 0 36 7
A SetInvert() 0 4 1
A getMinMaxVal() 0 15 4
A resetEdgeMatrices() 0 10 4
A isobarHCrossing() 16 16 3
A isobarVCrossing() 16 16 3
B determineIsobarEdgeCrossings() 6 19 5
B getCrossingCoord() 10 27 5
B adjustDataPointValues() 0 14 5
A UseHighContrastColor() 0 5 1
B CalculateColors() 0 24 6
D getIsobars() 12 84 20

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Contour often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Contour, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace Amenadiel\JpGraph\Plot;
3
4
use Amenadiel\JpGraph\Image;
5
6
/*=======================================================================
7
// File:        JPGRAPH_CONTOUR.PHP
8
// Description: Contour plot
9
// Created:     2009-03-08
10
// Ver:         $Id: jpgraph_contour.php 1870 2009-09-29 04:24:18Z ljp $
11
//
12
// Copyright (c) Asial Corporation. All rights reserved.
13
//========================================================================
14
 */
15
16
define('HORIZ_EDGE', 0);
17
define('VERT_EDGE', 1);
18
19
/**
20
 * This class encapsulates the core contour plot algorithm. It will find the path
21
 * of the specified isobars in the data matrix specified. It is assumed that the
22
 * data matrix models an equspaced X-Y mesh of datavalues corresponding to the Z
23
 * values.
24
 *
25
 */
26
class Contour
27
{
28
    private $dataPoints   = array();
29
    private $nbrCols      = 0;
30
    private $nbrRows      = 0;
31
    private $horizEdges   = array();
0 ignored issues
show
Unused Code introduced by
The property $horizEdges is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
32
    private $vertEdges   = array();
0 ignored issues
show
Unused Code introduced by
The property $vertEdges is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
33
    private $isobarValues = array();
34
    private $stack        = null;
0 ignored issues
show
Unused Code introduced by
The property $stack is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
35
    private $isobarCoord  = array();
36
    private $nbrIsobars   = 10;
37
    private $isobarColors   = array();
38
    private $invert       = true;
39
    private $highcontrast = false;
40
    private $highcontrastbw = false;
41
42
    /**
43
     * Create a new contour level "algorithm machine".
44
     * @param $aMatrix    The values to find the contour from
45
     * @param $aIsobars Mixed. If integer it determines the number of isobars to be used. The levels are determined
46
     * automatically as equdistance between the min and max value of the matrice.
47
     * If $aIsobars is an array then this is interpretated as an array of values to be used as isobars in the
48
     * contour plot.
49
     * @return an instance of the contour algorithm
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
50
     */
51
    public function __construct($aMatrix, $aIsobars = 10, $aColors = null)
52
    {
53
        $this->nbrRows    = count($aMatrix);
54
        $this->nbrCols    = count($aMatrix[0]);
55
        $this->dataPoints = $aMatrix;
56
57
        if (is_array($aIsobars)) {
58
            // use the isobar values supplied
59
            $this->nbrIsobars   = count($aIsobars);
60
            $this->isobarValues = $aIsobars;
61
        } else {
62
            // Determine the isobar values automatically
63
            $this->nbrIsobars = $aIsobars;
64
            list($min, $max)  = $this->getMinMaxVal();
65
            $stepSize         = ($max - $min) / $aIsobars;
66
            $isobar           = $min + $stepSize / 2;
67
            for ($i = 0; $i < $aIsobars; $i++) {
68
                $this->isobarValues[$i] = $isobar;
69
                $isobar += $stepSize;
70
            }
71
        }
72
73
        if ($aColors !== null && count($aColors) > 0) {
74
            if (!is_array($aColors)) {
75
                Util\JpGraphError::RaiseL(28001);
76
                //'Third argument to Contour must be an array of colors.'
77
            }
78
79
            if (count($aColors) != count($this->isobarValues)) {
80
                Util\JpGraphError::RaiseL(28002);
81
                //'Number of colors must equal the number of isobar lines specified';
82
            }
83
84
            $this->isobarColors = $aColors;
85
        }
86
    }
87
88
    /**
89
     * Flip the plot around the Y-coordinate. This has the same affect as flipping the input
90
     * data matrice
91
     *
92
     * @param $aFlg If true the the vertice in input data matrice position (0,0) corresponds to the top left
93
     * corner of teh plot otherwise it will correspond to the bottom left corner (a horizontal flip)
94
     */
95
    public function SetInvert($aFlg = true)
96
    {
97
        $this->invert = $aFlg;
98
    }
99
100
    /**
101
     * Find the min and max values in the data matrice
102
     *
103
     * @return array(min_value,max_value)
0 ignored issues
show
Documentation introduced by
The doc-type array(min_value,max_value) could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
104
     */
105
    public function getMinMaxVal()
106
    {
107
        $min = $this->dataPoints[0][0];
108
        $max = $this->dataPoints[0][0];
109
        for ($i = 0; $i < $this->nbrRows; $i++) {
110
            if (($mi = min($this->dataPoints[$i])) < $min) {
111
                $min = $mi;
112
            }
113
114
            if (($ma = max($this->dataPoints[$i])) > $max) {
115
                $max = $ma;
116
            }
117
        }
118
        return array($min, $max);
119
    }
120
121
    /**
122
     * Reset the two matrices that keeps track on where the isobars crosses the
123
     * horizontal and vertical edges
124
     */
125
    public function resetEdgeMatrices()
126
    {
127
        for ($k = 0; $k < 2; $k++) {
128
            for ($i = 0; $i <= $this->nbrRows; $i++) {
129
                for ($j = 0; $j <= $this->nbrCols; $j++) {
130
                    $this->edges[$k][$i][$j] = false;
0 ignored issues
show
Bug introduced by
The property edges does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
131
                }
132
            }
133
        }
134
    }
135
136
    /**
137
     * Determine if the specified isobar crosses the horizontal edge specified by its row and column
138
     *
139
     * @param $aRow Row index of edge to be checked
140
     * @param $aCol Col index of edge to be checked
141
     * @param $aIsobar Isobar value
142
     * @return true if the isobar is crossing this edge
143
     */
144 View Code Duplication
    public function isobarHCrossing($aRow, $aCol, $aIsobar)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
145
    {
146
        if ($aCol >= $this->nbrCols - 1) {
147
            Util\JpGraphError::RaiseL(28003, $aCol);
148
            //'ContourPlot Internal Error: isobarHCrossing: Coloumn index too large (%d)'
149
        }
150
        if ($aRow >= $this->nbrRows) {
151
            Util\JpGraphError::RaiseL(28004, $aRow);
152
            //'ContourPlot Internal Error: isobarHCrossing: Row index too large (%d)'
153
        }
154
155
        $v1 = $this->dataPoints[$aRow][$aCol];
156
        $v2 = $this->dataPoints[$aRow][$aCol + 1];
157
158
        return ($aIsobar - $v1) * ($aIsobar - $v2) < 0;
159
    }
160
161
    /**
162
     * Determine if the specified isobar crosses the vertical edge specified by its row and column
163
     *
164
     * @param $aRow Row index of edge to be checked
165
     * @param $aCol Col index of edge to be checked
166
     * @param $aIsobar Isobar value
167
     * @return true if the isobar is crossing this edge
168
     */
169 View Code Duplication
    public function isobarVCrossing($aRow, $aCol, $aIsobar)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
170
    {
171
        if ($aRow >= $this->nbrRows - 1) {
172
            Util\JpGraphError::RaiseL(28005, $aRow);
173
            //'isobarVCrossing: Row index too large
174
        }
175
        if ($aCol >= $this->nbrCols) {
176
            Util\JpGraphError::RaiseL(28006, $aCol);
177
            //'isobarVCrossing: Col index too large
178
        }
179
180
        $v1 = $this->dataPoints[$aRow][$aCol];
181
        $v2 = $this->dataPoints[$aRow + 1][$aCol];
182
183
        return ($aIsobar - $v1) * ($aIsobar - $v2) < 0;
184
    }
185
186
    /**
187
     * Determine all edges, horizontal and vertical that the specified isobar crosses. The crossings
188
     * are recorded in the two edge matrices.
189
     *
190
     * @param $aIsobar The value of the isobar to be checked
191
     */
192
    public function determineIsobarEdgeCrossings($aIsobar)
193
    {
194
        $ib = $this->isobarValues[$aIsobar];
195
196
        for ($i = 0; $i < $this->nbrRows - 1; $i++) {
197
            for ($j = 0; $j < $this->nbrCols - 1; $j++) {
198
                $this->edges[HORIZ_EDGE][$i][$j] = $this->isobarHCrossing($i, $j, $ib);
199
                $this->edges[VERT_EDGE][$i][$j]  = $this->isobarVCrossing($i, $j, $ib);
200
            }
201
        }
202
203
        // We now have the bottom and rightmost edges unsearched
204 View Code Duplication
        for ($i = 0; $i < $this->nbrRows - 1; $i++) {
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...
205
            $this->edges[VERT_EDGE][$i][$j] = $this->isobarVCrossing($i, $this->nbrCols - 1, $ib);
0 ignored issues
show
Bug introduced by
The variable $j does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
206
        }
207 View Code Duplication
        for ($j = 0; $j < $this->nbrCols - 1; $j++) {
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...
208
            $this->edges[HORIZ_EDGE][$i][$j] = $this->isobarHCrossing($this->nbrRows - 1, $j, $ib);
209
        }
210
    }
211
212
    /**
213
     * Return the normalized coordinates for the crossing of the specified edge with the specified
214
     * isobar- The crossing is simpy detrmined with a linear interpolation between the two vertices
215
     * on each side of the edge and the value of the isobar
216
     *
217
     * @param $aRow Row of edge
218
     * @param $aCol Column of edge
219
     * @param $aEdgeDir Determine if this is a horizontal or vertical edge
220
     * @param $ib The isobar value
221
     * @return unknown_type
222
     */
223
    public function getCrossingCoord($aRow, $aCol, $aEdgeDir, $aIsobarVal)
224
    {
225
226
        // In order to avoid numerical problem when two vertices are very close
227
        // we have to check and avoid dividing by close to zero denumerator.
228
        if ($aEdgeDir == HORIZ_EDGE) {
229
            $d = abs($this->dataPoints[$aRow][$aCol] - $this->dataPoints[$aRow][$aCol + 1]);
230 View Code Duplication
            if ($d > 0.001) {
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...
231
                $xcoord = $aCol + abs($aIsobarVal - $this->dataPoints[$aRow][$aCol]) / $d;
232
            } else {
233
                $xcoord = $aCol;
234
            }
235
            $ycoord = $aRow;
236
        } else {
237
            $d = abs($this->dataPoints[$aRow][$aCol] - $this->dataPoints[$aRow + 1][$aCol]);
238 View Code Duplication
            if ($d > 0.001) {
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...
239
                $ycoord = $aRow + abs($aIsobarVal - $this->dataPoints[$aRow][$aCol]) / $d;
240
            } else {
241
                $ycoord = $aRow;
242
            }
243
            $xcoord = $aCol;
244
        }
245
        if ($this->invert) {
246
            $ycoord = $this->nbrRows - 1 - $ycoord;
247
        }
248
        return array($xcoord, $ycoord);
249
    }
250
251
    /**
252
     * In order to avoid all kinds of unpleasent extra checks and complex boundary
253
     * controls for the degenerated case where the contour levels exactly crosses
254
     * one of the vertices we add a very small delta (0.1%) to the data point value.
255
     * This has no visible affect but it makes the code sooooo much cleaner.
256
     *
257
     */
258
    public function adjustDataPointValues()
259
    {
260
        $ni = count($this->isobarValues);
261
        for ($k = 0; $k < $ni; $k++) {
262
            $ib = $this->isobarValues[$k];
263
            for ($row = 0; $row < $this->nbrRows - 1; ++$row) {
264
                for ($col = 0; $col < $this->nbrCols - 1; ++$col) {
265
                    if (abs($this->dataPoints[$row][$col] - $ib) < 0.0001) {
266
                        $this->dataPoints[$row][$col] += $this->dataPoints[$row][$col] * 0.001;
267
                    }
268
                }
269
            }
270
        }
271
    }
272
273
    /**
274
     * @param $aFlg
275
     * @param $aBW
276
     * @return unknown_type
277
     */
278
    public function UseHighContrastColor($aFlg = true, $aBW = false)
279
    {
280
        $this->highcontrast   = $aFlg;
281
        $this->highcontrastbw = $aBW;
282
    }
283
284
    /**
285
     * Calculate suitable colors for each defined isobar
286
     *
287
     */
288
    public function CalculateColors()
289
    {
290
        if ($this->highcontrast) {
291
            if ($this->highcontrastbw) {
292
                for ($ib = 0; $ib < $this->nbrIsobars; $ib++) {
293
                    $this->isobarColors[$ib] = 'black';
294
                }
295
            } else {
296
                // Use only blue/red scale
297
                $step = round(255 / ($this->nbrIsobars - 1));
298
                for ($ib = 0; $ib < $this->nbrIsobars; $ib++) {
299
                    $this->isobarColors[$ib] = array($ib * $step, 50, 255 - $ib * $step);
300
                }
301
            }
302
        } else {
303
            $n    = $this->nbrIsobars;
0 ignored issues
show
Unused Code introduced by
$n is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
304
            $v    = 0;
305
            $step = 1 / ($this->nbrIsobars - 1);
306
            for ($ib = 0; $ib < $this->nbrIsobars; $ib++) {
307
                $this->isobarColors[$ib] = Image\RGB::GetSpectrum($v);
308
                $v += $step;
309
            }
310
        }
311
    }
312
313
    /**
314
     * This is where the main work is done. For each isobar the crossing of the edges are determined
315
     * and then each cell is analyzed to find the 0, 2 or 4 crossings. Then the normalized coordinate
316
     * for the crossings are determined and pushed on to the isobar stack. When the method is finished
317
     * the $isobarCoord will hold one arrayfor each isobar where all the line segments that makes
318
     * up the contour plot are stored.
319
     *
320
     * @return array( $isobarCoord, $isobarValues, $isobarColors )
0 ignored issues
show
Documentation introduced by
The doc-type array( could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
321
     */
322
    public function getIsobars()
323
    {
324
        $this->adjustDataPointValues();
325
326
        for ($isobar = 0; $isobar < $this->nbrIsobars; $isobar++) {
327
            $ib = $this->isobarValues[$isobar];
328
            $this->resetEdgeMatrices();
329
            $this->determineIsobarEdgeCrossings($isobar);
330
            $this->isobarCoord[$isobar] = array();
331
332
            $ncoord = 0;
333
334
            for ($row = 0; $row < $this->nbrRows - 1; ++$row) {
335
                for ($col = 0; $col < $this->nbrCols - 1; ++$col) {
336
337
                    // Find out how many crossings around the edges
338
                    $n = 0;
339 View Code Duplication
                    if ($this->edges[HORIZ_EDGE][$row][$col]) {
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...
340
                        $neigh[$n++] = array($row, $col, HORIZ_EDGE);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$neigh was never initialized. Although not strictly required by PHP, it is generally a good practice to add $neigh = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
341
                    }
342
343 View Code Duplication
                    if ($this->edges[HORIZ_EDGE][$row + 1][$col]) {
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...
344
                        $neigh[$n++] = array($row + 1, $col, HORIZ_EDGE);
0 ignored issues
show
Bug introduced by
The variable $neigh does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
345
                    }
346
347 View Code Duplication
                    if ($this->edges[VERT_EDGE][$row][$col]) {
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...
348
                        $neigh[$n++] = array($row, $col, VERT_EDGE);
349
                    }
350
351 View Code Duplication
                    if ($this->edges[VERT_EDGE][$row][$col + 1]) {
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...
352
                        $neigh[$n++] = array($row, $col + 1, VERT_EDGE);
353
                    }
354
355
                    if ($n == 2) {
356
                        $n1                                    = 0;
357
                        $n2                                    = 1;
358
                        $this->isobarCoord[$isobar][$ncoord++] = array(
359
                            $this->getCrossingCoord($neigh[$n1][0], $neigh[$n1][1], $neigh[$n1][2], $ib),
360
                            $this->getCrossingCoord($neigh[$n2][0], $neigh[$n2][1], $neigh[$n2][2], $ib));
361
                    } elseif ($n == 4) {
362
                        // We must determine how to connect the edges either northwest->southeast or
363
                        // northeast->southwest. We do that by calculating the imaginary middle value of
364
                        // the cell by averaging the for corners. This will compared with the value of the
365
                        // top left corner will help determine the orientation of the ridge/creek
366
                        $midval = ($this->dataPoints[$row][$col] + $this->dataPoints[$row][$col + 1] + $this->dataPoints[$row + 1][$col] + $this->dataPoints[$row + 1][$col + 1]) / 4;
367
                        $v      = $this->dataPoints[$row][$col];
368
                        if ($midval == $ib) {
369
                            // Orientation "+"
370
                            $n1 = 0;
371
                            $n2 = 1;
372
                            $n3 = 2;
373
                            $n4 = 3;
374
                        } elseif (($midval > $ib && $v > $ib) || ($midval < $ib && $v < $ib)) {
375
                            // Orientation of ridge/valley = "\"
376
                            $n1 = 0;
377
                            $n2 = 3;
378
                            $n3 = 2;
379
                            $n4 = 1;
380
                        } elseif (($midval > $ib && $v < $ib) || ($midval < $ib && $v > $ib)) {
381
                            // Orientation of ridge/valley = "/"
382
                            $n1 = 0;
383
                            $n2 = 2;
384
                            $n3 = 3;
385
                            $n4 = 1;
386
                        }
387
388
                        $this->isobarCoord[$isobar][$ncoord++] = array(
389
                            $this->getCrossingCoord($neigh[$n1][0], $neigh[$n1][1], $neigh[$n1][2], $ib),
0 ignored issues
show
Bug introduced by
The variable $n1 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
390
                            $this->getCrossingCoord($neigh[$n2][0], $neigh[$n2][1], $neigh[$n2][2], $ib));
0 ignored issues
show
Bug introduced by
The variable $n2 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
391
392
                        $this->isobarCoord[$isobar][$ncoord++] = array(
393
                            $this->getCrossingCoord($neigh[$n3][0], $neigh[$n3][1], $neigh[$n3][2], $ib),
0 ignored issues
show
Bug introduced by
The variable $n3 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
394
                            $this->getCrossingCoord($neigh[$n4][0], $neigh[$n4][1], $neigh[$n4][2], $ib));
0 ignored issues
show
Bug introduced by
The variable $n4 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
395
                    }
396
                }
397
            }
398
        }
399
400
        if (count($this->isobarColors) == 0) {
401
            // No manually specified colors. Calculate them automatically.
402
            $this->CalculateColors();
403
        }
404
        return array($this->isobarCoord, $this->isobarValues, $this->isobarColors);
405
    }
406
}
407
408
// EOF
409