Java Geometry Algorithm directVincenty(Point2D.Double point, double brng, double distance)

Here you can find the source of directVincenty(Point2D.Double point, double brng, double distance)

Description

Calculate a destination point given a start point, a bearing angle and a distance.

License

Apache License

Parameter

Parameter Description
point starting point (lat/long in decimal degrees)
brng bearing angle from north (decimal degrees)
distance distance (meters)

Return

the destination point (lat/long in decimal degrees)

Declaration

public static Point2D.Double directVincenty(Point2D.Double point,
        double brng, double distance) 

Method Source Code

//package com.java2s;
//License from project: Apache License 

import java.awt.geom.Point2D;

public class Main {
    /**//from   w ww  . jav a 2s  .co m
     * Calculate a destination point given a start point, a bearing angle and a distance.
     * <p>
     * The code employs the Vincenty direct formula from T.Vincenty, "Direct and Inverse Solutions of Geodesics on the Ellipsoid with
     * application of nested equations", Survey Review, vol XXII no 176, 1975 http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
     * <p>
     * See http://www.movable-type.co.uk/scripts/latlong-vincenty-direct.html for explanation and sample web application.
     * <p>
     * @param point starting point (lat/long in decimal degrees)
     * @param brng bearing angle from north (decimal degrees)
     * @param distance distance (meters)
     * @return the destination point (lat/long in decimal degrees)
     */
    public static Point2D.Double directVincenty(Point2D.Double point,
            double brng, double distance) {
        // WGS-84 ellipsoid parameters
        double a = 6378137, b = 6356752.3142, f = 1 / 298.257223563;
        double s = distance;
        double alpha1 = brng * Math.PI / 180;
        double sinAlpha1 = Math.sin(alpha1);
        double cosAlpha1 = Math.cos(alpha1);
        double tanU1 = (1 - f) * Math.tan(point.y * Math.PI / 180);
        double cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1)), sinU1 = tanU1
                * cosU1;
        double sigma1 = Math.atan2(tanU1, cosAlpha1);
        double sinAlpha = cosU1 * sinAlpha1;
        double cosSqAlpha = 1 - sinAlpha * sinAlpha;
        double uSq = cosSqAlpha * (a * a - b * b) / (b * b);
        double A = 1 + uSq / 16384
                * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
        double B = uSq / 1024
                * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
        double cos2SigmaM = Double.NaN;
        double sinSigma = Double.NaN;
        double cosSigma = Double.NaN;
        double sigma = s / (b * A), sigmaP = 2 * Math.PI;
        while (Math.abs(sigma - sigmaP) > 1e-12) {
            cos2SigmaM = Math.cos(2 * sigma1 + sigma);
            sinSigma = Math.sin(sigma);
            cosSigma = Math.cos(sigma);
            double deltaSigma = B
                    * sinSigma
                    * (cos2SigmaM + B
                            / 4
                            * (cosSigma
                                    * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B
                                    / 6
                                    * cos2SigmaM
                                    * (-3 + 4 * sinSigma * sinSigma)
                                    * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
            sigmaP = sigma;
            sigma = s / (b * A) + deltaSigma;
        }
        double tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
        double lat2 = Math.atan2(sinU1 * cosSigma + cosU1 * sinSigma
                * cosAlpha1,
                (1 - f) * Math.sqrt(sinAlpha * sinAlpha + tmp * tmp));
        double lambda = Math.atan2(sinSigma * sinAlpha1, cosU1 * cosSigma
                - sinU1 * sinSigma * cosAlpha1);
        double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
        double L = lambda
                - (1 - C)
                * f
                * sinAlpha
                * (sigma + C
                        * sinSigma
                        * (cos2SigmaM + C * cosSigma
                                * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
        // var revAz = Math.atan2(sinAlpha, -tmp); // final bearing
        return new Point2D.Double(point.x + (L * 180 / Math.PI), lat2 * 180
                / Math.PI);
    }
}

Related

  1. cornersToWorldFile(Point2D[] esq, Dimension size)
  2. curvedLineHit(Point point, Point startPoint, Point endPoint, Point controlPoint1, Point controlPoint2, float padding)
  3. derivativeOfCubicBezier(Point2D p0, Point2D p1, Point2D p2, Point2D p3, double t)
  4. deriveLocation(Point origin, double radius)
  5. determineConnectionPoint(Point wayPoint, Polygon polygon)
  6. dot(@Nonnull Point2D pA, @Nonnull Point2D pB)
  7. dot(final Point2D a, final Point2D b)
  8. dot(Point a, Point b, Point c)
  9. dotNorm(final Point2D a, final Point2D b)