Completed
Pull Request — dev (#33)
by Jordan
01:55
created

CartesianCoordinate::numberOfDimensions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Samsara\Fermat\Values;
4
5
use Samsara\Exceptions\UsageError\IntegrityConstraint;
6
use Samsara\Fermat\Numbers;
7
use Samsara\Fermat\Types\Tuple;
8
use Samsara\Fermat\Types\Base\CoordinateInterface;
9
10
class CartesianCoordinate extends Tuple implements CoordinateInterface
11
{
12
13
    /**
14
     * @var array
15
     */
16
    protected $axes;
17
18 1
    public function __construct(array $data)
19
    {
20 1
        $zeroIndexedData = [];
21
22 1
        foreach ($data as $axis => $value) {
23 1
            $this->axes[$axis] = count($zeroIndexedData);
24 1
            $zeroIndexedData[] = $value;
25
        }
26
27 1
        parent::__construct($zeroIndexedData);
28 1
    }
29
30
    public function getAxis($axis): ImmutableNumber
31
    {
32
        return $this->get($this->axes[$axis]);
33
    }
34
35
    public function numberOfDimensions(): int
36
    {
37
        return $this->size();
38
    }
39
40
    public function axisValues(): array
41
    {
42
        return $this->all();
43
    }
44
45
    public function distanceTo(CoordinateInterface $coordinate): ImmutableNumber
46
    {
47
        if (!($coordinate instanceof CartesianCoordinate)) {
48
            throw new IntegrityConstraint(
49
                'Must be the same coordinate system',
50
                'Only attempt to get distance between coordinates that use the same coordinate system',
51
                'Distance cannot be calculated between coordinates that use different coordinate systems because the properties necessary to convert them cannot be assumed'
52
            );
53
        }
54
55
        if ($this->size() != $coordinate->size()) {
56
            throw new IntegrityConstraint(
57
                'Must have same dimensionality',
58
                'Check dimensionality of both coordinates before getting distance',
59
                'Coordinates must share the same number of axes in order for a distance to be calculated'
60
            );
61
        }
62
63
        /** @var ImmutableNumber $n */
64
        $n = Numbers::makeZero();
65
66
        foreach ($this->all() as $index => $value) {
67
            $n = $n->add($coordinate->get($index)->subtract($value)->pow(2));
68
        }
69
70
        $n = $n->sqrt();
71
72
        return $n;
73
    }
74
75
}