Beispiel #1
0
        /// <summary>
        /// Calculate the distance between two points. This algorithm does not take the curvature of the Earth into
        /// account, so it only works for small distance up to, say 200 km, and not too close to the poles.
        /// </summary>
        /// <param name="p1">Point 1. @Nonnull</param>
        /// <param name="p2">Point 2. @Nonnull</param>
        /// <returns>Straight distance between p1 and p2. Only accurate for small distances up to 200 km.</returns>
        public static double distanceInMeters(Point p1, Point p2)
        {
            CheckArgs.checkNonnull("p1", p1);
            CheckArgs.checkNonnull("p2", p2);

            Point from;
            Point to;

            if (p1.lonDeg <= p2.lonDeg)
            {
                from = p1;
                to   = p2;
            }
            else
            {
                from = p2;
                to   = p1;
            }

            // Calculate mid point of 2 latitudes.
            double avgLat = from.latDeg + ((to.latDeg - from.latDeg) / 2.0);

            double deltaLonDeg360 = Math.Abs(to.lonDeg - from.lonDeg);
            double deltaLonDeg    = ((deltaLonDeg360 <= 180.0) ? deltaLonDeg360 : (360.0 - deltaLonDeg360));
            double deltaLatDeg    = Math.Abs(to.latDeg - from.latDeg);

            // Meters per longitude is fixed; per latitude requires * cos(avg(lat)).
            double deltaXMeters = degreesLonToMetersAtLat(deltaLonDeg, avgLat);
            double deltaYMeters = degreesLatToMeters(deltaLatDeg);

            // Calculate length through Earth. This is an approximation, but works fine for short distances.
            double lenMeters = Math.Sqrt((deltaXMeters * deltaXMeters) + (deltaYMeters * deltaYMeters));

            return(lenMeters);
        }
Beispiel #2
0
        /// <summary>
        /// Create a random point, uniformly distributed over the surface of the Earth.
        /// </summary>
        /// <param name="randomGenerator">Random generator used to create a point. @Nonnull</param>
        /// <returns>Random point with uniform distribution over the sphere. @Nonnull</returns>
        public static Point fromUniformlyDistributedRandomPoints(Random randomGenerator)
        {
            CheckArgs.checkNonnull("randomGenerator", randomGenerator);

            // Calculate uniformly distributed 3D point on sphere (radius = 1.0):
            // http://mathproofs.blogspot.co.il/2005/04/uniform-random-distribution-on-sphere.html
            double unitRand1 = randomGenerator.NextDouble();
            double unitRand2 = randomGenerator.NextDouble();
            double theta0    = (2.0 * Math.PI) * unitRand1;
            double theta1    = Math.Acos(1.0 - (2.0 * unitRand2));
            double x         = Math.Sin(theta0) * Math.Sin(theta1);
            double y         = Math.Cos(theta0) * Math.Sin(theta1);
            double z         = Math.Cos(theta1);

            // Convert Carthesian 3D point into lat/lon (radius = 1.0):
            // http://stackoverflow.com/questions/1185408/converting-from-longitude-latitude-to-cartesian-coordinates
            double latRad = Math.Asin(z);
            double lonRad = Math.Atan2(y, x);

            // Convert radians to degrees.
            System.Diagnostics.Debug.Assert(!Double.IsNaN(latRad));
            System.Diagnostics.Debug.Assert(!Double.IsNaN(lonRad));
            double lat = RadianToDegree(latRad);
            double lon = RadianToDegree(lonRad);

            return(fromMicroDeg(degToMicroDeg(lat), degToMicroDeg(lon)));
        }