/* * Copyright (C) 2011 apurv * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package nescent.phylogeoref.writer.utility; import de.micromata.opengis.kml.v_2_2_0.Coordinate; import static java.lang.Math.*; import static java.lang.System.out; /** * Provides the various aviation formulae. * @author apurv */ public class AMath { /** * Converts angle to radians from degrees. * @param angle_degree * @return */ public static double getAngleInRadians(double angle_degree){ double angle_radian = angle_degree * Math.PI/180; return angle_radian; } /** * Converts angle to degrees from radians. * @param angle_radian * @return */ public static double getAngleInDegrees(double angle_radian){ double angle_degree = angle_radian * 180/Math.PI; return angle_degree; } /** * Returns the great circle distance between the points (lat1, long1) and point (lat2, long2)<br> * It is actually an angle between 0 and pie. * @param fromCoord * @param toCoord * @return */ public static double getGreatCircleDistance(Coordinate fromCoord, Coordinate toCoord){ double lat1 = AMath.getAngleInRadians(fromCoord.getLatitude()); double lon1 = AMath.getAngleInRadians(fromCoord.getLongitude()); double lat2 = AMath.getAngleInRadians(toCoord.getLatitude()); double lon2 = AMath.getAngleInRadians(toCoord.getLongitude()); double d =0.0; double term1 = sin(lat1) * sin(lat2); double term2 = cos(lat1) * cos(lat2) * cos(lon1-lon2); double sum = term1 + term2; d = acos(sum); return Math.abs(d); } /** * Gets the coordinate corresponding to the fraction f between the source and destination coordinates. * <br> * @see http://iphylo.blogspot.com/2007/06/earth-not-flat-official.html * @param fromCoord * @param toCoord * @param d the great circle distance. * @param f the fraction. 0 represents the fromPoint and 1 the toPoint * @return */ public static Coordinate getIntermediateCoordinate(Coordinate fromCoord, Coordinate toCoord, double d, double f){ Coordinate coord = null; double lat1 = AMath.getAngleInRadians(fromCoord.getLatitude()); double lon1 = AMath.getAngleInRadians(fromCoord.getLongitude()); double alt1 = fromCoord.getAltitude(); double lat2 = AMath.getAngleInRadians(toCoord.getLatitude()); double lon2 = AMath.getAngleInRadians(toCoord.getLongitude()); double alt2 = toCoord.getAltitude(); double A = getA(f, d); double B = getB(f, d); double x = getX(A, B, lat1, lon1, lat2, lon2); double y = getY(A, B, lat1, lon1, lat2, lon2); double z = getZ(A, B, lat1, lon1, lat2, lon2); double lat = atan2(z, sqrt( pow(x,2) + pow(y,2))); double lon = atan2(y, x); double alt = alt1; lat = getAngleInDegrees(lat); lon = getAngleInDegrees(lon); coord = new Coordinate(lon, lat, alt); return coord; } /** * Returns the A value used in the formula * @param f * @param d * @return */ private static double getA(double f, double d){ double A = sin((1-f)*d) / sin(d); return A; } /** * Returns the B value to be used in the formula. * @param f * @param d * @return */ private static double getB(double f, double d){ double B = sin(f*d) / sin(d); return B; } /** * Returns the x value to be used in the formula. * @param A * @param B * @param lat1 * @param lon1 * @param lat2 * @param lon2 * @return */ private static double getX(double A, double B, double lat1, double lon1, double lat2, double lon2){ double x = 0.0; x = A*cos(lat1)*cos(lon1) + B*cos(lat2)*cos(lon2); return x; } /** * Returns the y value to be used in the formula. * @param A * @param B * @param lat1 * @param lon1 * @param lat2 * @param lon2 * @return */ private static double getY(double A, double B, double lat1, double lon1, double lat2, double lon2){ double y = 0.0; y = A*cos(lat1)*sin(lon1) + B*cos(lat2)*sin(lon2); return y; } /** * Returns the z value to be used in the formula. * @param A * @param B * @param lat1 * @param lon1 * @param lat2 * @param lon2 * @return */ private static double getZ(double A, double B, double lat1, double lon1, double lat2, double lon2){ double z = 0.0; z = A*sin(lat1) + B*sin(lat2); return z; } }