Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
20 / 20 |
|
100.00% |
12 / 12 |
CRAP | |
100.00% |
1 / 1 |
Sphere | |
100.00% |
20 / 20 |
|
100.00% |
12 / 12 |
12 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
distance2PointsOnSphere | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
byRadius | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
byVolume | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRadiusByVolume | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
bySurface | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRadiusBySurface | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getVolume | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getVolumeByRadius | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRadius | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getSurface | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getSurfaceByRadius | |
100.00% |
1 / 1 |
|
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 | */ |
13 | declare(strict_types=1); |
14 | |
15 | namespace 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 | */ |
25 | final 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 | } |