org.orekit.bodies.FieldGeodeticPoint 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-2024 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.text.NumberFormat;
import org.hipparchus.CalculusFieldElement;
import org.hipparchus.Field;
import org.hipparchus.geometry.euclidean.threed.FieldVector3D;
import org.hipparchus.util.CompositeFormat;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.FieldSinCos;
import org.hipparchus.util.MathUtils;
/** Point location relative to a 2D body surface, using {@link CalculusFieldElement}.
* Instance of this class are guaranteed to be immutable.
* @param the type of the field elements
* @since 7.1
* @see BodyShape
* @author Luc Maisonobe
*/
public class FieldGeodeticPoint> {
/** Latitude of the point (rad). */
private final T latitude;
/** Longitude of the point (rad). */
private final T longitude;
/** Altitude of the point (m). */
private final T altitude;
/** Zenith direction. */
private FieldVector3D zenith;
/** Nadir direction. */
private FieldVector3D nadir;
/** North direction. */
private FieldVector3D north;
/** South direction. */
private FieldVector3D south;
/** East direction. */
private FieldVector3D east;
/** West direction. */
private FieldVector3D 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 FieldGeodeticPoint(final T latitude, final T longitude,
final T altitude) {
final T zero = latitude.getField().getZero();
final T pi = zero.getPi();
T lat = MathUtils.normalizeAngle(latitude, pi.multiply(0.5));
T lon = MathUtils.normalizeAngle(longitude, zero);
if (lat.getReal() > pi.multiply(0.5).getReal()) {
// latitude is beyond the pole -> add 180 to longitude
lat = pi.subtract(lat);
lon = MathUtils.normalizeAngle(longitude.add(pi), zero);
}
this.latitude = lat;
this.longitude = lon;
this.altitude = altitude;
}
/** Build a new instance from a {@link GeodeticPoint}.
* @param field field to which the elements belong
* @param geodeticPoint geodetic point to convert
* @since 12.1
*/
public FieldGeodeticPoint(final Field field, final GeodeticPoint geodeticPoint) {
this(field.getZero().newInstance(geodeticPoint.getLatitude()),
field.getZero().newInstance(geodeticPoint.getLongitude()),
field.getZero().newInstance(geodeticPoint.getAltitude()));
}
/** Get the latitude.
* @return latitude, an angular value in the range [-π/2, π/2]
*/
public T getLatitude() {
return latitude;
}
/** Get the longitude.
* @return longitude, an angular value in the range [-π, π]
*/
public T getLongitude() {
return longitude;
}
/** Get the altitude.
* @return altitude
*/
public T 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 FieldVector3D getZenith() {
if (zenith == null) {
final FieldSinCos scLat = FastMath.sinCos(latitude);
final FieldSinCos scLon = FastMath.sinCos(longitude);
zenith = new FieldVector3D<>(scLon.cos().multiply(scLat.cos()),
scLon.sin().multiply(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 FieldVector3D 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 FieldVector3D getNorth() {
if (north == null) {
final FieldSinCos scLat = FastMath.sinCos(latitude);
final FieldSinCos scLon = FastMath.sinCos(longitude);
north = new FieldVector3D<>(scLon.cos().multiply(scLat.sin()).negate(),
scLon.sin().multiply(scLat.sin()).negate(),
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 FieldVector3D 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 FieldVector3D getEast() {
if (east == null) {
final FieldSinCos scLon = FastMath.sinCos(longitude);
east = new FieldVector3D<>(scLon.sin().negate(),
scLon.cos(),
longitude.getField().getZero());
}
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 FieldVector3D getWest() {
if (west == null) {
west = getEast().negate();
}
return west;
}
@Override
public boolean equals(final Object object) {
if (object instanceof FieldGeodeticPoint>) {
@SuppressWarnings("unchecked")
final FieldGeodeticPoint other = (FieldGeodeticPoint) object;
return getLatitude().equals(other.getLatitude()) &&
getLongitude().equals(other.getLongitude()) &&
getAltitude().equals(other.getAltitude());
}
return false;
}
@Override
public int hashCode() {
return getLatitude().hashCode() ^
getLongitude().hashCode() ^
getAltitude().hashCode();
}
@Override
public String toString() {
final NumberFormat format = CompositeFormat.getDefaultNumberFormat();
return "{lat: " +
format.format(FastMath.toDegrees(getLatitude().getReal())) +
" deg, lon: " +
format.format(FastMath.toDegrees(getLongitude().getReal())) +
" deg, alt: " +
format.format(getAltitude().getReal()) +
"}";
}
}