1 /*
2 * Copyright (C) 2019 Alberto Irurueta Carro (alberto@irurueta.com)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.irurueta.navigation.inertial;
17
18 import com.irurueta.units.Distance;
19 import com.irurueta.units.DistanceConverter;
20 import com.irurueta.units.DistanceUnit;
21
22 import java.io.Serial;
23 import java.io.Serializable;
24 import java.util.Objects;
25
26 /**
27 * Contains radii of curvature of the WGS84 ellipsoid at a given latitude.
28 */
29 public class RadiiOfCurvature implements Serializable, Cloneable {
30
31 /**
32 * Serialization version. This is used to ensure compatibility of deserialization of permanently stored serialized
33 * instances.
34 */
35 @Serial
36 private static final long serialVersionUID = 0L;
37
38 /**
39 * Meridian radius of curvature expressed in meters (m).
40 * This is the radius of curvature for north-south motion.
41 * It is the radius of curvature of a meridian, a cross-section of the ellipsoid
42 * surface in the north-down plane, at the point of interest (a given latitude).
43 * This is the same as the radius of the best-fitting circle to the meridian
44 * ellipse at the point of interest.
45 * The meridian radius of curvature varies with latitude and is smallest at the
46 * equator, where the geocentric radius is largest, and largest at the poles.
47 */
48 private double rn;
49
50 /**
51 * Transverse radius of curvature expressed in meters (m).
52 * This is the radius of curvature for east-west motion.
53 * This is also known as the normal radius of curvature or prime vertical radius
54 * of curvature.
55 * It is the radius of curvature of a cross-section of the ellipsoid surface in
56 * the east-down plane at the point of interest.
57 * This is the vertical plane perpendicular to the meridian plane and is not
58 * the plane of constant latitude.
59 * The transverse radius of curvature varies with latitude and is smallest at the
60 * equator. It is also equal to the length of the normal from a point on the
61 * surface to the polar axis.
62 */
63 private double re;
64
65 /**
66 * Constructor.
67 */
68 public RadiiOfCurvature() {
69 }
70
71 /**
72 * Constructor.
73 *
74 * @param rn meridian radius of curvature expressed in meters (m).
75 * @param re transverse radius of curvature expressed in meters (m).
76 */
77 public RadiiOfCurvature(final double rn, final double re) {
78 setValues(rn, re);
79 }
80
81 /**
82 * Constructor.
83 *
84 * @param rnDistance meridian radius of curvature.
85 * @param reDistance transverse radius of curvature.
86 */
87 public RadiiOfCurvature(final Distance rnDistance, final Distance reDistance) {
88 setValues(rnDistance, reDistance);
89 }
90
91 /**
92 * Constructor.
93 *
94 * @param input instance to copy data from.
95 */
96 public RadiiOfCurvature(final RadiiOfCurvature input) {
97 copyFrom(input);
98 }
99
100 /**
101 * Gets meridian radius of curvature expressed in meters (m).
102 * This is the radius of curvature for north-south motion.
103 * It is the radius of curvature of a meridian, a cross-section of the ellipsoid
104 * surface in the north-down plane, at the point of interest (a given latitude).
105 * This is the same as the radius of the best-fitting circle to the meridian
106 * ellipse at the point of interest.
107 * The meridian radius of curvature varies with latitude and is smallest at the
108 * equator, where the geocentric radius is largest, and largest at the poles.
109 *
110 * @return meridian radius of curvature expressed in meters (m).
111 */
112 public double getRn() {
113 return rn;
114 }
115
116 /**
117 * Sets meridian radius of curvature expressed in meters (m).
118 * This is the radius of curvature for north-south motion.
119 * It is the radius of curvature of a meridian, a cross-section of the ellipsoid
120 * surface in the north-down plane, at the point of interest (a given latitude).
121 * This is the same as the radius of the best-fitting circle to the meridian
122 * ellipse at the point of interest.
123 * The meridian radius of curvature varies with latitude and is smallest at the
124 * equator, where the geocentric radius is largest, and largest at the poles.
125 *
126 * @param rn meridian radius of curvature expressed in meters (m).
127 */
128 public void setRn(final double rn) {
129 this.rn = rn;
130 }
131
132 /**
133 * Gets transverse radius of curvature expressed in meters (m).
134 * This is the radius of curvature for east-wet motion.
135 * This is also known as the normal radius of curvature or prime vertical radius
136 * of curvature.
137 * It is the radius of curvature of a cross-section of the ellipsoid surface in
138 * the east-down plane at the point of interest.
139 * This is the vertical plane perpendicular to the meridian plane and is not
140 * the plane of constant latitude.
141 * The transverse radius of curvature varies with latitude and is smallest at the
142 * equator. It is also equal to the length of the normal from a point on the
143 * surface to the polar axis.
144 *
145 * @return transverse radius of curvature expressed in meters (m).
146 */
147 public double getRe() {
148 return re;
149 }
150
151 /**
152 * Sets transverse radius of curvature expressed in meters (m).
153 * This is the radius of curvature for east-wet motion.
154 * This is also known as the normal radius of curvature or prime vertical radius
155 * of curvature.
156 * It is the radius of curvature of a cross-section of the ellipsoid surface in
157 * the east-down plane at the point of interest.
158 * This is the vertical plane perpendicular to the meridian plane and is not
159 * the plane of constant latitude.
160 * The transverse radius of curvature varies with latitude and is smallest at the
161 * equator. It is also equal to the length of the normal from a point on the
162 * surface to the polar axis.
163 *
164 * @param re transverse radius of curvature expressed in meters (m).
165 */
166 public void setRe(final double re) {
167 this.re = re;
168 }
169
170 /**
171 * Sets radii of curvature.
172 *
173 * @param rn meridian radius of curvature expressed in meters (m).
174 * @param re transverse radius of curvature expressed in meters (m).
175 */
176 public void setValues(final double rn, final double re) {
177 this.rn = rn;
178 this.re = re;
179 }
180
181 /**
182 * Gets meridian radius of curvature.
183 * This is the radius of curvature for north-south motion.
184 * It is the radius of curvature of a meridian, a cross-section of the ellipsoid
185 * surface in the north-down plane, at the point of interest (a given latitude).
186 * This is the same as the radius of the best-fitting circle to the meridian
187 * ellipse at the point of interest.
188 * The meridian radius of curvature varies with latitude and is smallest at the
189 * equator, where the geocentric radius is largest, and largest at the poles.
190 *
191 * @param result instance where meridian radius of curvature will be stored.
192 */
193 public void getRnDistance(final Distance result) {
194 result.setValue(rn);
195 result.setUnit(DistanceUnit.METER);
196 }
197
198 /**
199 * Gets meridian radius of curvature.
200 * This is the radius of curvature for north-south motion.
201 * It is the radius of curvature of a meridian, a cross-section of the ellipsoid
202 * surface in the north-down plane, at the point of interest (a given latitude).
203 * This is the same as the radius of the best-fitting circle to the meridian
204 * ellipse at the point of interest.
205 * The meridian radius of curvature varies with latitude and is smallest at the
206 * equator, where the geocentric radius is largest, and largest at the poles.
207 *
208 * @return meridian radius of curvature.
209 */
210 public Distance getRnDistance() {
211 return new Distance(rn, DistanceUnit.METER);
212 }
213
214 /**
215 * Sets meridian radius of curvature.
216 * This is the radius of curvature for north-south motion.
217 * It is the radius of curvature of a meridian, a cross-section of the ellipsoid
218 * surface in the north-down plane, at the point of interest (a given latitude).
219 * This is the same as the radius of the best-fitting circle to the meridian
220 * ellipse at the point of interest.
221 * The meridian radius of curvature varies with latitude and is smallest at the
222 * equator, where the geocentric radius is largest, and largest at the poles.
223 *
224 * @param rnDistance meridian radius of curvature to be set.
225 */
226 public void setRnDistance(final Distance rnDistance) {
227 rn = DistanceConverter.convert(rnDistance.getValue().doubleValue(), rnDistance.getUnit(), DistanceUnit.METER);
228 }
229
230 /**
231 * Gets transverse radius or curvature.
232 * This is the radius of curvature for east-wet motion.
233 * This is also known as the normal radius of curvature or prime vertical radius
234 * of curvature.
235 * It is the radius of curvature of a cross-section of the ellipsoid surface in
236 * the east-down plane at the point of interest.
237 * This is the vertical plane perpendicular to the meridian plane and is not
238 * the plane of constant latitude.
239 * The transverse radius of curvature varies with latitude and is smallest at the
240 * equator. It is also equal to the length of the normal from a point on the
241 * surface to the polar axis.
242 *
243 * @param result instance where transverse radius of curvature will be stored.
244 */
245 public void getReDistance(final Distance result) {
246 result.setValue(re);
247 result.setUnit(DistanceUnit.METER);
248 }
249
250 /**
251 * Gets transverse radius of curvature.
252 * This is the radius of curvature for east-wet motion.
253 * This is also known as the normal radius of curvature or prime vertical radius
254 * of curvature.
255 * It is the radius of curvature of a cross-section of the ellipsoid surface in
256 * the east-down plane at the point of interest.
257 * This is the vertical plane perpendicular to the meridian plane and is not
258 * the plane of constant latitude.
259 * The transverse radius of curvature varies with latitude and is smallest at the
260 * equator. It is also equal to the length of the normal from a point on the
261 * surface to the polar axis.
262 *
263 * @return transverse radius of curvature.
264 */
265 public Distance getReDistance() {
266 return new Distance(re, DistanceUnit.METER);
267 }
268
269 /**
270 * Sets transverse radius of curvature.
271 * This is the radius of curvature for east-wet motion.
272 * This is also known as the normal radius of curvature or prime vertical radius
273 * of curvature.
274 * It is the radius of curvature of a cross-section of the ellipsoid surface in
275 * the east-down plane at the point of interest.
276 * This is the vertical plane perpendicular to the meridian plane and is not
277 * the plane of constant latitude.
278 * The transverse radius of curvature varies with latitude and is smallest at the
279 * equator. It is also equal to the length of the normal from a point on the
280 * surface to the polar axis.
281 *
282 * @param reDistance transverse radius of curvature to be set.
283 */
284 public void setReDistance(final Distance reDistance) {
285 re = DistanceConverter.convert(reDistance.getValue().doubleValue(), reDistance.getUnit(), DistanceUnit.METER);
286 }
287
288 /**
289 * Sets radii of curvature.
290 *
291 * @param rnDistance meridian radius of curvature.
292 * @param reDistance transverse radius of curvature.
293 */
294 public void setValues(final Distance rnDistance, final Distance reDistance) {
295 setRnDistance(rnDistance);
296 setReDistance(reDistance);
297 }
298
299 /**
300 * Copies this instance data into provided instance.
301 *
302 * @param output destination instance where data will be copied to.
303 */
304 public void copyTo(final RadiiOfCurvature output) {
305 output.rn = rn;
306 output.re = re;
307 }
308
309 /**
310 * Copies data of provided instance into this instance.
311 *
312 * @param input instance to copy data from.
313 */
314 public void copyFrom(final RadiiOfCurvature input) {
315 rn = input.rn;
316 re = input.re;
317 }
318
319 /**
320 * Computes and returns hash code for this instance. Hash codes are almost unique
321 * values that are useful for fast classification and storage of objects in collections.
322 *
323 * @return Hash code.
324 */
325 @Override
326 public int hashCode() {
327 return Objects.hash(rn, re);
328 }
329
330 /**
331 * Checks if provided object is a RadiiOfCurvature instance having exactly the same
332 * contents as this instance.
333 *
334 * @param obj object to be compared.
335 * @return true if both objects are considered to be equal, false otherwise.
336 */
337 @Override
338 public boolean equals(final Object obj) {
339 if (obj == null) {
340 return false;
341 }
342 if (obj == this) {
343 return true;
344 }
345 if (!(obj instanceof RadiiOfCurvature)) {
346 return false;
347 }
348
349 //noinspection PatternVariableCanBeUsed
350 final var other = (RadiiOfCurvature) obj;
351 return equals(other);
352 }
353
354 /**
355 * Checks if provided instance has exactly the same contents as this instance.
356 *
357 * @param other instance to be compared.
358 * @return true if both instances are considered to be equal, false otherwise.
359 */
360 public boolean equals(final RadiiOfCurvature other) {
361 return equals(other, 0.0);
362 }
363
364 /**
365 * Checks if provided instance has contents similar to this instance up to provided
366 * threshold value.
367 *
368 * @param other instance to be compared.
369 * @param threshold maximum allowed difference between radii values.
370 * @return true if both instances are considered to be equal (up to provided
371 * threshold), false otherwise.
372 */
373 public boolean equals(final RadiiOfCurvature other, final double threshold) {
374 if (other == null) {
375 return false;
376 }
377
378 return Math.abs(rn - other.rn) <= threshold && Math.abs(re - other.re) <= threshold;
379 }
380
381 /**
382 * Makes a copy of this instance.
383 *
384 * @return a copy of this instance.
385 * @throws CloneNotSupportedException if clone fails for some reason.
386 */
387 @Override
388 protected Object clone() throws CloneNotSupportedException {
389 final var result = (RadiiOfCurvature) super.clone();
390 copyTo(result);
391 return result;
392 }
393 }