View Javadoc
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 }