Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_2_Build_1041 / libraries / libjni-proj4 / src / pj_mlfn.c @ 33839

History | View | Annotate | Download (1.61 KB)

1
#ifndef lint
2
static const char SCCSID[]="@(#)pj_mlfn.c        4.5        95/07/06        GIE        REL";
3
#endif
4
#include <projects.h>
5
/* meridinal distance for ellipsoid and inverse
6
**        8th degree - accurate to < 1e-5 meters when used in conjuction
7
**                with typical major axis values.
8
**        Inverse determines phi to EPS (1e-11) radians, about 1e-6 seconds.
9
*/
10
#define C00 1.
11
#define C02 .25
12
#define C04 .046875
13
#define C06 .01953125
14
#define C08 .01068115234375
15
#define C22 .75
16
#define C44 .46875
17
#define C46 .01302083333333333333
18
#define C48 .00712076822916666666
19
#define C66 .36458333333333333333
20
#define C68 .00569661458333333333
21
#define C88 .3076171875
22
#define EPS 1e-11
23
#define MAX_ITER 10
24
#define EN_SIZE 5
25
        double *
26
pj_enfn(double es) {
27
        double t, *en;
28

    
29
        if (en = (double *)pj_malloc(EN_SIZE * sizeof(double))) {
30
                en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08)));
31
                en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08)));
32
                en[2] = (t = es * es) * (C44 - es * (C46 + es * C48));
33
                en[3] = (t *= es) * (C66 - es * C68);
34
                en[4] = t * es * C88;
35
        } /* else return NULL if unable to allocate memory */
36
        return en;
37
}
38
        double
39
pj_mlfn(double phi, double sphi, double cphi, double *en) {
40
        cphi *= sphi;
41
        sphi *= sphi;
42
        return(en[0] * phi - cphi * (en[1] + sphi*(en[2]
43
                + sphi*(en[3] + sphi*en[4]))));
44
}
45
        double
46
pj_inv_mlfn(double arg, double es, double *en) {
47
        double s, t, phi, k = 1./(1.-es);
48
        int i;
49

    
50
        phi = arg;
51
        for (i = MAX_ITER; i ; --i) { /* rarely goes over 2 iterations */
52
                s = sin(phi);
53
                t = 1. - es * s * s;
54
                phi -= t = (pj_mlfn(phi, s, cos(phi), en) - arg) * (t * sqrt(t)) * k;
55
                if (fabs(t) < EPS)
56
                        return phi;
57
        }
58
        pj_errno = -17;
59
        return phi;
60
}