Completed
Push — master ( ba922a...9c7654 )
by Milos
03:24
created

IntervalFunction::evaluate()   B

Complexity

Conditions 6
Paths 12

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 26
rs 8.439
cc 6
eloc 15
nc 12
nop 1
1
<?php
2
3
namespace Cgi\Calc\Func;
4
5
use Cgi\Calc\FunctionInterface;
6
use Cgi\Calc\Point\Path;
7
use Cgi\Calc\Point;
8
9
class IntervalFunction implements FunctionInterface
10
{
11
    /** @var Path */
12
    private $path;
13
14
    /** @var bool */
15
    private $extrapolate;
16
17
    /**
18
     * @param Path $path
19
     * @param bool $extrapolate
20
     */
21
    public function __construct(Path $path, $extrapolate = true)
22
    {
23
        if (false === $path->isMonotonouslyIncreasingX()) {
24
            throw new \InvalidArgumentException('Path must be monotony increasing by X');
25
        }
26
27
        $this->path = $path;
28
        $this->extrapolate = $extrapolate ? true : false;
29
    }
30
31
    /**
32
     * @param float $x
33
     *
34
     * @return float|null
35
     */
36
    public function evaluate($x)
37
    {
38
        $nowPoint = new Point($x, 0);
39
40
        $containingLine = null;
41
        foreach ($this->path->getLineIterator() as $line) {
42
            if ($nowPoint->betweenX($line->getStartPoint(), $line->getEndPoint())) {
43
                $containingLine = $line;
44
                break;
45
            }
46
        }
47
48
        if (null === $containingLine) {
49
            if (false === $this->extrapolate) {
50
                return null;
51
            }
52
53
            if ($this->path->firstPoint()->getX() > $x) {
54
                $containingLine = $this->path->firstLine();
55
            }  else {
56
                $containingLine = $this->path->lastLine();
57
            }
58
        }
59
60
        return $containingLine->getLinearFunction()->evaluate($x);
61
    }
62
}
63