Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
12 / 12
CRAP
100.00% covered (success)
100.00%
1 / 1
Sphere
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
12 / 12
12
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 distance2PointsOnSphere
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 byRadius
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 byVolume
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRadiusByVolume
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 bySurface
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRadiusBySurface
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getVolume
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getVolumeByRadius
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRadius
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSurface
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSurfaceByRadius
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS\Math\Geometry\Shape\D3
8 * @copyright Dennis Eichhorn
9 * @license   OMS License 2.0
10 * @version   1.0.0
11 * @link      https://jingga.app
12 */
13declare(strict_types=1);
14
15namespace phpOMS\Math\Geometry\Shape\D3;
16
17/**
18 * Sphere shape.
19 *
20 * @package phpOMS\Math\Geometry\Shape\D3
21 * @license OMS License 2.0
22 * @link    https://jingga.app
23 * @since   1.0.0
24 */
25final class Sphere implements D3ShapeInterface
26{
27    /**
28     * Radius.
29     *
30     * @var float
31     * @since 1.0.0
32     */
33    private float $radius = 0.0;
34
35    /**
36     * Constructor.
37     *
38     * @param float $radius Sphere radius
39     *
40     * @since 1.0.0
41     */
42    public function __construct(float $radius)
43    {
44        $this->radius = $radius;
45    }
46
47    /**
48     * Calculating the distance between two points on a sphere
49     *
50     * @param float $latStart  Latitude of start point in deg
51     * @param float $longStart Longitude of start point in deg
52     * @param float $latEnd    Latitude of target point in deg
53     * @param float $longEnd   Longitude of target point in deg
54     * @param float $radius    Sphere radius (6371000 = earth)
55     *
56     * @return float Distance between points in meter
57     *
58     * @since 1.0.0
59     */
60    public static function distance2PointsOnSphere(float $latStart, float $longStart, float $latEnd, float $longEnd, float $radius = 6371000.0) : float
61    {
62        $latFrom = \deg2rad($latStart);
63        $lonFrom = \deg2rad($longStart);
64        $latTo   = \deg2rad($latEnd);
65        $lonTo   = \deg2rad($longEnd);
66
67        //$latDelta = $latTo - $latFrom;
68        $lonDelta = $lonTo - $lonFrom;
69
70        $a = \pow(\cos($latTo) * \sin($lonDelta), 2) + \pow(\cos($latFrom) * \sin($latTo) - \sin($latFrom) * \cos($latTo) * \cos($lonDelta), 2);
71        $b = \sin($latFrom) * \sin($latTo) + \cos($latFrom) * \cos($latTo) * \cos($lonDelta);
72
73        $angle = \atan2(\sqrt($a), $b);
74        // Approximation (very good for short distances)
75        // $angle = 2 * asin(\sqrt(\pow(\sin($latDelta / 2), 2) + \cos($latFrom) * \cos($latTo) * \pow(\sin($lonDelta / 2), 2)));
76
77        return $angle * $radius;
78    }
79
80    /**
81     * Create sphere by radius
82     *
83     * @param float $r Radius
84     *
85     * @return Sphere
86     *
87     * @since 1.0.0
88     */
89    public static function byRadius(float $r) : self
90    {
91        return new self($r);
92    }
93
94    /**
95     * Create sphere by volume
96     *
97     * @param float $v Sphere volume
98     *
99     * @return Sphere
100     *
101     * @since 1.0.0
102     */
103    public static function byVolume(float $v) : self
104    {
105        return new self(self::getRadiusByVolume($v));
106    }
107
108    /**
109     * Radius
110     *
111     * @param float $v Volume
112     *
113     * @return float
114     *
115     * @since 1.0.0
116     */
117    public static function getRadiusByVolume(float $v) : float
118    {
119        return \pow($v * 3 / (4 * \M_PI), 1 / 3);
120    }
121
122    /**
123     * Create sphere by surface
124     *
125     * @param float $s Sphere surface
126     *
127     * @return Sphere
128     *
129     * @since 1.0.0
130     */
131    public static function bySurface(float $s) : self
132    {
133        return new self(self::getRadiusBySurface($s));
134    }
135
136    /**
137     * Get radius by sphere
138     *
139     * @param float $S Surface
140     *
141     * @return float
142     *
143     * @since  1.0.0
144     *
145     * @SuppressWarnings(PHPMD.CamelCaseVariableName)
146     * @SuppressWarnings(PHPMD.CamelCaseParameterName)
147     */
148    public static function getRadiusBySurface(float $S) : float
149    {
150        return \sqrt($S / (4 * \M_PI));
151    }
152
153    /**
154     * Get volume
155     *
156     * @return float Sphere volume
157     *
158     * @since 1.0.0
159     */
160    public function getVolume() : float
161    {
162        return self::getVolumeByRadius($this->radius);
163    }
164
165    /**
166     * Get sphere volume by radius
167     *
168     * @param float $r Radius
169     *
170     * @return float
171     *
172     * @since 1.0.0
173     */
174    public static function getVolumeByRadius(float $r) : float
175    {
176        return 4 / 3 * \M_PI * $r ** 3;
177    }
178
179    /**
180     * Get radius
181     *
182     * @return float Sphere radius
183     *
184     * @since 1.0.0
185     */
186    public function getRadius() : float
187    {
188        return $this->radius;
189    }
190
191    /**
192     * Get surface
193     *
194     * @return float Sphere surface
195     *
196     * @since 1.0.0
197     */
198    public function getSurface() : float
199    {
200        return self::getSurfaceByRadius($this->radius);
201    }
202
203    /**
204     * Surface area
205     *
206     * @param float $r Radius
207     *
208     * @return float
209     *
210     * @since 1.0.0
211     */
212    public static function getSurfaceByRadius(float $r) : float
213    {
214        return 4 * \M_PI * $r ** 2;
215    }
216}