Skip to content

Commit 7ffff7c

Browse files
authored
Added MathUtil
1 parent 04fecd3 commit 7ffff7c

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

src/MathUtil.hpp

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//******************************************************************************
2+
// Copyright 2013 Google Inc.
3+
// https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/MathUtil.java
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// This software and the related documents are provided as is, with no express
11+
// or implied warranties, other than those that are expressly stated in the
12+
// License.
13+
//******************************************************************************
14+
15+
#ifndef GEOMETRY_LIBRARY_MATH_UTIL
16+
#define GEOMETRY_LIBRARY_MATH_UTIL
17+
18+
#include <cmath>
19+
20+
#define M_PI 3.14159265358979323846
21+
22+
23+
class MathUtil {
24+
public:
25+
/**
26+
* The earth's radius, in meters.
27+
* Mean radius as defined by IUGG.
28+
*/
29+
const size_t EARTH_RADIUS = 6371009;
30+
31+
/**
32+
* Restrict x to the range [low, high].
33+
*/
34+
static inline double clamp(double x, double low, double high) {
35+
return x < low ? low : (x > high ? high : x);
36+
}
37+
38+
/**
39+
* Wraps the given value into the inclusive-exclusive interval between min and max.
40+
* @param n The value to wrap.
41+
* @param min The minimum.
42+
* @param max The maximum.
43+
*/
44+
static inline double wrap(double n, double min, double max) {
45+
return (n >= min && n < max) ? n : (MathUtil::mod(n - min, max - min) + min);
46+
}
47+
48+
/**
49+
* Returns the non-negative remainder of x / m.
50+
* @param x The operand.
51+
* @param m The modulus.
52+
*/
53+
static inline double mod(size_t x, size_t m) {
54+
return ((x % m) + m) % m;
55+
}
56+
57+
/**
58+
* Returns mercator Y corresponding to latitude.
59+
* See http://en.wikipedia.org/wiki/Mercator_projection .
60+
*/
61+
static inline double mercator(double lat) {
62+
return log(tan(lat * 0.5 + M_PI / 4.0));
63+
}
64+
65+
/**
66+
* Returns latitude from mercator Y.
67+
*/
68+
static inline double inverseMercator(double y) {
69+
return 2.0 * atan(exp(y)) - M_PI / 2.0;
70+
}
71+
72+
/**
73+
* Returns haversine(angle-in-radians).
74+
* hav(x) == (1 - cos(x)) / 2 == sin(x / 2)^2.
75+
*/
76+
static inline double hav(double x) {
77+
double sinHalf = sin(x * 0.5);
78+
return sinHalf * sinHalf;
79+
}
80+
81+
/**
82+
* Computes inverse haversine. Has good numerical stability around 0.
83+
* arcHav(x) == acos(1 - 2 * x) == 2 * asin(sqrt(x)).
84+
* The argument must be in [0, 1], and the result is positive.
85+
*/
86+
static inline double arcHav(double x) {
87+
return 2.0 * asin(sqrt(x));
88+
}
89+
90+
// Given h==hav(x), returns sin(abs(x)).
91+
static inline double sinFromHav(double h) {
92+
return 2.0 * sqrt(h * (1.0 - h));
93+
}
94+
95+
// Returns hav(asin(x)).
96+
static inline double havFromSin(double x) {
97+
double x2 = x * x;
98+
return x2 / (1.0 + sqrt(1.0 - x2)) * 0.5;
99+
}
100+
101+
// Returns sin(arcHav(x) + arcHav(y)).
102+
static inline double sinSumFromHav(double x, double y) {
103+
double a = sqrt(x * (1 - x));
104+
double b = sqrt(y * (1 - y));
105+
return 2.0 * (a + b - 2 * (a * y + b * x));
106+
}
107+
108+
/**
109+
* Returns hav() of distance from (lat1, lng1) to (lat2, lng2) on the unit sphere.
110+
*/
111+
static inline double havDistance(double lat1, double lat2, double dLng) {
112+
return MathUtil::hav(lat1 - lat2) + MathUtil::hav(dLng) * cos(lat1) * cos(lat2);
113+
}
114+
};
115+
116+
#endif // GEOMETRY_LIBRARY_MATH_UTIL

0 commit comments

Comments
 (0)