Geo-Coordinates-VandH-XS
view release on metacpan or search on metacpan
b = fx*GX + fy*GY;
c = fx*fx + fy*fy - Q2;
disc = b*b - A*c; /* discriminant */
x, y, z, delta;
if (fabs(disc) < EPSILON) {
z = b/A;
x = (GX*z - fx)/Q;
y = (fy - GY*z)/Q;
} else {
delta = sqrt(disc);
z = (b + delta)/A;
x = (GX*z - fx)/Q;
y = (fy - GY*z)/Q;
if (vhat * (PX*x + PY*y + PZ*z) < 0) { /* wrong direction */
z = (b - delta)/A;
x = (GX*z - fx)/Q;
y = (fy - GY*z)/Q;
}
}
lat = asin(z);
lat2 = lat*lat;
earthlat = lat*(bi[0] + lat2*(bi[1] + lat2*(bi[2] + lat2*(bi[3] + \
lat2*(bi[4] + lat2*(bi[5] + lat2*(bi[6])))))));
earthlat = degrees(earthlat);
/* Adjust longitude by 52 degrees */
lon = degrees(atan2(x, y));
earthlon = lon + 52.0;
XPUSHs(sv_2mortal(newSVnv(earthlat)));
XPUSHs(sv_2mortal(newSVnv(earthlon)));
PUTBACK;
}
MODULE = Geo::Coordinates::VandH::XS PACKAGE = Geo::Coordinates::VandH::XS
PROTOTYPES: DISABLE
double
radians (degrees)
double degrees
double
degrees (radians)
double radians
double
distance (v1, h1, v2, h2)
double v1
double h1
double v2
double h2
void
toVH (lat, lon)
double lat
double lon
PREINIT:
I32* temp;
PPCODE:
temp = PL_markstack_ptr++;
toVH(lat, lon);
if (PL_markstack_ptr != temp) {
/* truly void, because dXSARGS not invoked */
PL_markstack_ptr = temp;
XSRETURN_EMPTY; /* return empty stack */
}
/* must have used dXSARGS; list context implied */
return; /* assume stack size is correct */
void
toLatLon (v, h)
double v
double h
PREINIT:
I32* temp;
PPCODE:
temp = PL_markstack_ptr++;
toLatLon(v, h);
if (PL_markstack_ptr != temp) {
/* truly void, because dXSARGS not invoked */
PL_markstack_ptr = temp;
XSRETURN_EMPTY; /* return empty stack */
}
/* must have used dXSARGS; list context implied */
return; /* assume stack size is correct */
( run in 1.107 second using v1.01-cache-2.11-cpan-5511b514fd6 )