/** * Navit, a modular navigation system. * Copyright (C) 2005-2008 Navit Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef lint static const char SCCSID[] = "@(#)geod_for.c 4.6 95/09/23 GIE REL"; #endif # include "projects.h" # include "geodesic.h" # define MERI_TOL 1e-9 static double th1, costh1, sinth1, sina12, cosa12, M, N, c1, c2, D, P, s1; static int merid, signS; void geod_pre(void) { al12 = adjlon(al12); /* reduce to +- 0-PI */ signS = fabs(al12) > HALFPI ? 1 : 0; th1 = ellipse ? atan(onef * tan(phi1)) : phi1; costh1 = cos(th1); sinth1 = sin(th1); if ((merid = fabs(sina12 = sin(al12)) < MERI_TOL)) { sina12 = 0.; cosa12 = fabs(al12) < HALFPI ? 1. : -1.; M = 0.; } else { cosa12 = cos(al12); M = costh1 * sina12; } N = costh1 * cosa12; if (ellipse) { if (merid) { c1 = 0.; c2 = f4; D = 1. - c2; D *= D; P = c2 / D; } else { c1 = geod_f * M; c2 = f4 * (1. - M * M); D = (1. - c2) * (1. - c2 - c1 * M); P = (1. + .5 * c1 * M) * c2 / D; } } if (merid) s1 = HALFPI - th1; else { s1 = (fabs(M) >= 1.) ? 0. : acos(M); s1 = sinth1 / sin(s1); s1 = (fabs(s1) >= 1.) ? 0. : acos(s1); } } void geod_for(void) { double d, sind, u, V, X, ds, cosds, sinds, ss = 0, de; if (ellipse) { d = geod_S / (D * geod_a); if (signS) d = -d; u = 2. * (s1 - d); V = cos(u + d); X = c2 * c2 * (sind = sin(d)) * cos(d) * (2. * V * V - 1.); ds = d + X - 2. * P * V * (1. - 2. * P * cos(u)) * sind; ss = s1 + s1 - ds; } else { ds = geod_S / geod_a; if (signS) ds = -ds; } cosds = cos(ds); sinds = sin(ds); if (signS) sinds = -sinds; al21 = N * cosds - sinth1 * sinds; if (merid) { phi2 = atan(tan(HALFPI + s1 - ds) / onef); if (al21 > 0.) { al21 = PI; if (signS) de = PI; else { phi2 = -phi2; de = 0.; } } else { al21 = 0.; if (signS) { phi2 = -phi2; de = 0; } else de = PI; } } else { al21 = atan(M / al21); if (al21 > 0) al21 += PI; if (al12 < 0.) al21 -= PI; al21 = adjlon(al21); phi2 = atan(-(sinth1 * cosds + N * sinds) * sin(al21) / (ellipse ? onef * M : M)); de = atan2(sinds * sina12, (costh1 * cosds - sinth1 * sinds * cosa12)); if (ellipse) { if (signS) de += c1 * ((1. - c2) * ds + c2 * sinds * cos(ss)); else de -= c1 * ((1. - c2) * ds - c2 * sinds * cos(ss)); } } lam2 = adjlon(lam1 + de); }