org.orekit.bodies.GeodeticPoint Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of orekit Show documentation
Show all versions of orekit Show documentation
OREKIT (ORbits Extrapolation KIT) is a low level space dynamics library.
It provides basic elements (orbits, dates, attitude, frames ...) and
various algorithms to handle them (conversions, analytical and numerical
propagation, pointing ...).
/* Copyright 2002-2022 CS GROUP
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.bodies;
import java.io.Serializable;
import java.text.NumberFormat;
import org.hipparchus.geometry.euclidean.threed.Vector3D;
import org.hipparchus.util.CompositeFormat;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.MathUtils;
import org.hipparchus.util.SinCos;
/** Point location relative to a 2D body surface.
* Instance of this class are guaranteed to be immutable.
* @see BodyShape
* @see FieldGeodeticPoint
* @author Luc Maisonobe
*/
public class GeodeticPoint implements Serializable {
/** North pole.
* @since 10.0
*/
public static final GeodeticPoint NORTH_POLE = new GeodeticPoint(+0.5 * FastMath.PI, 0.0, 0.0);
/** South pole.
* @since 10.0
*/
public static final GeodeticPoint SOUTH_POLE = new GeodeticPoint(-0.5 * FastMath.PI, 0.0, 0.0);
/** Serializable UID. */
private static final long serialVersionUID = 7862466825590075399L;
/** Latitude of the point (rad). */
private final double latitude;
/** Longitude of the point (rad). */
private final double longitude;
/** Altitude of the point (m). */
private final double altitude;
/** Zenith direction. */
private transient Vector3D zenith;
/** Nadir direction. */
private transient Vector3D nadir;
/** North direction. */
private transient Vector3D north;
/** South direction. */
private transient Vector3D south;
/** East direction. */
private transient Vector3D east;
/** West direction. */
private transient Vector3D west;
/**
* Build a new instance. The angular coordinates will be normalized so that
* the latitude is between ±π/2 and the longitude is between ±π.
*
* @param latitude latitude of the point (rad)
* @param longitude longitude of the point (rad)
* @param altitude altitude of the point (m)
*/
public GeodeticPoint(final double latitude, final double longitude,
final double altitude) {
double lat = MathUtils.normalizeAngle(latitude, FastMath.PI / 2);
double lon = MathUtils.normalizeAngle(longitude, 0);
if (lat > FastMath.PI / 2.0) {
// latitude is beyond the pole -> add 180 to longitude
lat = FastMath.PI - lat;
lon = MathUtils.normalizeAngle(longitude + FastMath.PI, 0);
}
this.latitude = lat;
this.longitude = lon;
this.altitude = altitude;
}
/** Get the latitude.
* @return latitude, an angular value in the range [-π/2, π/2]
*/
public double getLatitude() {
return latitude;
}
/** Get the longitude.
* @return longitude, an angular value in the range [-π, π]
*/
public double getLongitude() {
return longitude;
}
/** Get the altitude.
* @return altitude
*/
public double getAltitude() {
return altitude;
}
/** Get the direction above the point, expressed in parent shape frame.
* The zenith direction is defined as the normal to local horizontal plane.
* @return unit vector in the zenith direction
* @see #getNadir()
*/
public Vector3D getZenith() {
if (zenith == null) {
final SinCos scLat = FastMath.sinCos(latitude);
final SinCos scLon = FastMath.sinCos(longitude);
zenith = new Vector3D(scLon.cos() * scLat.cos(), scLon.sin() * scLat.cos(), scLat.sin());
}
return zenith;
}
/** Get the direction below the point, expressed in parent shape frame.
* The nadir direction is the opposite of zenith direction.
* @return unit vector in the nadir direction
* @see #getZenith()
*/
public Vector3D getNadir() {
if (nadir == null) {
nadir = getZenith().negate();
}
return nadir;
}
/** Get the direction to the north of point, expressed in parent shape frame.
* The north direction is defined in the horizontal plane
* (normal to zenith direction) and following the local meridian.
* @return unit vector in the north direction
* @see #getSouth()
*/
public Vector3D getNorth() {
if (north == null) {
final SinCos scLat = FastMath.sinCos(latitude);
final SinCos scLon = FastMath.sinCos(longitude);
north = new Vector3D(-scLon.cos() * scLat.sin(), -scLon.sin() * scLat.sin(), scLat.cos());
}
return north;
}
/** Get the direction to the south of point, expressed in parent shape frame.
* The south direction is the opposite of north direction.
* @return unit vector in the south direction
* @see #getNorth()
*/
public Vector3D getSouth() {
if (south == null) {
south = getNorth().negate();
}
return south;
}
/** Get the direction to the east of point, expressed in parent shape frame.
* The east direction is defined in the horizontal plane
* in order to complete direct triangle (east, north, zenith).
* @return unit vector in the east direction
* @see #getWest()
*/
public Vector3D getEast() {
if (east == null) {
final SinCos scLon = FastMath.sinCos(longitude);
east = new Vector3D(-scLon.sin(), scLon.cos(), 0);
}
return east;
}
/** Get the direction to the west of point, expressed in parent shape frame.
* The west direction is the opposite of east direction.
* @return unit vector in the west direction
* @see #getEast()
*/
public Vector3D getWest() {
if (west == null) {
west = getEast().negate();
}
return west;
}
@Override
public boolean equals(final Object object) {
if (object instanceof GeodeticPoint) {
final GeodeticPoint other = (GeodeticPoint) object;
return this.getLatitude() == other.getLatitude() &&
this.getLongitude() == other.getLongitude() &&
this.getAltitude() == other.getAltitude();
}
return false;
}
@Override
public int hashCode() {
return Double.valueOf(this.getLatitude()).hashCode() ^
Double.valueOf(this.getLongitude()).hashCode() ^
Double.valueOf(this.getAltitude()).hashCode();
}
@Override
public String toString() {
final NumberFormat format = CompositeFormat.getDefaultNumberFormat();
return "{lat: " +
format.format(FastMath.toDegrees(this.getLatitude())) +
" deg, lon: " +
format.format(FastMath.toDegrees(this.getLongitude())) +
" deg, alt: " +
format.format(this.getAltitude()) +
"}";
}
}