10 # define MIN(a,b) (((a) < (b)) ? (a) : (b)) 14 # define MAX(a,b) (((a) > (b)) ? (a) : (b)) 17 #define MAX_NUMBER_ITERATIONS (100) 25 #if defined USE_MPFR && defined HAVE_LIBMPFR 35 #define DEFAULT_PREC 64 38 #define _MPFR_DEFAULT_PREC MIN(MAX((DEFAULT_PREC), (MPFR_PREC_MIN)), ((MPFR_PREC_MAX) / 4)) 40 int deg_to_rad_mpfr(mpfr_ptr res, mpfr_srcptr x, mpfr_rnd_t r);
41 int VincentyDistance_mpfr(mpfr_ptr res, mpfr_srcptr lat1, mpfr_srcptr lng1, mpfr_srcptr lat2, mpfr_srcptr lng2, mpfr_prec_t p, mpfr_rnd_t r);
44 int deg_to_rad_mpfr(mpfr_ptr res, mpfr_srcptr x, mpfr_rnd_t r)
48 mpfr_init2(pi, mpfr_get_default_prec() * 2);
51 mpfr_mul(res, x, pi, r);
52 mpfr_div_ui(res, res, 180, r);
55 mpfr_clears(pi, (mpfr_ptr)NULL);
60 int VincentyDistance_mpfr(mpfr_ptr res, mpfr_srcptr lat1, mpfr_srcptr lng1, mpfr_srcptr lat2, mpfr_srcptr lng2, mpfr_prec_t p, mpfr_rnd_t r)
62 mpfr_t
a, b,
f, fInv, L, U1, U2, sinU1, sinU2, cosU1, cosU2, lambda, lambdaP, sinLambda, cosLambda, sigma, sinSigma, cosSigma, sinAlpha, cosSqAlpha, cos2SigmaM, C, dLambda, lambdaC, uSq, k1, A, B, deltaSigma;
63 mpfr_inits2(p,
a, b,
f, fInv, L, U1, U2, sinU1, sinU2, cosU1, cosU2, lambda, lambdaP, sinLambda, cosLambda, sigma, sinSigma, cosSigma, sinAlpha, cosSqAlpha, cos2SigmaM, C, dLambda, lambdaC, uSq, k1, A, B, deltaSigma, (mpfr_ptr)NULL);
64 mpfr_t part1, tmp1, tmp2, tmp3, tmp4;
65 mpfr_inits2(p, part1, tmp1, tmp2, tmp3, tmp4, (mpfr_ptr)NULL);
72 mpfr_set_ld(lambdaC, (
long double)1e-24, MPFR_RNDA);
74 mpfr_set_ld(
a, (
long double)6378137.0, r);
76 mpfr_set_ld(fInv, (
long double)298.257223563, r);
77 mpfr_ui_div(
f, 1, fInv, r);
80 mpfr_ui_sub(tmp1, 1,
f, r);
81 mpfr_mul(b, tmp1,
a, r);
84 mpfr_sub(L, lng2, lng1, r);
90 mpfr_ui_sub(part1, 1,
f, r);
91 mpfr_tan(tmp1, lat1, r);
92 mpfr_mul(U1, part1, tmp1, r);
94 mpfr_tan(tmp1, lat2, r);
95 mpfr_mul(U2, part1, tmp1, r);
100 mpfr_sin(sinU1, U1, r);
101 mpfr_sin(sinU2, U2, r);
102 mpfr_cos(cosU1, U1, r);
103 mpfr_cos(cosU2, U2, r);
108 mpfr_set(lambda, L, r);
110 mpfr_set_ui(lambdaP, 0, r);
120 mpfr_sin(sinLambda, lambda, r);
121 mpfr_cos(cosLambda, lambda, r);
125 mpfr_mul(tmp1, cosU2, sinLambda, r);
127 mpfr_sqr(tmp1, tmp1, r);
129 mpfr_mul(tmp2, cosU1, sinU2, r);
131 mpfr_mul(tmp3, sinU1, cosU2, r);
132 mpfr_mul(tmp3, tmp3, cosLambda, r);
134 mpfr_sub(tmp2, tmp2, tmp3, r);
136 mpfr_sqr(tmp2, tmp2, r);
138 mpfr_add(tmp3, tmp1, tmp2, r);
140 mpfr_sqrt(sinSigma, tmp3, r);
142 if(mpfr_nan_p(sinSigma) != 0 || mpfr_zero_p(sinSigma) != 0 || mpfr_cmp_ui(sinSigma, 0) == 0)
return -1;
145 mpfr_mul(tmp1, sinU1, sinU2, r);
146 mpfr_mul(tmp2, cosU1, cosU2, r);
147 mpfr_mul(tmp2, tmp2, cosLambda, r);
148 mpfr_add(cosSigma, tmp1, tmp2, r);
151 mpfr_atan2(sigma, sinSigma, cosSigma, r);
154 mpfr_mul(sinAlpha, cosU1, cosU2, r);
155 mpfr_mul(sinAlpha, sinAlpha, sinLambda, r);
156 mpfr_mul(sinAlpha, sinAlpha, sinSigma, r);
159 mpfr_mul(tmp1, sinAlpha, sinAlpha, r);
160 mpfr_ui_sub(cosSqAlpha, 1, tmp1, r);
163 mpfr_mul(tmp1, sinU1, sinU2, r);
164 mpfr_div(tmp1, tmp1, cosSqAlpha, r);
165 mpfr_mul_ui(tmp1, tmp1, 2, r);
166 mpfr_sub(cos2SigmaM, cosSigma, tmp1, r);
168 if(mpfr_nan_p(cos2SigmaM) != 0) mpfr_set_ui(cos2SigmaM, 0, r);
171 mpfr_mul_ui(tmp1, cosSqAlpha, 3, r);
172 mpfr_ui_sub(tmp2, 4, tmp1, r);
173 mpfr_mul(tmp1,
f, tmp2, r);
174 mpfr_add_ui(tmp2, tmp1, 4, r);
175 mpfr_mul(tmp1, cosSqAlpha, tmp2, r);
176 mpfr_div_ui(tmp2,
f, 16, r);
177 mpfr_mul(C, tmp2, tmp1, r);
179 mpfr_set(lambdaP, lambda, r);
182 mpfr_sqr(tmp3, cos2SigmaM, r);
183 mpfr_mul_ui(tmp3, tmp3, 2, r);
184 mpfr_sub_ui(tmp2, tmp3, 1, r);
185 mpfr_mul(tmp1, cosSigma, tmp2, r);
186 mpfr_mul(tmp1, C, tmp1, r);
187 mpfr_add(tmp3, cos2SigmaM, tmp1, r);
188 mpfr_mul(tmp2, sinSigma, tmp3, r);
189 mpfr_mul(tmp2, C, tmp2, r);
190 mpfr_add(tmp1, sigma, tmp2, r);
191 mpfr_mul(tmp3, sinAlpha, tmp1, r);
192 mpfr_mul(tmp3,
f, tmp3, r);
193 mpfr_ui_sub(tmp2, 1, C, r);
194 mpfr_mul(tmp1, tmp2, tmp3, r);
195 mpfr_add(lambda, L, tmp1, r);
197 mpfr_sub(dLambda, lambda, lambdaP, r);
198 mpfr_abs(dLambda, dLambda, r);
200 while((mpfr_less_p(dLambda, lambdaC) == 0) && (--iterLimit > 0));
203 mpfr_sqr(tmp1,
a, r);
204 mpfr_sqr(tmp2, b, r);
205 mpfr_sub(tmp3, tmp1, tmp2, r);
206 mpfr_div(tmp1, tmp3, tmp2, r);
207 mpfr_mul(uSq, cosSqAlpha, tmp1, r);
210 mpfr_add_ui(tmp2, uSq, 1, r);
211 mpfr_sqrt(tmp1, tmp2, r);
212 mpfr_sub_ui(tmp2, tmp1, 1, r);
213 mpfr_add_ui(tmp3, tmp1, 1, r);
214 mpfr_div(k1, tmp2, tmp3, r);
217 mpfr_sqr(tmp1, k1, r);
218 mpfr_div_ui(tmp3, tmp1, 4, r);
219 mpfr_add_ui(tmp2, tmp3, 1, r);
220 mpfr_ui_sub(tmp3, 1, k1, r);
221 mpfr_div(A, tmp2, tmp3, r);
224 mpfr_mul_ui(tmp3, tmp1, 3, r);
225 mpfr_div_ui(tmp3, tmp3, 8, r);
226 mpfr_ui_sub(tmp2, 1, tmp3, r);
227 mpfr_mul(B, k1, tmp2, r);
230 mpfr_sqr(tmp2, sinSigma, r);
231 mpfr_mul_ui(tmp2, tmp2, 4, r);
232 mpfr_sub_ui(tmp2, tmp2, 3, r);
233 mpfr_sqr(tmp4, cos2SigmaM, r);
234 mpfr_mul_ui(tmp3, tmp4, 4, r);
235 mpfr_sub_ui(tmp3, tmp3, 3, r);
236 mpfr_mul(tmp1, tmp2, tmp3, r);
238 mpfr_mul(tmp3, cos2SigmaM, tmp1, r);
239 mpfr_mul(tmp3, tmp3, B, r);
240 mpfr_div_ui(tmp3, tmp3, 6, r);
242 mpfr_mul_ui(tmp2, tmp4, 2, r);
243 mpfr_sub_ui(tmp2, tmp2, 1, r);
245 mpfr_mul(tmp1, cosSigma, tmp2, r);
246 mpfr_sub(tmp1, tmp1, tmp3, r);
248 mpfr_mul(tmp2, B, tmp1, r);
249 mpfr_div_ui(tmp2, tmp2, 4, r);
250 mpfr_add(tmp2, cos2SigmaM, tmp2, r);
252 mpfr_mul(tmp1, sinSigma, tmp2, r);
253 mpfr_mul(deltaSigma, B, tmp1, r);
256 mpfr_sub(tmp1, sigma, deltaSigma, r);
257 mpfr_mul(tmp2, A, tmp1, r);
258 mpfr_mul(res, b, tmp2, r);
280 mpfr_clears(
a, b,
f, fInv, L, U1, U2, sinU1, sinU2, cosU1, cosU2, lambda, lambdaP, sinLambda, cosLambda, sigma, sinSigma, cosSigma, sinAlpha, cosSqAlpha, cos2SigmaM, C, dLambda, lambdaC, uSq, k1, A, B, deltaSigma, (mpfr_ptr)NULL);
281 mpfr_clears(part1, tmp1, tmp2, tmp3, tmp4, (mpfr_ptr)NULL);
288 mpfr_rnd_t rnd = MPFR_RNDN;
289 mpfr_prec_t prec =
MAX(_MPFR_DEFAULT_PREC, 32);
291 mpfr_t ans, lat1, lng1, ele1, lat2, lng2, ele2, lat_start, lat_end, lng_start, lng_end;
292 mpfr_inits2(prec, ans, lat1, lng1, ele1, lat2, lng2, ele2, lat_start, lat_end, lng_start, lng_end, (mpfr_ptr)NULL);
294 mpfr_set_default_prec(prec);
297 mpfr_set_d(lat_start, lat1_deg, rnd);
298 mpfr_set_d(lng_start, lng1_deg, rnd);
299 mpfr_set_d(ele1, ele1_in, rnd);
300 mpfr_set_d(lat_end, lat2_deg, rnd);
301 mpfr_set_d(lng_end, lng2_deg, rnd);
302 mpfr_set_d(ele2, ele2_in, rnd);
304 deg_to_rad_mpfr(lat1, lat_start, rnd);
305 deg_to_rad_mpfr(lat2, lat_end, rnd);
306 deg_to_rad_mpfr(lng1, lng_start, rnd);
307 deg_to_rad_mpfr(lng2, lng_end, rnd);
311 for(prec = _MPFR_DEFAULT_PREC; (mpfr_nan_p(ans) != 0) && (prec < (MPFR_PREC_MAX / 4)); prec *= 2)
315 if(VincentyDistance_mpfr(ans, lat1, lng1, lat2, lng2, prec, rnd) == -1)
321 mpfr_t ans_real, dAlt, tmp1, tmp2, tmp3;
322 mpfr_inits2(prec, ans_real, dAlt, tmp1, tmp2, tmp3, (mpfr_ptr)NULL);
323 mpfr_sub(dAlt, ele1, ele2, rnd);
324 mpfr_sqr(tmp1, dAlt, rnd);
325 mpfr_sqr(tmp2, ans, rnd);
326 mpfr_add(tmp3, tmp1, tmp2, rnd);
327 mpfr_sqrt(ans_real, tmp3, rnd);
335 mpfr_clears(dAlt, tmp1, tmp2, tmp3, (mpfr_ptr)NULL);
337 mpfr_clears(lat1, lng1, ele1, lat2, lng2, ele2, (mpfr_ptr)NULL);
339 long double res = mpfr_get_ld(ans_real, rnd);
341 mpfr_clears(ans, ans_real, (mpfr_ptr)NULL);
350 mpfr_rnd_t rnd = MPFR_RNDN;
351 mpfr_prec_t prec =
MAX(_MPFR_DEFAULT_PREC, 32);
353 mpfr_t ans, e, d, tmp1;
354 mpfr_inits2(prec, ans, e, d, tmp1, (mpfr_ptr)NULL);
356 mpfr_set_default_prec(prec);
358 mpfr_set_ld(d, dst, rnd);
359 mpfr_set_d(e, d_ele, rnd);
362 mpfr_div(tmp1, e, d, rnd);
363 mpfr_asin(tmp1, tmp1, rnd);
364 mpfr_tan(ans, tmp1, rnd);
365 float res = mpfr_get_d(ans, rnd);
367 mpfr_clears(ans, e, d, tmp1, (mpfr_ptr)NULL);
375 #define FORMULA_DOUBLE 380 #define f ((long double)(1/(long double)298.257223563)) 381 #define a ((long double)6378137.0) 382 #define PI ((long double)(M_PI)) 386 long double lat1, lat2, lng1, lng2;
387 lat1 = (
long double)lat1_deg / 180 *
PI;
388 lng1 = (
long double)lng1_deg / 180 *
PI;
389 lat2 = (
long double)lat2_deg / 180 *
PI;
390 lng2 = (
long double)lng2_deg / 180 *
PI;
391 long double b, lambda, L, U1, U2, cosU1, cosU2, sinU1, sinU2, sinLambda, cosLambda, sinSigma, cosSigma, sigma, sinAlpha, cosSqAlpha, cos2SigmaM, C, uSq, k1, A, B, deltaSigma, res;
393 lambda = L = lng2 - lng1;
394 U1 = atan((1 -
f) * tan(lat1));
395 U2 = atan((1 -
f) * tan(lat2));
400 long double lambda_prev;
404 lambda_prev = lambda;
405 sinLambda = sin(lambda);
406 cosLambda = cos(lambda);
407 sinSigma = sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));
410 cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
411 sigma = atan2(sinSigma, cosSigma);
412 sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
413 cosSqAlpha = 1 - sinAlpha * sinAlpha;
414 cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
416 C =
f / 16 * cosSqAlpha * (4 +
f * (4 - 3 * cosSqAlpha));
417 lambda = L + (1 - C) *
f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
419 while(abs(lambda - lambda_prev) > (
long double)1e-24 && (--iterLimit > 0));
421 uSq = cosSqAlpha * (
a *
a - b * b) / (b * b);
422 k1 = (sqrt(1 + uSq) - 1) / (sqrt(1 + uSq) + 1);
423 A = (1 + 0.25 * k1 * k1) / (1 - k1);
424 B = k1 * (1 - 3/8 * k1 * k1);
425 deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
426 res = b * A * (sigma - deltaSigma);
433 double res_real = (double)sqrt(pow((
long double)ele1 - (
long double)ele2, 2) + pow(res, 2));
439 return (
float)tan(asin((
long double)d_ele / dst));
float calculate_incline(long double dst, alt_t d_ele)
long double calculate_distance(lat_t lat1_deg, lng_t lng1_deg, alt_t ele1, lat_t lat2_deg, lng_t lng2_deg, alt_t ele2)
#define MAX_NUMBER_ITERATIONS