/*
* Copyright 2013 Google Inc.
*
* Licensed 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 com.car2go.maps.util;
/**
* Utility functions that are used my both PolyUtil and SphericalUtil.
*/
class MathUtil {
/**
* The earth's radius, in meters.
* Mean radius as defined by IUGG.
*/
static final double EARTH_RADIUS = 6371009.0D;
MathUtil() {
}
/**
* Restrict x to the range [low, high].
*/
static double clamp(double x, double low, double high) {
return x < low ? low : (x > high ? high : x);
}
/**
* Wraps the given value into the inclusive-exclusive interval between min and max.
*
* @param n The value to wrap.
* @param min The minimum.
* @param max The maximum.
*/
static double wrap(double n, double min, double max) {
return n >= min && n < max ? n : mod(n - min, max - min) + min;
}
/**
* Returns the non-negative remainder of x / m.
*
* @param x The operand.
* @param m The modulus.
*/
static double mod(double x, double m) {
return (x % m + m) % m;
}
/**
* Returns mercator Y corresponding to latitude.
* See http://en.wikipedia.org/wiki/Mercator_projection .
*/
static double mercator(double lat) {
return Math.log(Math.tan(lat * 0.5D + 0.7853981633974483D));
}
/**
* Returns latitude from mercator Y.
*/
static double inverseMercator(double y) {
return 2.0D * Math.atan(Math.exp(y)) - 1.5707963267948966D;
}
/**
* Returns haversine(angle-in-radians).
* hav(x) == (1 - cos(x)) / 2 == sin(x / 2)^2.
*/
static double hav(double x) {
double sinHalf = Math.sin(x * 0.5D);
return sinHalf * sinHalf;
}
/**
* Computes inverse haversine. Has good numerical stability around 0.
* arcHav(x) == acos(1 - 2 * x) == 2 * asin(sqrt(x)).
* The argument must be in [0, 1], and the result is positive.
*/
static double arcHav(double x) {
return 2.0D * Math.asin(Math.sqrt(x));
}
/**
* Given h==hav(x), returns sin(abs(x)).
*/
static double sinFromHav(double h) {
return 2.0D * Math.sqrt(h * (1.0D - h));
}
/**
* Returns hav(asin(x)).
*/
static double havFromSin(double x) {
double x2 = x * x;
return x2 / (1.0D + Math.sqrt(1.0D - x2)) * 0.5D;
}
/**
* Returns sin(arcHav(x) + arcHav(y)).
*/
static double sinSumFromHav(double x, double y) {
double a = Math.sqrt(x * (1.0D - x));
double b = Math.sqrt(y * (1.0D - y));
return 2.0D * (a + b - 2.0D * (a * y + b * x));
}
/**
* Returns hav() of distance from (lat1, lng1) to (lat2, lng2) on the unit sphere.
*/
static double havDistance(double lat1, double lat2, double dLng) {
return hav(lat1 - lat2) + hav(dLng) * Math.cos(lat1) * Math.cos(lat2);
}
}