Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
Solved

# Convert this JS to VB

Posted on 2006-07-18
Medium Priority
755 Views
Hi All,

I have this javascript that I would like to use in a vb app, but need a hand converting it to vb functions.

'Begin JS Code

//complex number functions from Javascript The Definitive Guide by David Flanagan

function Complex(real, imaginary) {
this.x = real;
this.y = imaginary;
}

// return magnitude of complex number
Complex.prototype.magnitude = function() {
return Math.sqrt(this.x * this.x + this.y * this.y);
};

//return a complex number that is the negative of input
Complex.prototype.negative = function() {
return new Complex(-this.x, -this.y);
};

//return the real portion of a complex number
Complex.prototype.valueOf = function() { return this.x; };

Complex.add = function (a, b) {
return new Complex(a.x + b.x, a.y + b.y);
};

//subtract two complex numbers
Complex.subtract = function (a, b) {
return new Complex(a.x - b.x, a.y - b.y);
};

//multiply two complex numbers
Complex.multiply = function (a, b) {
return new Complex(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
};

//divide two complex numbers
Complex.divide = function (a, b) {
var cmod2 = b.x * b.x + b.y * b.y;
var temp = new Complex(b.x / cmod2, -b.y / cmod2);
return new Complex.multiply(a, temp);
};

//scale a complex number
Complex.scale = function (a, s) {
return new Complex(a.x * s, a.y * s);
};

//power of a complex number
Complex.power = function(a, p) {
if (p>0) {
var ans = new Complex(a.x, a.y);
for (il=1; il<p; il++) ans = Complex.multiply(ans, a);
}
else {
var ans = new Complex(1, 1);
}
return new Complex(ans.x,ans.y);
};

Complex.prototype.toString = function() {
return "{" + this.x + "," + this.y + "}";
};

var a =  6378388.0;
var n0 = 6023150.0;
var e0 = 2510000.0;
var lt0 = -41.0;
var ln0 = 173.0;

var cfi = new Array(0.6399175073,
-0.1358797613,
0.063294409,
-0.02526853,
0.0117879,
-0.0055161,
0.0026906,
-0.001333,
0.00067,
-0.00034);

var cfl = new Array(1.5627014243,
0.5185406398,
-0.03333098,
-0.1052906,
-0.0368594,
0.007317,
0.01220,
0.00394,
-0.0013 );

var cfb1 = new Array(6);
cfb1[0] = new Complex(0.7557853228,           0.0);
cfb1[1] = new Complex(0.249204646,   0.003371507);
cfb1[2] = new Complex(-0.001541739,   0.041058560);
cfb1[3] = new Complex(-0.10162907,    0.01727609);
cfb1[4] = new Complex(-0.26623489,   -0.36249218);
cfb1[5] = new Complex(-0.6870983,    -1.1651967);

var cfb2 = new Array(6);
cfb2[0] = new Complex(1.3231270439,           0.0);
cfb2[1] = new Complex(-0.577245789,  -0.007809598);
cfb2[2] = new Complex(0.508307513,  -0.112208952);
cfb2[3] = new Complex(-0.15094762,    0.18200602);
cfb2[4] = new Complex(1.01418179,    1.64497696);
cfb2[5] = new Complex(1.9660549,     2.5127645);

function calcRandB(form, in1, in2, in3, in4) {             //calculate plane grid range and bearing
// in1 - point 1 coordinates index
// in2 - point 2 coordinates index
// in3 - distance index
// in4 - bearing index
var de = parseFloat(form.east[in2].value) - parseFloat(form.east[in1].value);  //difference in eastings
var dn = parseFloat(form.north[in2].value) - parseFloat(form.north[in1].value);  //difference in northings

form.distvalue[in3].value = Math.sqrt(de * de + dn * dn);          //compute distance
form.distvalue[in3].value = roundoff(form.distvalue[in3].value,distsize);  //round off distance

var x = Math.atan2(de,dn);    //compute bearing, result in radians
if (x < 0) {
x += 2 * pi;             //if negative add 2*pi or 360 degrees
}
return true;
}

function calcPoint(form, in1, in2, in3, in4) {           //calculate grid coordinates from plane grid range and bearing
// in1 - point 1 coordinates index
// in2 - point 2 coordinates index
// in3 - distance index
// in4 - bearing index

var x = dms2ddd(form.degreevalue[in4].value, form.minutevalue[in4].value, form.secondvalue[in4].value);  //convert to decimal degrees
var dn = parseFloat(form.distvalue[in3].value) * Math.cos(x) ;
var de = parseFloat(form.distvalue[in3].value) * Math.sin(x) ;
form.north[in2].value = parseFloat(form.north[in1].value) + dn;
form.east[in2].value = parseFloat(form.east[in1].value) + de;
form.north[in2].value = roundoff(form.north[in2].value,distsize);
form.east[in2].value = roundoff(form.east[in2].value,distsize);
return true;
}

x = x * pi / 180;
return x;
}

x = x * 180 / pi;
return x;
}

function roundoff(x,y){              //round off x to y decimal places
x = parseFloat(x);
y = parseFloat(y);
x = Math.round(x * Math.pow(10,y))/Math.pow(10,y);
return x;
}

function dms2ddd(d,m,s){

if (isblank(d)) d = '0';
else {
var y = d.slice(0, 1);
d = parseFloat(d);
}
if (isblank(m)) m = '0';
else
m = parseFloat(m);
if (isblank(s)) s = '0';
else
s = parseFloat(s);
var x = Math.abs(d) + (Math.abs(m) / 60) + (Math.abs(s) / 3600);  //convert to decimal degrees
if ((y == "-") || (d < 0) || (m < 0) || (s < 0)) x = -x;
return x;

}

function isblank(s)
{
for(var i = 0; i < s.length; i++) {
var c = s.charAt(i);
if ((c != ' ') && (c != '\n') && (c != '\t')) return false;
}
return true;
}

function geo2grid(form, in1, in2, in3, in4, in5){
// in1 - point latitude index
// in2 - point longitude index
// in3 - point grid coordinates
// in4 - grid convergence index
// in5 - point scale factor index

var a =  6378388.0;
var n0 = 6023150.0;
var e0 = 2510000.0;
var lt0 = -41.0;
var ln0 = 173.0;

var latddd = dms2ddd(form.degreevalue[in1].value, form.minutevalue[in1].value, form.secondvalue[in1].value);  // convert latitude of point to decimal degrees then radians
var londdd = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude

var lt = (latddd - lt0) * 0.03600;
var sum = 0;
for (i=0; i < 10; i++) {
sum = sum + cfi[i] * Math.pow(lt, i + 1);
}

var z1 = new Complex(sum, deg2rad(londdd - ln0));

var z0 = new Complex(0,0);
var z2 = new Complex(0,0);
var z3 = new Complex(0,0);

for (ij=0; ij<6; ij++) {
z2 = Complex.power(z1, ij+1);
z3 = Complex.multiply(cfb1[ij], z2);
}
form.north[in3].value = n0 + z0.x * a;
form.east[in3].value = e0 + z0.y * a;
}

function grid2geo(form, in1, in2, in3, in4, in5){
// in1 - point latitude index
// in2 - point longitude index
// in3 - point grid coordinates
// in4 - grid convergence index
// in5 - point scale factor index

var a =  6378388.0;
var n0 = 6023150.0;
var e0 = 2510000.0;
var lt0 = -41.0;
var ln0 = 173.0;

var north = parseFloat(form.north[in3].value);
var east = parseFloat(form.east[in3].value);

var z = new Complex((north - n0)/a, (east - e0)/a);

var z1 = new Complex(0,0);
var z2 = new Complex(0,0);
var z3 = new Complex(0,0);
for (ij=0; ij<6; ij++) {
z2 = Complex.power(z,ij+1);
z3 = Complex.multiply(cfb2[ij],z2);
}
for (kk=0; kk<2; kk++) {
z2 = new Complex(0,0);
for (ij=2; ij<7; ij++) {
}

z3 = new Complex(cfb1[0].x, cfb1[0].y);

}
var dphi = 0;
for (ij=1; ij<10; ij++) {
dphi = dphi + cfl[ij-1] * Math.pow(z1.x,ij);
}

var latdeg = lt0 + (dphi * 100000 / 3600);
var londeg = ln0 + rad2deg(z1.y);

ddd2dms(form, in1, latdeg);
ddd2dms(form, in2, londeg);
}

function tttghg() {
// calclulate constants required for Redfern's formulae
var k = parseFloat(form.k.value);  //scale factor
var a = parseFloat(form.a.value);  //semi-major axis
var f = 1 / parseFloat(form.invf.value);  //flattening
var b = a * (1 - f);    //semi-minor axis
var e2 = (a * a - b * b)/(a * a);  //eccentricity squared
var e = Math.sqrt(e2);  //eccentricity
var ei2 = (a * a - b * b)/(b * b); //second eccentricity squared
var ei = Math.sqrt(ei2); //second eccentricity
var n = (a - b)/(a + b);
var G = a * (1 - n) * (1 - n * n) * (1 + (9 / 4) * n * n + (255 / 64) * Math.pow(n,4)) * (pi / 180);  //Mean length of an arc of one degree of the meridian
var north = (parseFloat(form.north[in3].value) - parseFloat(form.falsenorth.value)) * units;  //northing from the equator
var east = (parseFloat(form.east[in3].value) - parseFloat(form.falseeast.value)) * units; //easting from the CM
var m = north / k;  //meridian distance
var sigma = (m * pi) / (180 * G);

// calculate the foot point latitude and constants for that latitude
var footlat = sigma + ((3 * n / 2) - (27 * Math.pow(n, 3) / 32)) * Math.sin(2 * sigma) + ((21 * n * n / 16) - (55 * Math.pow(n, 4) / 32)) * Math.sin(4 * sigma) + (151 * Math.pow(n, 3) / 96) * Math.sin(6 * sigma) + (1097 * Math.pow(n, 4) / 512) * Math.sin(8 * sigma);
var rho = a * (1 - e2) / Math.pow(1 - (e2 * Math.sin(footlat) * Math.sin(footlat)),(3/2)); //radius of curvature in plane of meridian
var nu = a / Math.sqrt(1 - (e2 * Math.sin(footlat) * Math.sin(footlat))); //radius of curvature in prime vertical
var psi = nu / rho;
var t = Math.tan(footlat);  //tan of latitude

// calculate latitude
var x = east / (k * nu);
var laterm1 = (t / (k * rho )) * ( east * x / 2);
var laterm2 = (t / (k * rho )) * ( east * Math.pow(x, 3) / 24) * (-4 * psi * psi + 9 * psi * (1 - t * t) + 12 * t * t );
var laterm3 = (t / (k * rho )) * ( east * Math.pow(x, 5) / 720) * (8 * Math.pow(psi, 4) * (11 - 24 * t * t) - 12 * Math.pow(psi, 3) * (21 - 71 * t * t) + 15 * psi * psi * (15 - 98 * t * t + 15 * Math.pow(t, 4)) + 180 * psi * (5 * t * t - 3 * Math.pow(t, 4)) + 360 * Math.pow(t, 4));
var laterm4 = (t / (k * rho )) * ( east * Math.pow(x, 7) / 40320) * (1385 + 3633 * t * t + 4095 * Math.pow(t, 4) + 1575 * Math.pow(t, 6));
var latrad = footlat - laterm1 + laterm2 - laterm3 + laterm4;

// calculate longitude
var seclat = 1 / Math.cos(footlat);
var loterm1 = x * seclat;
var loterm2 = (Math.pow(x, 3) / 6) * seclat * (psi + 2 * t * t);
var loterm3 = (Math.pow(x, 5) / 120) * seclat * (-4 * Math.pow(psi, 3) * (1 - 6 * t * t) + psi * psi * (9 -68 * t * t) + 72 * psi * t * t + 24 * Math.pow(t, 4));
var loterm4 = (Math.pow(x, 7) / 5040) * seclat * (61 + 662 * t * t + 1320 * Math.pow(t, 4) + 720 * Math.pow(t, 6));
var w = loterm1 - loterm2 + loterm3 - loterm4;

// calculate grid convergence
var gterm1 = -t * x;
var gterm2 = (t * Math.pow(x, 3) / 3) * (-2 * psi * psi + 3 * psi + t * t);
var gterm3 = (-t * Math.pow(x, 5) / 15) * (Math.pow(psi, 4) * (11 - 24 * t * t) - 3 * Math.pow(psi, 3) * (8 - 23 * t * t) + 5 * psi * psi * (3 - 14 * t * t) + 30 * psi * t * t + 3 * Math.pow(t, 4));
var gterm4 = (t * Math.pow(x, 7) / 315) * (17 +77 * t * t + 105 * Math.pow(t, 4) + 45 * Math.pow(t, 6));
var gridconv = gterm1 + gterm2 + gterm3 + gterm4;

// calculate point scale factor
x = east * east / (k * k * rho * nu);
var kterm1 = x / 2;
var kterm2 = (x * x / 24) * (4 * psi * (1 - 6 * t * t) - 3 * (1 - 16 * t * t) - 24 * t * t / psi);
var kterm3 = Math.pow(x, 3) / 720 ;
var pointk = k * (1 + kterm1 + kterm2 + kterm3);
form.pointk[in5].value = roundoff(pointk, bearsize);

return true;
}

function calcRandBgeo(form, in1, in2, in3, in4, in5, in6){
// in1 - point 1 latitude index
// in2 - point 1 longitude index
// in3 - point 2 latitude index
// in4 - point 2 longitude index
// in5 - distance index
// in6 - bearing index

var j = form.units.selectedIndex;
var units = form.units.options[j].value;

// calclulate constants
//  var k = parseFloat(form.k.value);  //scale factor
var a = parseFloat(form.a.value);  //semi-major axis
var f = 1 / parseFloat(form.invf.value);  //flattening
var b = a * (1 - f);    //semi-minor axis

var latddd1 = dms2ddd(form.degreevalue[in1].value, form.minutevalue[in1].value, form.secondvalue[in1].value);  // convert latitude of point to decimal degrees then radians
var londdd1 = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude
var latddd2 = dms2ddd(form.degreevalue[in3].value, form.minutevalue[in3].value, form.secondvalue[in3].value);  // convert latitude of point to decimal degrees then radians
var londdd2 = dms2ddd(form.degreevalue[in4].value, form.minutevalue[in4].value, form.secondvalue[in4].value);  // likewise for longitude

if (Math.abs(w) > 1.5707963268) {
alert("Sorry this calculator isn't designed for such large distances.\nTry my Great Circle Calculator instead.");
}
var tanB1 = Math.tan(latrad1) * (1 - f);
var tanB2 = Math.tan(latrad2) * (1 - f);
var B1 = Math.atan(tanB1);
var B2 = Math.atan(tanB2);

var term1 = Math.sin(w) * Math.cos(B2);
var term2 = Math.sin(B2) * Math.cos(B1) - Math.sin(B1) * Math.cos(B2) * Math.cos(w);
var phi = Math.asin(Math.sqrt(term1 * term1 + term2 * term2));
var c = (Math.cos(B1) * Math.cos(B2) * Math.sin(w)) / Math.sin(phi);
var m = 1 - c * c;

term1 = phi * (1 + f + f * f)
term2 = Math.sin(B1) * Math.sin(B2) * ((f + f * f) * Math.sin(phi) - ((f * f / 2) * phi * phi / Math.sin(phi)));
var term3 = m * (-1 * (phi * (f + f * f) / 2) - ((f + f * f) / 2) * Math.sin(phi) * Math.cos(phi) + ((f * f / 2) * phi * phi) / Math.tan(phi));
var term4 = Math.sin(B1) * Math.sin(B2) * Math.sin(B1) * Math.sin(B2) * (-1 * (f * f /2) * Math.sin(phi) * Math.cos(phi));
var term5 = m * m * ((f * f / 16 ) * phi + (f * f / 16) * Math.sin(phi) * Math.cos(phi) - (f * f / 2) * phi * phi / Math.tan(phi) - (f * f / 8) * Math.sin(phi) * Math.pow(Math.cos(phi), 3));
var term6 = Math.sin(B1) * Math.sin(B2) * m * ((f * f / 2) * phi * phi / Math.sin(phi) + (f * f / 2) * Math.sin(phi) * Math.cos(phi) * Math.cos(phi));
var s = b * (term1 + term2 + term3 + term4 + term5 + term6);
form.distvalue[in5].value = roundoff((s / units), distsize);  //round off distance

term1 = (f + f * f) * phi;
term2 = Math.sin(B1) * Math.sin(B2) * ( -1 * (f * f / 2) * Math.sin(phi) - f * f * phi * phi / Math.sin(phi));
term3 = m * (-1 * (5 * f * f / 4) * phi + (f * f /4) * Math.sin(phi) * Math.cos(phi) + f * f * phi * phi / Math.tan(phi));
lamda = c * (term1 + term2 + term3) + w;

var de = Math.sin(B2) * Math.cos(B1) - Math.cos(lamda) * Math.sin(B1) * Math.cos(B2);
var dn = Math.sin(lamda) * Math.cos(B2);
var x = Math.atan2(dn,de);    //compute bearing, result in radians
if (x < 0) {
x += 2 * pi;             //if negative add 2*pi or 360 degrees
}

if (w == 0) {
if (latddd2 < latddd1)
x =  pi;
else if (latddd2 > latddd1)
x = 0;
else if (latddd2 == latddd1) {
x = 0;
form.distvalue[in5].value = roundoff(0, distsize);  //round off distance
}
}

return true;
}

function calcPointgeo(form, in1, in2, in3, in4, in5, in6){
// in1 - point 1 latitude index
// in2 - point 1 longitude index
// in3 - point 2 latitude index
// in4 - point 2 longitude index
// in5 - distance index
// in6 - bearing index

var j = form.units.selectedIndex;
var units = form.units.options[j].value;

// calclulate constants
//  var k = parseFloat(form.k.value);  //scale factor
var a = parseFloat(form.a.value);  //semi-major axis
var f = 1 / parseFloat(form.invf.value);  //flattening
var b = a * (1 - f);    //semi-minor axis
var e2 = (a * a - b * b)/(a * a);  //eccentricity squared
var e = Math.sqrt(e2);  //eccentricity
var ei2 = (a * a - b * b)/(b * b); //second eccentricity squared
var ei = Math.sqrt(ei2); //second eccentricity

var latddd1 = dms2ddd(form.degreevalue[in1].value, form.minutevalue[in1].value, form.secondvalue[in1].value);  // convert latitude of point to decimal degrees then radians
var londdd1 = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude
var x12 = dms2ddd(form.degreevalue[in6].value, form.minutevalue[in6].value, form.secondvalue[in6].value);  //convert to decimal degrees
var s = (parseFloat(form.distvalue[in5].value) * units);

if (Math.abs(s) > 10019148.059) {
alert("Sorry this calculator isn't designed for such large distances.\nTry my Great Circle Calculator instead.");
}
var tanB1 = Math.tan(latrad1) * (1 - f);
var B1 = Math.atan(tanB1);
var cosB0 = Math.cos(B1) * Math.sin(x12);
var B0 = Math.acos(cosB0);
var g = Math.cos(B1) * Math.cos(x12);
var m = (1 + (ei2 / 2) * Math.sin(B1) * Math.sin(B1)) * (1 - Math.cos(B0) * Math.cos(B0));
var phis = s / b;
var a1 = (1 + (ei2 / 2) * Math.sin(B1) * Math.sin(B1)) * (Math.sin(B1) * Math.sin(B1) * Math.cos(phis) + g * Math.sin(B1) * Math.sin(phis));

var term1 = a1 * (-1 * (ei2 / 2) * Math.sin(phis));
var term2 = m * (-1 * (ei2 / 4) * phis + (ei2 / 4) * Math.sin(phis) * Math.cos(phis));
var term3 = a1 * a1 * ((5 * ei2 * ei2 / 8) * Math.sin(phis) * Math.cos(phis));
var term4 = m * m * (( 11 * ei2 * ei2 / 64) * phis - (13 * ei2 * ei2 / 64) * Math.sin(phis) * Math.cos(phis) - (ei2 * ei2 / 8) * phis * Math.cos(phis) * Math.cos(phis) + (5 * ei2 * ei2 / 32) * Math.sin(phis) * Math.pow(Math.cos(phis), 3));
var term5 = a1 * m * ((3 * ei2 * ei2 / 8) * Math.sin(phis) + (ei2 * ei2 /4) * phis * Math.cos(phis) - (5 * ei2 * ei2 / 8) * Math.sin(phis) * Math.cos(phis) * Math.cos(phis));
var phi0 = phis + term1 + term2 + term3 + term4 + term5;

var cotlamda = (Math.cos(B1) * Math.cos(phi0) - Math.sin(B1) * Math.sin(phi0) * Math.cos(x12)) / (Math.sin(phi0) * Math.sin(x12));
var lamda = Math.atan(1 / cotlamda);

term1 = -1 * f * phis;
term2 = a1 * ((3 * f * f / 2) * Math.sin(phis));
term3 = m * ((3 * f * f / 4) * phis - (3 * f * f / 4) * Math.sin(phis) * Math.cos(phis));
var w = (term1 + term2 + term3) * Math.cos(B0) + lamda;

var sinB2 = Math.sin(B1) * Math.cos(phi0) + g * Math.sin(phi0);
var cosB2 = Math.sqrt((Math.cos(B0) * Math.cos(B0)) + Math.pow((g * Math.cos(phi0) - Math.sin(B1) * Math.sin(phi0)), 2));
var tanB2 = sinB2 / cosB2;
var tanlat2 = tanB2 / (1 - f);

return true;
}

function ddd2dms(form, ind, bearing){
var y = Math.abs(parseFloat(bearing));
form.degreevalue[ind].value = parseInt(y + 1) - 1;
var x = y - form.degreevalue[ind].value;
form.minutevalue[ind].value = parseInt(x * 60 + 1) - 1;
form.secondvalue[ind].value = ((x * 60) - form.minutevalue[ind].value) * 60;
form.secondvalue[ind].value = roundoff(form.secondvalue[ind].value,secsize);
if (form.secondvalue[ind].value == 60) {
form.secondvalue[ind].value = "0";
form.minutevalue[ind].value = form.minutevalue[ind].value * 1 + 1;
if (form.minutevalue[ind].value == 60) {
form.minutevalue[ind].value = "0";
form.degreevalue[ind].value = form.degreevalue[ind].value * 1 + 1;
}
}
if (bearing < 0) {
if (form.degreevalue[ind].value != 0)
form.degreevalue[ind].value = -form.degreevalue[ind].value;
else if (form.minutevalue[ind].value != 0)
form.minutevalue[ind].value = -form.minutevalue[ind].value;
else
form.secondvalue[ind].value = -form.secondvalue[ind].value;
}
form.degreevalue[ind].value += "\260";                                        // add degrees symbol now we have finished with value
form.minutevalue[ind].value += "\'";                                        //add minute symbol now we have finished with value
form.secondvalue[ind].value += '\"';               //round off seconds and add symbol
return true;
}

function confirmSphChange(form){             //to only allow changes to spheroid parameters if in user defined mode

var i = form.spheroid.selectedIndex;
if (i != 22) {
form.a.blur();
form.invf.blur();
alert("\n To override Spheroid Parameters\n use the User Defined option.");
}
return true;
}

var i = form.spheroid.selectedIndex;
switch(i) {
case 0:
form.a.value = 6378388.000;
form.invf.value = 297.000;
break;
}
return true;
}

function confirmProjChange(form){             //to only allow changes to projection parameters if in user defined mode

var i = form.projection.selectedIndex;
if (i != 2) {
form.falsenorth.blur();
form.falseeast.blur();
form.k.blur();
alert("\n To override Projection Parameters\n use the User Defined option.");
}
return true;
}

function updateProjection(form, x){

var i = form.projection.selectedIndex;
var j = form.units.selectedIndex;
var units = form.units.options[j].value;
switch(i) {
case 0:
form.falsenorth.value = 0;
form.falseeast.value = 500000 / units;
form.k.value = 0.9996;
break;
case 1:
form.falsenorth.value = 10000000 / units;
form.falseeast.value = 500000 / units;
form.k.value = 0.9996;
break;
case 2:
if (x == 1) {                  // only reset if called from projection selection not grid units
form.falsenorth.value = '';
form.falseeast.value = '';
form.k.value = '';
}
break;
}
}

function swapgeos(form){
var x = form.degreevalue[0].value;
form.degreevalue[0].value = form.degreevalue[5].value;
form.degreevalue[5].value = x;
x = form.degreevalue[1].value;
form.degreevalue[1].value = form.degreevalue[6].value;
form.degreevalue[6].value = x;

x = form.minutevalue[0].value;
form.minutevalue[0].value = form.minutevalue[5].value;
form.minutevalue[5].value = x;
x = form.minutevalue[1].value;
form.minutevalue[1].value = form.minutevalue[6].value;
form.minutevalue[6].value = x;

x = form.secondvalue[0].value;
form.secondvalue[0].value = form.secondvalue[5].value;
form.secondvalue[5].value = x;
x = form.secondvalue[1].value;
form.secondvalue[1].value = form.secondvalue[6].value;
form.secondvalue[6].value = x;
return true;
}

function swapgrid(form){
var x = form.north[0].value;
form.north[0].value = form.north[1].value;
form.north[1].value = x;
x = form.east[0].value;
form.east[0].value = form.east[1].value;
form.east[1].value = x;
return true;
}

function updateCM(form){
var zone = parseFloat(form.zone.value);
if ((zone < 1) || (zone > 60) || isblank(form.zone.value)) {
form.zone.value = "";
form.zone.focus();
}
else {
form.cmlong.value =  zone * 6 - 183 + "\260";
}
}

function updateZone(form){
var cmlong = parseFloat(form.cmlong.value);
if ((cmlong < -180) || (cmlong > 180) || isblank(form.cmlong.value)) {
form.cmlong.value = "";
form.cmlong.focus();
}
else {
form.zone.value = roundoff(((cmlong + 183) / 6), 2);
}
}

'End JS Code

0
Question by:nzfire
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 12
• 10

LVL 1

Author Comment

ID: 17135833
Alternatively, I have 'C' source code to the above...
0

LVL 15

Expert Comment

ID: 17137607
It's easy enough to convert this,  as long as you give ALL the information. For example, many of the functions have a parameter "form" - what is this? Is it an HTML form or is it something else? What are its fields?

Just to give you an idea of how it can be done, the complex number functionality can be converted to:
Public Class Complex
Public x As Integer, y As Integer

Public Sub New(ByVal real As Integer, ByVal imaginary As Integer)
x = real
y = imaginary
End Sub

'  return magnitude of complex number
Public Function magnitude() As Double
Return Math.Sqrt(Me.x * Me.x + Me.y * Me.y)
End Function

' return a complex number that is the negative of input
Public Function negative() As Complex
Return New Complex(-Me.x, -Me.y)
End Function

' return the real portion of a complex number
Public Function valueOf() As Integer
Return Me.x
End Function

Public Function add(ByVal b As Complex) As Complex
Return New Complex(Me.x + b.x, Me.y + b.y)
End Function

' subtract two complex numbers
Public Function subtract(ByVal b As Complex) As Complex
Return New Complex(Me.x - b.x, Me.y - b.y)
End Function

' multiply two complex numbers
Public Function multiply(ByVal b As Complex) As Complex
Return New Complex(Me.x * b.x - Me.y * b.y, Me.x * b.y + Me.y * b.x)
End Function

' divide two complex numbers
Public Function divide(ByVal b As Complex) As Complex
Dim cmod2 As Integer
Dim temp As Complex

cmod2 = b.x * b.x + b.y * b.y
temp = New Complex(b.x / cmod2, -b.y / cmod2)
Return Me.multiply(temp)
End Function

' scale a complex number
Public Function scale(ByVal s As Integer)
Return New Complex((Me.x) * s, (Me.y) * s)
End Function

' power of a complex number
Public Function power(ByVal p As Integer)
Dim ans As Complex
Dim il As Integer
If (p > 0) Then
ans = New Complex(Me.x, Me.y)
For il = 1 To p
ans = ans.multiply(ans)
Next
Else
ans = New Complex(1, 1))
End If
Return New Complex(ans.x, ans.y)
End Function

Public Overrides Function toString() As String
Return "{" + Me.x + "," + Me.y + "}"
End Function

End Class
0

LVL 1

Author Comment

ID: 17141909
Hi bpmurray,

Thanks so much for doing it this far. Sorry about the lack of information. Yes, it is an HTML form.

The 2 functions that I require are: geo2grid and grid to geo. I will post the HTML here if that helps.

If you view the page, the calculations that are performed in the "Point 1" area are all I require.

Thanks once again.

'/Begin code

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<title>Untitled Document</title>
<SCRIPT language=JavaScript type=text/javascript>
<!--

var pi = Math.PI;
var secsize = 4;       // round second display to
var distsize = 3;      // round distance display to
var bearsize = 8;      // round bearing display to

//complex number functions from Javascript The Definitive Guide by David Flanagan

function Complex(real, imaginary) {
this.x = real;
this.y = imaginary;
}

// return magnitude of complex number
Complex.prototype.magnitude = function() {
return Math.sqrt(this.x * this.x + this.y * this.y);
};

//return a complex number that is the negative of input
Complex.prototype.negative = function() {
return new Complex(-this.x, -this.y);
};

//return the real portion of a complex number
Complex.prototype.valueOf = function() { return this.x; };

Complex.add = function (a, b) {
return new Complex(a.x + b.x, a.y + b.y);
};

//subtract two complex numbers
Complex.subtract = function (a, b) {
return new Complex(a.x - b.x, a.y - b.y);
};

//multiply two complex numbers
Complex.multiply = function (a, b) {
return new Complex(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
};

//divide two complex numbers
Complex.divide = function (a, b) {
var cmod2 = b.x * b.x + b.y * b.y;
var temp = new Complex(b.x / cmod2, -b.y / cmod2);
return new Complex.multiply(a, temp);
};

//scale a complex number
Complex.scale = function (a, s) {
return new Complex(a.x * s, a.y * s);
};

//power of a complex number
Complex.power = function(a, p) {
if (p>0) {
var ans = new Complex(a.x, a.y);
for (il=1; il<p; il++) ans = Complex.multiply(ans, a);
}
else {
var ans = new Complex(1, 1);
}
return new Complex(ans.x,ans.y);
};

Complex.prototype.toString = function() {
return "{" + this.x + "," + this.y + "}";
};

var a =  6378388.0;
var n0 = 6023150.0;
var e0 = 2510000.0;
var lt0 = -41.0;
var ln0 = 173.0;

var cfi = new Array(0.6399175073,
-0.1358797613,
0.063294409,
-0.02526853,
0.0117879,
-0.0055161,
0.0026906,
-0.001333,
0.00067,
-0.00034);

var cfl = new Array(1.5627014243,
0.5185406398,
-0.03333098,
-0.1052906,
-0.0368594,
0.007317,
0.01220,
0.00394,
-0.0013 );

var cfb1 = new Array(6);
cfb1[0] = new Complex(0.7557853228,           0.0);
cfb1[1] = new Complex(0.249204646,   0.003371507);
cfb1[2] = new Complex(-0.001541739,   0.041058560);
cfb1[3] = new Complex(-0.10162907,    0.01727609);
cfb1[4] = new Complex(-0.26623489,   -0.36249218);
cfb1[5] = new Complex(-0.6870983,    -1.1651967);

var cfb2 = new Array(6);
cfb2[0] = new Complex(1.3231270439,           0.0);
cfb2[1] = new Complex(-0.577245789,  -0.007809598);
cfb2[2] = new Complex(0.508307513,  -0.112208952);
cfb2[3] = new Complex(-0.15094762,    0.18200602);
cfb2[4] = new Complex(1.01418179,    1.64497696);
cfb2[5] = new Complex(1.9660549,     2.5127645);

function calcRandB(form, in1, in2, in3, in4) {             //calculate plane grid range and bearing
// in1 - point 1 coordinates index
// in2 - point 2 coordinates index
// in3 - distance index
// in4 - bearing index
var de = parseFloat(form.east[in2].value) - parseFloat(form.east[in1].value);  //difference in eastings
var dn = parseFloat(form.north[in2].value) - parseFloat(form.north[in1].value);  //difference in northings

form.distvalue[in3].value = Math.sqrt(de * de + dn * dn);          //compute distance
form.distvalue[in3].value = roundoff(form.distvalue[in3].value,distsize);  //round off distance

var x = Math.atan2(de,dn);    //compute bearing, result in radians
if (x < 0) {
x += 2 * pi;             //if negative add 2*pi or 360 degrees
}
return true;
}

function calcPoint(form, in1, in2, in3, in4) {           //calculate grid coordinates from plane grid range and bearing
// in1 - point 1 coordinates index
// in2 - point 2 coordinates index
// in3 - distance index
// in4 - bearing index

var x = dms2ddd(form.degreevalue[in4].value, form.minutevalue[in4].value, form.secondvalue[in4].value);  //convert to decimal degrees
var dn = parseFloat(form.distvalue[in3].value) * Math.cos(x) ;
var de = parseFloat(form.distvalue[in3].value) * Math.sin(x) ;
form.north[in2].value = parseFloat(form.north[in1].value) + dn;
form.east[in2].value = parseFloat(form.east[in1].value) + de;
form.north[in2].value = roundoff(form.north[in2].value,distsize);
form.east[in2].value = roundoff(form.east[in2].value,distsize);
return true;
}

x = x * pi / 180;
return x;
}

x = x * 180 / pi;
return x;
}

function roundoff(x,y){              //round off x to y decimal places
x = parseFloat(x);
y = parseFloat(y);
x = Math.round(x * Math.pow(10,y))/Math.pow(10,y);
return x;
}

function dms2ddd(d,m,s){

if (isblank(d)) d = '0';
else {
var y = d.slice(0, 1);
d = parseFloat(d);
}
if (isblank(m)) m = '0';
else
m = parseFloat(m);
if (isblank(s)) s = '0';
else
s = parseFloat(s);
var x = Math.abs(d) + (Math.abs(m) / 60) + (Math.abs(s) / 3600);  //convert to decimal degrees
if ((y == "-") || (d < 0) || (m < 0) || (s < 0)) x = -x;
return x;

}

function isblank(s)
{
for(var i = 0; i < s.length; i++) {
var c = s.charAt(i);
if ((c != ' ') && (c != '\n') && (c != '\t')) return false;
}
return true;
}

function geo2grid(form, in1, in2, in3, in4, in5){
// in1 - point latitude index
// in2 - point longitude index
// in3 - point grid coordinates
// in4 - grid convergence index
// in5 - point scale factor index

var a =  6378388.0;
var n0 = 6023150.0;
var e0 = 2510000.0;
var lt0 = -41.0;
var ln0 = 173.0;

var latddd = dms2ddd(form.degreevalue[in1].value, form.minutevalue[in1].value, form.secondvalue[in1].value);  // convert latitude of point to decimal degrees then radians
var londdd = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude

var lt = (latddd - lt0) * 0.03600;
var sum = 0;
for (i=0; i < 10; i++) {
sum = sum + cfi[i] * Math.pow(lt, i + 1);
}

var z1 = new Complex(sum, deg2rad(londdd - ln0));

var z0 = new Complex(0,0);
var z2 = new Complex(0,0);
var z3 = new Complex(0,0);

for (ij=0; ij<6; ij++) {
z2 = Complex.power(z1, ij+1);
z3 = Complex.multiply(cfb1[ij], z2);
}
form.north[in3].value = n0 + z0.x * a;
form.east[in3].value = e0 + z0.y * a;
}

function grid2geo(form, in1, in2, in3, in4, in5){
// in1 - point latitude index
// in2 - point longitude index
// in3 - point grid coordinates
// in4 - grid convergence index
// in5 - point scale factor index

var a =  6378388.0;
var n0 = 6023150.0;
var e0 = 2510000.0;
var lt0 = -41.0;
var ln0 = 173.0;

var north = parseFloat(form.north[in3].value);
var east = parseFloat(form.east[in3].value);

var z = new Complex((north - n0)/a, (east - e0)/a);

var z1 = new Complex(0,0);
var z2 = new Complex(0,0);
var z3 = new Complex(0,0);
for (ij=0; ij<6; ij++) {
z2 = Complex.power(z,ij+1);
z3 = Complex.multiply(cfb2[ij],z2);
}
for (kk=0; kk<2; kk++) {
z2 = new Complex(0,0);
for (ij=2; ij<7; ij++) {
}

z3 = new Complex(cfb1[0].x, cfb1[0].y);

}
var dphi = 0;
for (ij=1; ij<10; ij++) {
dphi = dphi + cfl[ij-1] * Math.pow(z1.x,ij);
}

var latdeg = lt0 + (dphi * 100000 / 3600);
var londeg = ln0 + rad2deg(z1.y);

ddd2dms(form, in1, latdeg);
ddd2dms(form, in2, londeg);
}

function tttghg() {
// calclulate constants required for Redfern's formulae
var k = parseFloat(form.k.value);  //scale factor
var a = parseFloat(form.a.value);  //semi-major axis
var f = 1 / parseFloat(form.invf.value);  //flattening
var b = a * (1 - f);    //semi-minor axis
var e2 = (a * a - b * b)/(a * a);  //eccentricity squared
var e = Math.sqrt(e2);  //eccentricity
var ei2 = (a * a - b * b)/(b * b); //second eccentricity squared
var ei = Math.sqrt(ei2); //second eccentricity
var n = (a - b)/(a + b);
var G = a * (1 - n) * (1 - n * n) * (1 + (9 / 4) * n * n + (255 / 64) * Math.pow(n,4)) * (pi / 180);  //Mean length of an arc of one degree of the meridian
var north = (parseFloat(form.north[in3].value) - parseFloat(form.falsenorth.value)) * units;  //northing from the equator
var east = (parseFloat(form.east[in3].value) - parseFloat(form.falseeast.value)) * units; //easting from the CM
var m = north / k;  //meridian distance
var sigma = (m * pi) / (180 * G);

// calculate the foot point latitude and constants for that latitude
var footlat = sigma + ((3 * n / 2) - (27 * Math.pow(n, 3) / 32)) * Math.sin(2 * sigma) + ((21 * n * n / 16) - (55 * Math.pow(n, 4) / 32)) * Math.sin(4 * sigma) + (151 * Math.pow(n, 3) / 96) * Math.sin(6 * sigma) + (1097 * Math.pow(n, 4) / 512) * Math.sin(8 * sigma);
var rho = a * (1 - e2) / Math.pow(1 - (e2 * Math.sin(footlat) * Math.sin(footlat)),(3/2)); //radius of curvature in plane of meridian
var nu = a / Math.sqrt(1 - (e2 * Math.sin(footlat) * Math.sin(footlat))); //radius of curvature in prime vertical
var psi = nu / rho;
var t = Math.tan(footlat);  //tan of latitude

// calculate latitude
var x = east / (k * nu);
var laterm1 = (t / (k * rho )) * ( east * x / 2);
var laterm2 = (t / (k * rho )) * ( east * Math.pow(x, 3) / 24) * (-4 * psi * psi + 9 * psi * (1 - t * t) + 12 * t * t );
var laterm3 = (t / (k * rho )) * ( east * Math.pow(x, 5) / 720) * (8 * Math.pow(psi, 4) * (11 - 24 * t * t) - 12 * Math.pow(psi, 3) * (21 - 71 * t * t) + 15 * psi * psi * (15 - 98 * t * t + 15 * Math.pow(t, 4)) + 180 * psi * (5 * t * t - 3 * Math.pow(t, 4)) + 360 * Math.pow(t, 4));
var laterm4 = (t / (k * rho )) * ( east * Math.pow(x, 7) / 40320) * (1385 + 3633 * t * t + 4095 * Math.pow(t, 4) + 1575 * Math.pow(t, 6));
var latrad = footlat - laterm1 + laterm2 - laterm3 + laterm4;

// calculate longitude
var seclat = 1 / Math.cos(footlat);
var loterm1 = x * seclat;
var loterm2 = (Math.pow(x, 3) / 6) * seclat * (psi + 2 * t * t);
var loterm3 = (Math.pow(x, 5) / 120) * seclat * (-4 * Math.pow(psi, 3) * (1 - 6 * t * t) + psi * psi * (9 -68 * t * t) + 72 * psi * t * t + 24 * Math.pow(t, 4));
var loterm4 = (Math.pow(x, 7) / 5040) * seclat * (61 + 662 * t * t + 1320 * Math.pow(t, 4) + 720 * Math.pow(t, 6));
var w = loterm1 - loterm2 + loterm3 - loterm4;

// calculate grid convergence
var gterm1 = -t * x;
var gterm2 = (t * Math.pow(x, 3) / 3) * (-2 * psi * psi + 3 * psi + t * t);
var gterm3 = (-t * Math.pow(x, 5) / 15) * (Math.pow(psi, 4) * (11 - 24 * t * t) - 3 * Math.pow(psi, 3) * (8 - 23 * t * t) + 5 * psi * psi * (3 - 14 * t * t) + 30 * psi * t * t + 3 * Math.pow(t, 4));
var gterm4 = (t * Math.pow(x, 7) / 315) * (17 +77 * t * t + 105 * Math.pow(t, 4) + 45 * Math.pow(t, 6));
var gridconv = gterm1 + gterm2 + gterm3 + gterm4;

// calculate point scale factor
x = east * east / (k * k * rho * nu);
var kterm1 = x / 2;
var kterm2 = (x * x / 24) * (4 * psi * (1 - 6 * t * t) - 3 * (1 - 16 * t * t) - 24 * t * t / psi);
var kterm3 = Math.pow(x, 3) / 720 ;
var pointk = k * (1 + kterm1 + kterm2 + kterm3);
form.pointk[in5].value = roundoff(pointk, bearsize);

return true;
}

function calcRandBgeo(form, in1, in2, in3, in4, in5, in6){
// in1 - point 1 latitude index
// in2 - point 1 longitude index
// in3 - point 2 latitude index
// in4 - point 2 longitude index
// in5 - distance index
// in6 - bearing index

var j = form.units.selectedIndex;
var units = form.units.options[j].value;

// calclulate constants
//  var k = parseFloat(form.k.value);  //scale factor
var a = parseFloat(form.a.value);  //semi-major axis
var f = 1 / parseFloat(form.invf.value);  //flattening
var b = a * (1 - f);    //semi-minor axis

var latddd1 = dms2ddd(form.degreevalue[in1].value, form.minutevalue[in1].value, form.secondvalue[in1].value);  // convert latitude of point to decimal degrees then radians
var londdd1 = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude
var latddd2 = dms2ddd(form.degreevalue[in3].value, form.minutevalue[in3].value, form.secondvalue[in3].value);  // convert latitude of point to decimal degrees then radians
var londdd2 = dms2ddd(form.degreevalue[in4].value, form.minutevalue[in4].value, form.secondvalue[in4].value);  // likewise for longitude

if (Math.abs(w) > 1.5707963268) {
alert("Sorry this calculator isn't designed for such large distances.\nTry my Great Circle Calculator instead.");
}
var tanB1 = Math.tan(latrad1) * (1 - f);
var tanB2 = Math.tan(latrad2) * (1 - f);
var B1 = Math.atan(tanB1);
var B2 = Math.atan(tanB2);

var term1 = Math.sin(w) * Math.cos(B2);
var term2 = Math.sin(B2) * Math.cos(B1) - Math.sin(B1) * Math.cos(B2) * Math.cos(w);
var phi = Math.asin(Math.sqrt(term1 * term1 + term2 * term2));
var c = (Math.cos(B1) * Math.cos(B2) * Math.sin(w)) / Math.sin(phi);
var m = 1 - c * c;

term1 = phi * (1 + f + f * f)
term2 = Math.sin(B1) * Math.sin(B2) * ((f + f * f) * Math.sin(phi) - ((f * f / 2) * phi * phi / Math.sin(phi)));
var term3 = m * (-1 * (phi * (f + f * f) / 2) - ((f + f * f) / 2) * Math.sin(phi) * Math.cos(phi) + ((f * f / 2) * phi * phi) / Math.tan(phi));
var term4 = Math.sin(B1) * Math.sin(B2) * Math.sin(B1) * Math.sin(B2) * (-1 * (f * f /2) * Math.sin(phi) * Math.cos(phi));
var term5 = m * m * ((f * f / 16 ) * phi + (f * f / 16) * Math.sin(phi) * Math.cos(phi) - (f * f / 2) * phi * phi / Math.tan(phi) - (f * f / 8) * Math.sin(phi) * Math.pow(Math.cos(phi), 3));
var term6 = Math.sin(B1) * Math.sin(B2) * m * ((f * f / 2) * phi * phi / Math.sin(phi) + (f * f / 2) * Math.sin(phi) * Math.cos(phi) * Math.cos(phi));
var s = b * (term1 + term2 + term3 + term4 + term5 + term6);
form.distvalue[in5].value = roundoff((s / units), distsize);  //round off distance

term1 = (f + f * f) * phi;
term2 = Math.sin(B1) * Math.sin(B2) * ( -1 * (f * f / 2) * Math.sin(phi) - f * f * phi * phi / Math.sin(phi));
term3 = m * (-1 * (5 * f * f / 4) * phi + (f * f /4) * Math.sin(phi) * Math.cos(phi) + f * f * phi * phi / Math.tan(phi));
lamda = c * (term1 + term2 + term3) + w;

var de = Math.sin(B2) * Math.cos(B1) - Math.cos(lamda) * Math.sin(B1) * Math.cos(B2);
var dn = Math.sin(lamda) * Math.cos(B2);
var x = Math.atan2(dn,de);    //compute bearing, result in radians
if (x < 0) {
x += 2 * pi;             //if negative add 2*pi or 360 degrees
}

if (w == 0) {
if (latddd2 < latddd1)
x =  pi;
else if (latddd2 > latddd1)
x = 0;
else if (latddd2 == latddd1) {
x = 0;
form.distvalue[in5].value = roundoff(0, distsize);  //round off distance
}
}

return true;
}

function calcPointgeo(form, in1, in2, in3, in4, in5, in6){
// in1 - point 1 latitude index
// in2 - point 1 longitude index
// in3 - point 2 latitude index
// in4 - point 2 longitude index
// in5 - distance index
// in6 - bearing index

var j = form.units.selectedIndex;
var units = form.units.options[j].value;

// calclulate constants
//  var k = parseFloat(form.k.value);  //scale factor
var a = parseFloat(form.a.value);  //semi-major axis
var f = 1 / parseFloat(form.invf.value);  //flattening
var b = a * (1 - f);    //semi-minor axis
var e2 = (a * a - b * b)/(a * a);  //eccentricity squared
var e = Math.sqrt(e2);  //eccentricity
var ei2 = (a * a - b * b)/(b * b); //second eccentricity squared
var ei = Math.sqrt(ei2); //second eccentricity

var latddd1 = dms2ddd(form.degreevalue[in1].value, form.minutevalue[in1].value, form.secondvalue[in1].value);  // convert latitude of point to decimal degrees then radians
var londdd1 = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude
var x12 = dms2ddd(form.degreevalue[in6].value, form.minutevalue[in6].value, form.secondvalue[in6].value);  //convert to decimal degrees
var s = (parseFloat(form.distvalue[in5].value) * units);

if (Math.abs(s) > 10019148.059) {
alert("Sorry this calculator isn't designed for such large distances.\nTry my Great Circle Calculator instead.");
}
var tanB1 = Math.tan(latrad1) * (1 - f);
var B1 = Math.atan(tanB1);
var cosB0 = Math.cos(B1) * Math.sin(x12);
var B0 = Math.acos(cosB0);
var g = Math.cos(B1) * Math.cos(x12);
var m = (1 + (ei2 / 2) * Math.sin(B1) * Math.sin(B1)) * (1 - Math.cos(B0) * Math.cos(B0));
var phis = s / b;
var a1 = (1 + (ei2 / 2) * Math.sin(B1) * Math.sin(B1)) * (Math.sin(B1) * Math.sin(B1) * Math.cos(phis) + g * Math.sin(B1) * Math.sin(phis));

var term1 = a1 * (-1 * (ei2 / 2) * Math.sin(phis));
var term2 = m * (-1 * (ei2 / 4) * phis + (ei2 / 4) * Math.sin(phis) * Math.cos(phis));
var term3 = a1 * a1 * ((5 * ei2 * ei2 / 8) * Math.sin(phis) * Math.cos(phis));
var term4 = m * m * (( 11 * ei2 * ei2 / 64) * phis - (13 * ei2 * ei2 / 64) * Math.sin(phis) * Math.cos(phis) - (ei2 * ei2 / 8) * phis * Math.cos(phis) * Math.cos(phis) + (5 * ei2 * ei2 / 32) * Math.sin(phis) * Math.pow(Math.cos(phis), 3));
var term5 = a1 * m * ((3 * ei2 * ei2 / 8) * Math.sin(phis) + (ei2 * ei2 /4) * phis * Math.cos(phis) - (5 * ei2 * ei2 / 8) * Math.sin(phis) * Math.cos(phis) * Math.cos(phis));
var phi0 = phis + term1 + term2 + term3 + term4 + term5;

var cotlamda = (Math.cos(B1) * Math.cos(phi0) - Math.sin(B1) * Math.sin(phi0) * Math.cos(x12)) / (Math.sin(phi0) * Math.sin(x12));
var lamda = Math.atan(1 / cotlamda);

term1 = -1 * f * phis;
term2 = a1 * ((3 * f * f / 2) * Math.sin(phis));
term3 = m * ((3 * f * f / 4) * phis - (3 * f * f / 4) * Math.sin(phis) * Math.cos(phis));
var w = (term1 + term2 + term3) * Math.cos(B0) + lamda;

var sinB2 = Math.sin(B1) * Math.cos(phi0) + g * Math.sin(phi0);
var cosB2 = Math.sqrt((Math.cos(B0) * Math.cos(B0)) + Math.pow((g * Math.cos(phi0) - Math.sin(B1) * Math.sin(phi0)), 2));
var tanB2 = sinB2 / cosB2;
var tanlat2 = tanB2 / (1 - f);

return true;
}

function ddd2dms(form, ind, bearing){
var y = Math.abs(parseFloat(bearing));
form.degreevalue[ind].value = parseInt(y + 1) - 1;
var x = y - form.degreevalue[ind].value;
form.minutevalue[ind].value = parseInt(x * 60 + 1) - 1;
form.secondvalue[ind].value = ((x * 60) - form.minutevalue[ind].value) * 60;
form.secondvalue[ind].value = roundoff(form.secondvalue[ind].value,secsize);
if (form.secondvalue[ind].value == 60) {
form.secondvalue[ind].value = "0";
form.minutevalue[ind].value = form.minutevalue[ind].value * 1 + 1;
if (form.minutevalue[ind].value == 60) {
form.minutevalue[ind].value = "0";
form.degreevalue[ind].value = form.degreevalue[ind].value * 1 + 1;
}
}
if (bearing < 0) {
if (form.degreevalue[ind].value != 0)
form.degreevalue[ind].value = -form.degreevalue[ind].value;
else if (form.minutevalue[ind].value != 0)
form.minutevalue[ind].value = -form.minutevalue[ind].value;
else
form.secondvalue[ind].value = -form.secondvalue[ind].value;
}
form.degreevalue[ind].value += "\260";                                        // add degrees symbol now we have finished with value
form.minutevalue[ind].value += "\'";                                        //add minute symbol now we have finished with value
form.secondvalue[ind].value += '\"';               //round off seconds and add symbol
return true;
}

function confirmSphChange(form){             //to only allow changes to spheroid parameters if in user defined mode

var i = form.spheroid.selectedIndex;
if (i != 22) {
form.a.blur();
form.invf.blur();
alert("\n To override Spheroid Parameters\n use the User Defined option.");
}
return true;
}

var i = form.spheroid.selectedIndex;
switch(i) {
case 0:
form.a.value = 6378388.000;
form.invf.value = 297.000;
break;
}
return true;
}

function confirmProjChange(form){             //to only allow changes to projection parameters if in user defined mode

var i = form.projection.selectedIndex;
if (i != 2) {
form.falsenorth.blur();
form.falseeast.blur();
form.k.blur();
alert("\n To override Projection Parameters\n use the User Defined option.");
}
return true;
}

function updateProjection(form, x){

var i = form.projection.selectedIndex;
var j = form.units.selectedIndex;
var units = form.units.options[j].value;
switch(i) {
case 0:
form.falsenorth.value = 0;
form.falseeast.value = 500000 / units;
form.k.value = 0.9996;
break;
case 1:
form.falsenorth.value = 10000000 / units;
form.falseeast.value = 500000 / units;
form.k.value = 0.9996;
break;
case 2:
if (x == 1) {                  // only reset if called from projection selection not grid units
form.falsenorth.value = '';
form.falseeast.value = '';
form.k.value = '';
}
break;
}
}

function swapgeos(form){
var x = form.degreevalue[0].value;
form.degreevalue[0].value = form.degreevalue[5].value;
form.degreevalue[5].value = x;
x = form.degreevalue[1].value;
form.degreevalue[1].value = form.degreevalue[6].value;
form.degreevalue[6].value = x;

x = form.minutevalue[0].value;
form.minutevalue[0].value = form.minutevalue[5].value;
form.minutevalue[5].value = x;
x = form.minutevalue[1].value;
form.minutevalue[1].value = form.minutevalue[6].value;
form.minutevalue[6].value = x;

x = form.secondvalue[0].value;
form.secondvalue[0].value = form.secondvalue[5].value;
form.secondvalue[5].value = x;
x = form.secondvalue[1].value;
form.secondvalue[1].value = form.secondvalue[6].value;
form.secondvalue[6].value = x;
return true;
}

function swapgrid(form){
var x = form.north[0].value;
form.north[0].value = form.north[1].value;
form.north[1].value = x;
x = form.east[0].value;
form.east[0].value = form.east[1].value;
form.east[1].value = x;
return true;
}

function updateCM(form){
var zone = parseFloat(form.zone.value);
if ((zone < 1) || (zone > 60) || isblank(form.zone.value)) {
form.zone.value = "";
form.zone.focus();
}
else {
form.cmlong.value =  zone * 6 - 183 + "\260";
}
}

function updateZone(form){
var cmlong = parseFloat(form.cmlong.value);
if ((cmlong < -180) || (cmlong > 180) || isblank(form.cmlong.value)) {
form.cmlong.value = "";
form.cmlong.focus();
}
else {
form.zone.value = roundoff(((cmlong + 183) / 6), 2);
}
}

//-->
</SCRIPT>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

<body>

<FORM name=geodetics onreset="return confirm('Erase ALL data and start over?')">
<TABLE width="100%">
<TBODY>
<TR>
<TD> <TABLE width="100%" border=1>
<TBODY>
<TR>
<TBODY>
<TR> </TR>
</TBODY>
</TABLE>
<table>
<tbody>
<tr>
<td>Spheroid:</td>
<td colspan=2><select name=spheroid>
<option
selected>International 1924</option>
</select> </td>
<td>Projection:</td>
<td><select onChange="updateProjection(this.form, 1)"
name=projection>
<option selected>NZMG</option>
</select> </td>
</tr>
<tr>
<td>Semi-Major Axis:</td>
</tr>
<tr>
<td>Inverse Flattening:</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>Grid Units:</td>
<td colspan=2><select name=units>
<option value=1
selected>Metres</option>
</select> </td>
</tr>
<tr>
</tr>
<tr>
<td>Latitude <br>
( - south): </td>
<td><input size=12 value=0Â° name=degreevalue></td>
<td><input size=4 value="0'" name=minutevalue></td>
<td><input size=6 value='0"' name=secondvalue></td>
<td><input name="button" type=button onClick="geo2grid(this.form, 0, 1, 0, 2, 0)" value=" Lat/Lon to N/E "></td>
<td>Northing:</td>
<td><input size=12 value=0 name=north></td>
</tr>
<tr>
<td>Longitude <br>
( - west): </td>
<td><input size=12 value=0Â° name=degreevalue></td>
<td><input size=4 value="0'" name=minutevalue></td>
<td><input size=6 value='0"' name=secondvalue></td>
<td><input name="button" type=button onClick="grid2geo(this.form, 0, 1, 0, 2, 0)" value=" N/E to Lat/Lon "></td>
<td>Easting:</td>
<td><input size=12 value=0 name=east></td>
</tr>
<tr>
<td></td>
<td><input type=hidden size=12 value=0Â° name=degreevalue></td>
<td><input type=hidden size=4 value="0'" name=minutevalue></td>
<td><input type=hidden size=6 value='0"' name=secondvalue></td>
<td> <h3>
<center>
Point 1
</center>
</h3></td>
<td></td>
<td><input type=hidden size=12 value=0 name=pointk></td>
</tr>
<tr>
</tr>
<tr>
<td>Ellipsoidal Distance:</td>
<td><input size=12 value=0 name=distvalue></td>
<td></td>
<td></td>
<td></td>
<td>Grid Distance:</td>
<td><input size=12 value=0 name=distvalue></td>
</tr>
<tr>
<tr>
<td>True Bearing: </td>
<td><input size=12 value=0Â° name=degreevalue></td>
<td><input size=4 value="0'" name=minutevalue></td>
<td><input size=6 value='0"' name=secondvalue></td>
<td></td>
<td>Grid Bearing: </td>
<td><input size=12 value=0Â° name=degreevalue></td>
<td><input size=4 value="0'" name=minutevalue></td>
<td><input size=6 value='0"' name=secondvalue></td>
</tr>
<tr>
<td></td>
<td><input name="button" type=button onClick="calcRandBgeo(this.form, 0, 1, 5, 6, 0, 3)" value="Calc R &amp; B"></td>
<td colspan=2><input name="button" type=button onClick="calcPointgeo(this.form, 0, 1, 5, 6, 0, 3)" value="Calc Point 2"></td>
<td></td>
<td></td>
<td><input name="button" type=button onClick="calcRandB(this.form, 0, 1, 1, 4)" value="Calc R &amp; B"></td>
<td colspan=2><input name="button" type=button onClick="calcPoint(this.form, 0, 1, 1, 4)" value="Calc Point 2"></td>
</tr>
<tr>
<td colspan=9> <hr> </td>
</tr>
<tr>
<td>Latitude <br>
( - south): </td>
<td><input size=12 value=0Â° name=degreevalue></td>
<td><input size=4 value="0'" name=minutevalue></td>
<td><input size=6 value='0"' name=secondvalue></td>
<td><input name="button" type=button onClick="geo2grid(this.form, 5, 6, 1, 7, 1)" value=" Lat/Lon to N/E "></td>
<td>Northing:</td>
<td><input size=12 value=0 name=north></td>
</tr>
<tr>
<td>Longitude <br>
( - west): </td>
<td><input size=12 value=0Â° name=degreevalue></td>
<td><input size=4 value="0'" name=minutevalue></td>
<td><input size=6 value='0"' name=secondvalue></td>
<td><input name="button" type=button onClick="grid2geo(this.form, 5, 6, 1, 7, 1)" value=" N/E to Lat/Lon "></td>
<td>Easting:</td>
<td><input size=12 value=0 name=east></td>
</tr>
<tr>
<td></td>
<td><input type=hidden size=12 value=0Â° name=degreevalue></td>
<td><input type=hidden size=4 value="0'" name=minutevalue></td>
<td><input type=hidden size=6 value='0"' name=secondvalue></td>
<td> <h3>
<center>
Point 2
</center>
</h3></td>
<td></td>
<td><input type=hidden size=12 value=0 name=pointk></td>
</tr>
<tr>
<td></td>
<td><input name="button" type=button onClick=swapgeos(form) value="Swap 1 &amp; 2"></td>
<td></td>
<td></td>
<td><input name="reset" type=reset value="Reset Fields"></td>
<td></td>
<td><input name="button" type=button onClick=swapgrid(form) value="Swap 1 &amp; 2"></td>
</tr>
</tbody>
</table></TD>
</TR>
</TBODY>
</TABLE></TD>
</TR>
</TBODY>
</TABLE>
</FORM>
<p></P>
</body>
</html>

'/End code
0

LVL 15

Accepted Solution

bpmurray earned 2000 total points
ID: 17142261
OK, here's the functionality. I'll assume that you know how to handle the form stuff - if not, please say so. It requires the complex class from my response above, and here is the module that consumes that class. Note that this is VB.Net. Anyway, here's the main module:

Module Geolib
Dim pi = Math.PI
Dim secsize As Integer = 4      ' round second display to
Dim distsize As Integer = 3      ' round distance display to
Dim bearsize As Integer = 8
Dim a As Double = 6378388.0
Dim n0 As Double = 6023150.0
Dim e0 As Double = 2510000.0
Dim lt0 As Double = -41.0
Dim ln0 As Double = 173.0

Dim cfi() As Double = {0.6399175073, -0.1358797613, 0.063294409, -0.02526853, 0.0117879, _
-0.0055161, 0.0026906, -0.001333, 0.00067, -0.00034}

Dim cfl() As Double = {0.5627014243, 0.5185406398, -0.03333098, -0.1052906, -0.0368594, _
0.007317, 0.0122, 0.00394, -0.0013}

Dim cfb1() As Complex = {New Complex(0.7557853228, 0.0), New Complex(0.249204646, 0.003371507), _
New Complex(-0.001541739, 0.04105856), New Complex(-0.10162907, 0.01727609), _
New Complex(-0.26623489, -0.36249218), New Complex(-0.6870983, -1.1651967)}

Dim cfb2() As Complex = {New Complex(1.3231270439, 0.0), New Complex(-0.577245789, -0.007809598), _
New Complex(0.508307513, -0.112208952), New Complex(-0.15094762, 0.18200602), _
New Complex(1.01418179, 1.64497696), New Complex(1.9660549, 2.5127645)}

Function calcRandB(ByVal form As FormType, ByVal in1 As Integer, ByVal in2 As Integer, ByVal in3 As Integer, ByVal in4 As Integer) As Boolean             ' calculate plane grid range and bearing
'  in1 - point 1 coordinates index
'  in2 - point 2 coordinates index
'  in3 - distance index
'  in4 - bearing index
Dim de As Double = CDbl(form.east(in2).value) - CDbl(form.east(in1).value)  ' difference in eastings
Dim dn As Double = CDbl(form.north(in2).value) - CDbl(form.north(in1).value)  ' difference in northings

form.distvalue(in3).value = Math.Sqrt(de * de + dn * dn)          ' compute distance
form.distvalue(in3).value = roundoff(form.distvalue(in3).value, distsize)  ' round off distance

Dim x As Double = Math.Atan2(de, dn)    ' compute bearing, result in radians
If (x < 0) Then
x += 2 * pi             ' If negative add 2*pi or 360 degrees
End If
Return True
End Function

Function calcPoint(ByVal form As FormType, ByVal in1 As Integer, ByVal in2 As Integer, ByVal in3 As Integer, ByVal in4 As Integer) As Boolean           ' calculate grid coordinates from plane grid range and bearing
'  in1 - point 1 coordinates index
'  in2 - point 2 coordinates index
'  in3 - distance index
'  in4 - bearing index

Dim x As Double = dms2ddd(form.degreevalue(in4).value, form.minutevalue(in4).value, form.secondvalue(in4).value)  ' convert to decimal degrees
Dim dn As Double = CDbl(form.distvalue(in3).value) * Math.Cos(x)
Dim de As Double = CDbl(form.distvalue(in3).value) * Math.Sin(x)
form.north(in2).value = CDbl(form.north(in1).value) + dn
form.east(in2).value = CDbl(form.east(in1).value) + de
form.north(in2).value = roundoff(form.north(in2).value, distsize)
form.east(in2).value = roundoff(form.east(in2).value, distsize)
Return True
End Function

x = x * pi / 180
Return x
End Function

x = x * 180 / pi
Return x
End Function

Function roundoff(ByVal x, ByVal y) As Double              ' round off x to y decimal places
x = CDbl(x)
y = CDbl(y)
x = Math.Round(x * Math.Pow(10, y)) / Math.Pow(10, y)
Return x
End Function

Function dms2ddd(ByVal ds As String, ByVal ms As String, ByVal ss As String) As Double
Dim d As Double
Dim m As Double
Dim y As String = ""
Dim s As Double
If (isblank(ds)) Then
d = 0
Else
y = Left(d, 1)
d = CDbl(d)
End If
If (isblank(ms)) Then
m = 0
Else
m = CDbl(m)
End If
If (isblank(ss)) Then
s = 0
Else
s = CDbl(s)
End If
Dim x As Double = Math.Abs(d) + (Math.Abs(m) / 60) + (Math.Abs(s) / 3600)  ' convert to decimal degrees
If ((y = "-") Or (d < 0) Or (m < 0) Or (s < 0)) Then
x = -x
End If
Return x
End Function

Function isblank(ByVal s As String) As Boolean
Dim temp As String = s.Trim()
If temp.Length = 0 Then
Return True
Else
Return False
End If
End Function

Sub geo2grid(ByVal form As FormType, ByVal in1 As Integer, ByVal in2 As Integer, ByVal in3 As Integer, ByVal in4 As Integer, ByVal in5 As Integer)
'  in1 - point latitude index
'  in2 - point longitude index
'  in3 - point grid coordinates
'  in4 - grid convergence index
'  in5 - point scale factor index

Dim a As Double = 6378388.0
Dim n0 As Double = 6023150.0
Dim e0 As Double = 2510000.0
Dim lt0 As Double = -41.0
Dim ln0 As Double = 173.0

Dim latddd As Double = dms2ddd(form.degreevalue(in1).value, form.minutevalue(in1).value, form.secondvalue(in1).value)  '  convert latitude of point to decimal degrees then radians
Dim londdd As Double = dms2ddd(form.degreevalue(in2).value, form.minutevalue(in2).value, form.secondvalue(in2).value)  '  likewise for longitude

Dim lt As Double = (latddd - lt0) * 0.036
Dim sum As Double = 0
Dim i As Integer
For i = 0 To 10
sum = sum + cfi(i) * Math.Pow(lt, i + 1)
Next i

Dim z1 As Complex = New Complex(sum, deg2rad(londdd - ln0))

Dim z0 As Complex = New Complex(0, 0)
Dim z2 As Complex = New Complex(0, 0)
Dim z3 As Complex = New Complex(0, 0)

Dim ij As Integer
For ij = 0 To 6
z2 = z1.power(ij + 1)
z3 = z2.multiply(cfb1(ij))
Next ij
form.north(in3).value = n0 + z0.x * a
form.east(in3).value = e0 + z0.y * a
End Sub

Sub grid2geo(ByVal form, ByVal in1, ByVal in2, ByVal in3, ByVal in4, ByVal in5)
'  in1 - point latitude index
'  in2 - point longitude index
'  in3 - point grid coordinates
'  in4 - grid convergence index
'  in5 - point scale factor index

Dim a As Double = 6378388.0
Dim n0 As Double = 6023150.0
Dim e0 As Double = 2510000.0
Dim lt0 As Double = -41.0
Dim ln0 As Double = 173.0

Dim north As Double = CDbl(form.north(in3).value)
Dim east As Double = CDbl(form.east(in3).value)

Dim z As Complex = New Complex((north - n0) / a, (east - e0) / a)

Dim z1 As Complex = New Complex(0, 0)
Dim z2 As Complex = New Complex(0, 0)
Dim z3 As Complex = New Complex(0, 0)
Dim ij As Integer
For ij = 0 To 6
z2 = z.power(ij + 1)
z3 = z2.multiply(cfb2(ij))
Next ij
Dim kk As Integer
For kk = 0 To 2
z2 = New Complex(0, 0)
For ij = 2 To 7
z2 = z2.add(z1.power(ij).multiply(cfb1(ij - 1).scale(ij - 1)))
Next ij

z3 = New Complex(cfb1(0).x, cfb1(0).y)

Next kk
Dim dphi As Double = 0
For ij = 1 To 10
dphi = dphi + cfl(ij - 1) * Math.Pow(z1.x, ij)
Next ij

Dim latdeg As Double = lt0 + (dphi * 100000 / 3600)
Dim londeg As Double = ln0 + rad2deg(z1.y)

ddd2dms(form, in1, latdeg)
ddd2dms(form, in2, londeg)
End Sub

Function tttghg() As Boolean
'  calclulate constants required for Redfern's formulae
Dim k As Double = CDbl(form.k.value)  ' scale factor
Dim a As Double = CDbl(form.a.value)  ' semi-major axis
Dim f As Double = 1 / CDbl(form.invf.value)  ' flattening
Dim b As Double = a * (1 - f)    ' semi-minor axis
Dim e2 As Double = (a * a - b * b) / (a * a)  ' eccentricity squared
Dim e As Double = Math.Sqrt(e2)  ' eccentricity
Dim ei2 As Double = (a * a - b * b) / (b * b) ' second eccentricity squared
Dim ei As Double = Math.Sqrt(ei2) ' second eccentricity
Dim n As Double = (a - b) / (a + b)
Dim G As Double = a * (1 - n) * (1 - n * n) * (1 + (9 / 4) * n * n + (255 / 64) * Math.Pow(n, 4)) * (pi / 180)  ' Mean length of an arc of one degree of the meridian
Dim north As Double = (CDbl(form.north(in3).value) - CDbl(form.falsenorth.value)) * units  ' northing from the equator
Dim east As Double = (CDbl(form.east(in3).value) - CDbl(form.falseeast.value)) * units ' easting from the CM
Dim m As Double = north / k  ' meridian distance
Dim sigma As Double = (m * pi) / (180 * G)

'  calculate the foot point latitude and constants for that latitude
Dim footlat As Double = sigma + ((3 * n / 2) - (27 * Math.Pow(n, 3) / 32)) * Math.Sin(2 * sigma) + ((21 * n * n / 16) - (55 * Math.Pow(n, 4) / 32)) * Math.Sin(4 * sigma) + (151 * Math.Pow(n, 3) / 96) * Math.Sin(6 * sigma) + (1097 * Math.Pow(n, 4) / 512) * Math.Sin(8 * sigma)
Dim rho As Double = a * (1 - e2) / Math.Pow(1 - (e2 * Math.Sin(footlat) * Math.Sin(footlat)), (3 / 2)) ' radius of curvature in plane of meridian
Dim nu As Double = a / Math.Sqrt(1 - (e2 * Math.Sin(footlat) * Math.Sin(footlat))) ' radius of curvature in prime vertical
Dim psi As Double = nu / rho
Dim t As Double = Math.Tan(footlat)  ' tan of latitude

'  calculate latitude
Dim x As Double = east / (k * nu)
Dim laterm1 As Double = (t / (k * rho)) * (east * x / 2)
Dim laterm2 As Double = (t / (k * rho)) * (east * Math.Pow(x, 3) / 24) * (-4 * psi * psi + 9 * psi * (1 - t * t) + 12 * t * t)
Dim laterm3 As Double = (t / (k * rho)) * (east * Math.Pow(x, 5) / 720) * (8 * Math.Pow(psi, 4) * (11 - 24 * t * t) - 12 * Math.Pow(psi, 3) * (21 - 71 * t * t) + 15 * psi * psi * (15 - 98 * t * t + 15 * Math.Pow(t, 4)) + 180 * psi * (5 * t * t - 3 * Math.Pow(t, 4)) + 360 * Math.Pow(t, 4))
Dim laterm4 As Double = (t / (k * rho)) * (east * Math.Pow(x, 7) / 40320) * (1385 + 3633 * t * t + 4095 * Math.Pow(t, 4) + 1575 * Math.Pow(t, 6))
Dim latrad As Double = footlat - laterm1 + laterm2 - laterm3 + laterm4

'  calculate longitude
Dim seclat As Double = 1 / Math.Cos(footlat)
Dim loterm1 As Double = x * seclat
Dim loterm2 As Double = (Math.Pow(x, 3) / 6) * seclat * (psi + 2 * t * t)
Dim loterm3 As Double = (Math.Pow(x, 5) / 120) * seclat * (-4 * Math.Pow(psi, 3) * (1 - 6 * t * t) + psi * psi * (9 - 68 * t * t) + 72 * psi * t * t + 24 * Math.Pow(t, 4))
Dim loterm4 As Double = (Math.Pow(x, 7) / 5040) * seclat * (61 + 662 * t * t + 1320 * Math.Pow(t, 4) + 720 * Math.Pow(t, 6))
Dim w As Double = loterm1 - loterm2 + loterm3 - loterm4

'  calculate grid convergence
Dim gterm1 As Double = -t * x
Dim gterm2 As Double = (t * Math.Pow(x, 3) / 3) * (-2 * psi * psi + 3 * psi + t * t)
Dim gterm3 As Double = (-t * Math.Pow(x, 5) / 15) * (Math.Pow(psi, 4) * (11 - 24 * t * t) - 3 * Math.Pow(psi, 3) * (8 - 23 * t * t) + 5 * psi * psi * (3 - 14 * t * t) + 30 * psi * t * t + 3 * Math.Pow(t, 4))
Dim gterm4 As Double = (t * Math.Pow(x, 7) / 315) * (17 + 77 * t * t + 105 * Math.Pow(t, 4) + 45 * Math.Pow(t, 6))
Dim gridconv As Double = gterm1 + gterm2 + gterm3 + gterm4

'  calculate point scale factor
x = east * east / (k * k * rho * nu)
Dim kterm1 = x / 2
Dim kterm2 = (x * x / 24) * (4 * psi * (1 - 6 * t * t) - 3 * (1 - 16 * t * t) - 24 * t * t / psi)
Dim kterm3 As Double = Math.Pow(x, 3) / 720
Dim pointk = k * (1 + kterm1 + kterm2 + kterm3)
form.pointk(in5).value = roundoff(pointk, bearsize)

Return True
End Function

Function calcRandBgeo(ByVal form, ByVal in1, ByVal in2, ByVal in3, ByVal in4, ByVal in5, ByVal in6) As Boolean
'  in1 - point 1 latitude index
'  in2 - point 1 longitude index
'  in3 - point 2 latitude index
'  in4 - point 2 longitude index
'  in5 - distance index
'  in6 - bearing index

Dim j As Double = form.units.selectedIndex
Dim units = form.units.options(j).value

'  calclulate constants
'   Dim k  As Double = CDbl(form.k.value)  ' scale factor
Dim a As Double = CDbl(form.a.value)  ' semi-major axis
Dim f As Double = 1 / CDbl(form.invf.value)  ' flattening
Dim b As Double = a * (1 - f)    ' semi-minor axis

Dim latddd1 = dms2ddd(form.degreevalue(in1).value, form.minutevalue(in1).value, form.secondvalue(in1).value)  '  convert latitude of point to decimal degrees then radians
Dim londdd1 = dms2ddd(form.degreevalue(in2).value, form.minutevalue(in2).value, form.secondvalue(in2).value)  '  likewise for longitude
Dim latddd2 = dms2ddd(form.degreevalue(in3).value, form.minutevalue(in3).value, form.secondvalue(in3).value)  '  convert latitude of point to decimal degrees then radians
Dim londdd2 = dms2ddd(form.degreevalue(in4).value, form.minutevalue(in4).value, form.secondvalue(in4).value)  '  likewise for longitude

If (Math.Abs(w) > 1.5707963268) Then
MsgBox("Sorry this calculator isn't designed for such large distances.\nTry my Great Circle Calculator instead.")
End If
Dim tanB1 As Double = Math.Tan(latrad1) * (1 - f)
Dim tanB2 As Double = Math.Tan(latrad2) * (1 - f)
Dim B1 As Double = Math.Atan(tanB1)
Dim B2 As Double = Math.Atan(tanB2)

Dim term1 As Double = Math.Sin(w) * Math.Cos(B2)
Dim term2 As Double = Math.Sin(B2) * Math.Cos(B1) - Math.Sin(B1) * Math.Cos(B2) * Math.Cos(w)
Dim phi As Double = Math.Asin(Math.Sqrt(term1 * term1 + term2 * term2))
Dim c As Double = (Math.Cos(B1) * Math.Cos(B2) * Math.Sin(w)) / Math.Sin(phi)
Dim m As Double = 1 - c * c

term1 = phi * (1 + f + f * f)
term2 = Math.Sin(B1) * Math.Sin(B2) * ((f + f * f) * Math.Sin(phi) - ((f * f / 2) * phi * phi / Math.Sin(phi)))
Dim term3 As Double = m * (-1 * (phi * (f + f * f) / 2) - ((f + f * f) / 2) * Math.Sin(phi) * Math.Cos(phi) + ((f * f / 2) * phi * phi) / Math.Tan(phi))
Dim term4 As Double = Math.Sin(B1) * Math.Sin(B2) * Math.Sin(B1) * Math.Sin(B2) * (-1 * (f * f / 2) * Math.Sin(phi) * Math.Cos(phi))
Dim term5 As Double = m * m * ((f * f / 16) * phi + (f * f / 16) * Math.Sin(phi) * Math.Cos(phi) - (f * f / 2) * phi * phi / Math.Tan(phi) - (f * f / 8) * Math.Sin(phi) * Math.Pow(Math.Cos(phi), 3))
Dim term6 As Double = Math.Sin(B1) * Math.Sin(B2) * m * ((f * f / 2) * phi * phi / Math.Sin(phi) + (f * f / 2) * Math.Sin(phi) * Math.Cos(phi) * Math.Cos(phi))
Dim s As Double = b * (term1 + term2 + term3 + term4 + term5 + term6)
form.distvalue(in5).value = roundoff((s / units), distsize)  ' round off distance

term1 = (f + f * f) * phi
term2 = Math.Sin(B1) * Math.Sin(B2) * (-1 * (f * f / 2) * Math.Sin(phi) - f * f * phi * phi / Math.Sin(phi))
term3 = m * (-1 * (5 * f * f / 4) * phi + (f * f / 4) * Math.Sin(phi) * Math.Cos(phi) + f * f * phi * phi / Math.Tan(phi))
lamda = c * (term1 + term2 + term3) + w

Dim de As Double = Math.Sin(B2) * Math.Cos(B1) - Math.Cos(lamda) * Math.Sin(B1) * Math.Cos(B2)
Dim dn As Double = Math.Sin(lamda) * Math.Cos(B2)
Dim x As Double = Math.Atan2(dn, de)    ' compute bearing, result in radians
If (x < 0) Then
x += 2 * pi             ' If negative add 2*pi or 360 degrees
End If

If (w = 0) Then
If (latddd2 < latddd1) Then
x = pi
ElseIf (latddd2 > latddd1) Then
x = 0
ElseIf (latddd2 = latddd1) Then
x = 0
form.distvalue(in5).value = roundoff(0, distsize)  ' round off distance
End If
End If
Return True
End Function

Function calcPointgeo(ByVal form As FormType, ByVal in1 As Integer, ByVal in2 As Integer, ByVal in3 As Integer, ByVal in4 As Integer, ByVal in5 As Integer, ByVal in6 As Integer) As Boolean
'  in1 - point 1 latitude index
'  in2 - point 1 longitude index
'  in3 - point 2 latitude index
'  in4 - point 2 longitude index
'  in5 - distance index
'  in6 - bearing index

Dim j As Double = form.units.selectedIndex
Dim units = form.units.options(j).value

'  calclulate constants
'   Dim k  As Double = CDbl(form.k.value)  ' scale factor
Dim a As Double = CDbl(form.a.value)  ' semi-major axis
Dim f As Double = 1 / CDbl(form.invf.value)  ' flattening
Dim b As Double = a * (1 - f)    ' semi-minor axis
Dim e2 = (a * a - b * b) / (a * a)  ' eccentricity squared
Dim e As Double = Math.Sqrt(e2)  ' eccentricity
Dim ei2 = (a * a - b * b) / (b * b) ' second eccentricity squared
Dim ei As Double = Math.Sqrt(ei2) ' second eccentricity

Dim latddd1 = dms2ddd(form.degreevalue(in1).value, form.minutevalue(in1).value, form.secondvalue(in1).value)  '  convert latitude of point to decimal degrees then radians
Dim londdd1 = dms2ddd(form.degreevalue(in2).value, form.minutevalue(in2).value, form.secondvalue(in2).value)  '  likewise for longitude
Dim x12 = dms2ddd(form.degreevalue(in6).value, form.minutevalue(in6).value, form.secondvalue(in6).value)  ' convert to decimal degrees
Dim s As Double = (CDbl(form.distvalue(in5).value) * units)

If (Math.Abs(s) > 10019148.059) Then
MsgBox("Sorry this calculator isn't designed for such large distances.\nTry my Great Circle Calculator instead.")
End If
Dim tanB1 As Double = Math.Tan(latrad1) * (1 - f)
Dim B1 As Double = Math.Atan(tanB1)
Dim cosB0 As Double = Math.Cos(B1) * Math.Sin(x12)
Dim B0 As Double = Math.Acos(cosB0)
Dim g As Double = Math.Cos(B1) * Math.Cos(x12)
Dim m As Double = (1 + (ei2 / 2) * Math.Sin(B1) * Math.Sin(B1)) * (1 - Math.Cos(B0) * Math.Cos(B0))
Dim phis = s / b
Dim a1 As Double = (1 + (ei2 / 2) * Math.Sin(B1) * Math.Sin(B1)) * (Math.Sin(B1) * Math.Sin(B1) * Math.Cos(phis) + g * Math.Sin(B1) * Math.Sin(phis))

Dim term1 As Double = a1 * (-1 * (ei2 / 2) * Math.Sin(phis))
Dim term2 As Double = m * (-1 * (ei2 / 4) * phis + (ei2 / 4) * Math.Sin(phis) * Math.Cos(phis))
Dim term3 As Double = a1 * a1 * ((5 * ei2 * ei2 / 8) * Math.Sin(phis) * Math.Cos(phis))
Dim term4 As Double = m * m * ((11 * ei2 * ei2 / 64) * phis - (13 * ei2 * ei2 / 64) * Math.Sin(phis) * Math.Cos(phis) - (ei2 * ei2 / 8) * phis * Math.Cos(phis) * Math.Cos(phis) + (5 * ei2 * ei2 / 32) * Math.Sin(phis) * Math.Pow(Math.Cos(phis), 3))
Dim term5 As Double = a1 * m * ((3 * ei2 * ei2 / 8) * Math.Sin(phis) + (ei2 * ei2 / 4) * phis * Math.Cos(phis) - (5 * ei2 * ei2 / 8) * Math.Sin(phis) * Math.Cos(phis) * Math.Cos(phis))
Dim phi0 = phis + term1 + term2 + term3 + term4 + term5

Dim cotlamda As Double = (Math.Cos(B1) * Math.Cos(phi0) - Math.Sin(B1) * Math.Sin(phi0) * Math.Cos(x12)) / (Math.Sin(phi0) * Math.Sin(x12))
Dim lamda As Double = Math.Atan(1 / cotlamda)

term1 = -1 * f * phis
term2 = a1 * ((3 * f * f / 2) * Math.Sin(phis))
term3 = m * ((3 * f * f / 4) * phis - (3 * f * f / 4) * Math.Sin(phis) * Math.Cos(phis))
Dim w As Double = (term1 + term2 + term3) * Math.Cos(B0) + lamda

Dim sinB2 As Double = Math.Sin(B1) * Math.Cos(phi0) + g * Math.Sin(phi0)
Dim cosB2 As Double = Math.Sqrt((Math.Cos(B0) * Math.Cos(B0)) + Math.Pow((g * Math.Cos(phi0) - Math.Sin(B1) * Math.Sin(phi0)), 2))
Dim tanB2 = sinB2 / cosB2
Dim tanlat2 = tanB2 / (1 - f)
Dim latrad2 As Double = Math.Atan(tanlat2)

Return True
End Function

Function ddd2dms(ByVal form As FormType, ByVal ind As Integer, ByVal bearing) As Boolean
Dim y As Double = Math.Abs(CDbl(bearing))
form.degreevalue(ind).value = CInt(y + 1) - 1
Dim x As Double = y - form.degreevalue(ind).value
form.minutevalue(ind).value = CInt(x * 60 + 1) - 1
form.secondvalue(ind).value = ((x * 60) - form.minutevalue(ind).value) * 60
form.secondvalue(ind).value = roundoff(form.secondvalue(ind).value, secsize)
If (form.secondvalue(ind).value = 60) Then
form.secondvalue(ind).value = "0"
form.minutevalue(ind).value = form.minutevalue(ind).value * 1 + 1
If (form.minutevalue(ind).value = 60) Then
form.minutevalue(ind).value = "0"
form.degreevalue(ind).value = form.degreevalue(ind).value * 1 + 1
End If
End If
If (bearing < 0) Then
If (form.degreevalue(ind).value <> 0) Then
form.degreevalue(ind).value = -form.degreevalue(ind).value
ElseIf (form.minutevalue(ind).value <> 0) Then
form.minutevalue(ind).value = -form.minutevalue(ind).value
Else
form.secondvalue(ind).value = -form.secondvalue(ind).value
End If
End If
form.degreevalue(ind).value += "\260"                                        '  add degrees symbol now we have finished with value
form.minutevalue(ind).value += "\'"                                        ' add minute symbol now we have finished with value
With form.secondvalue(ind)
value = value + '\"'               ' round off seconds and add symbol
End With
Return True
End Function

Function confirmSphChange(ByVal form) As Boolean             ' to only allow changes to spheroid parameters If in user defined mode

Dim i As Double = form.spheroid.selectedIndex
If (i <> 22) Then
form.a.blur()
form.invf.blur()
MsgBox("\n To override Spheroid Parameters\n use the User Defined option.")
End If
Return True
End Function

Dim i As Double = form.spheroid.selectedIndex
Select Case i
Case 0
form.a.value = 6378388.0
form.invf.value = 297.0
End Select
Return True
End Function

Function confirmProjChange(ByVal form) As Boolean             ' to only allow changes to projection parameters If in user defined mode

Dim i As Double = form.projection.selectedIndex
If (i <> 2) Then
form.falsenorth.blur()
form.falseeast.blur()
form.k.blur()
MsgBox("\n To override Projection Parameters\n use the User Defined option.")
End If
Return True
End Function

Sub updateProjection(ByVal form, ByVal x As Integer)

Dim i As Double = form.projection.selectedIndex
Dim j As Double = form.units.selectedIndex
Dim units = form.units.options(j).value
Select Case i
Case 0
form.falsenorth.value = 0
form.falseeast.value = 500000 / units
form.k.value = 0.9996

Case 1
form.falsenorth.value = 10000000 / units
form.falseeast.value = 500000 / units
form.k.value = 0.9996

Case 2
If (x = 1) Then                  '  only reset If called from projection selection not grid units
form.falsenorth.value = ''
form.falseeast.value = ''
form.k.value = ''
End If

End Select
End Sub

Function swapgeos(ByVal form) As Boolean
Dim x As Double = form.degreevalue(0).value
form.degreevalue(0).value = form.degreevalue(5).value
form.degreevalue(5).value = x
x = form.degreevalue(1).value
form.degreevalue(1).value = form.degreevalue(6).value
form.degreevalue(6).value = x

x = form.minutevalue(0).value
form.minutevalue(0).value = form.minutevalue(5).value
form.minutevalue(5).value = x
x = form.minutevalue(1).value
form.minutevalue(1).value = form.minutevalue(6).value
form.minutevalue(6).value = x

x = form.secondvalue(0).value
form.secondvalue(0).value = form.secondvalue(5).value
form.secondvalue(5).value = x
x = form.secondvalue(1).value
form.secondvalue(1).value = form.secondvalue(6).value
form.secondvalue(6).value = x
Return True
End Function

Function swapgrid(ByVal form) As Boolean
Dim x As Double = form.north(0).value
form.north(0).value = form.north(1).value
form.north(1).value = x
x = form.east(0).value
form.east(0).value = form.east(1).value
form.east(1).value = x
Return True
End Function

Sub updateCM(ByVal form)
Dim zone As Double = CDbl(form.zone.value)
If ((zone < 1) Or (zone > 60) Or isblank(form.zone.value)) Then
form.zone.value = ""
MsgBox("\n  Please enter a UTM Zone number\n between 1 and 60.")
form.zone.focus()
Else
form.cmlong.value = zone * 6 - 183 + "\260"
End If
End Sub

Sub updateZone(ByVal form)
Dim cmlong As Double = CDbl(form.cmlong.value)
If ((cmlong < -180) Or (cmlong > 180) Or isblank(form.cmlong.value)) Then
form.cmlong.value = ""
MsgBox("\n Please enter a Longitude of Central Meridian between +/- 180\260")
form.cmlong.focus()
Else
form.zone.value = roundoff(((cmlong + 183) / 6), 2)
End If
End Sub

End Module
0

LVL 1

Author Comment

ID: 17142668
Hi Again bpmurray,

Could you give me a quick rundown of the form stuff...

For instance form.east(in2).value

In the case of the field "east" how does the in2 work? How can i pass variables to the function?
0

LVL 1

Author Comment

ID: 17143503
I found out how i can get it to work, however, I get an error in the for loop:

Index was outside the bounds of the array

This is the code from the Geo2Grid function

Dim a As Double = 6378388.0
Dim n0 As Double = 6023150.0
Dim e0 As Double = 2510000.0
Dim lt0 As Double = -41.0
Dim ln0 As Double = 173.0

Dim latddd As Double = dms2ddd(Val(Me.latDeg.Text), Val(Me.latMin.Text), Val(Me.latSec.Text))  '  convert latitude of point to decimal degrees then radians
Dim londdd As Double = dms2ddd(Val(Me.lonDeg.Text), Val(Me.lonMin.Text), Val(Me.lonSec.Text))  '  likewise for longitude

Debug.Print(latddd)
Debug.Print(londdd)

Dim lt As Double = (latddd - lt0) * 0.036
Dim sum As Double = 0
Dim i As Integer
For i = 0 To 10
sum = sum + cfi(i) * Math.Pow(lt, i + 1)    '<--index was outside the bounds of the array
Next i

Dim z1 As Complex = New Complex(sum, deg2rad(londdd - ln0))

Dim z0 As Complex = New Complex(0, 0)
Dim z2 As Complex = New Complex(0, 0)
Dim z3 As Complex = New Complex(0, 0)

Dim ij As Integer
For ij = 0 To 6
z2 = z1.power(ij + 1)
z3 = z2.multiply(cfb1(ij))
Next ij
Me.North.Text = n0 + z0.x * a
Me.East.Text = e0 + z0.y * a
0

LVL 15

Expert Comment

ID: 17144074
Oops! You're dead right: that's an error. In fact, all the FOR-loops are incorrect; the to-value should be 1 less. So this particular example should be:

For i = 0 To 9  ' <============== reduce by 1 from 10
sum = sum + cfi(i) * Math.Pow(lt, i + 1)    '<--index was outside the bounds of the array
Next i

Dim z1 As Complex = New Complex(sum, deg2rad(londdd - ln0))

Dim z0 As Complex = New Complex(0, 0)
Dim z2 As Complex = New Complex(0, 0)
Dim z3 As Complex = New Complex(0, 0)

Dim ij As Integer
For ij = 0 To 5 ' <============== reduce by 1 from 6
z2 = z1.power(ij + 1)

There are a few more (actually 8 altogether) that need to be adjusted.
0

LVL 1

Author Comment

ID: 17144969
Ok, here's the update - you're really going to hate me now! I am starting to work with just that function for now and have reduced the to-value to 1 less than what it was.

Now the error I get is: "Arithmetic operation resulted in an overflow."
the location of the error is:

Public Function multiply(ByVal b As Complex) As Complex
Return New Complex(Me.x * b.x - Me.y * b.y, Me.x * b.y + Me.y * b.x)
End Function

Just for your info, my test data is -34 degrees, 24 minutes, 2 seconds and 174 degrees east, 34 minutes and 1 second.

0

LVL 15

Expert Comment

ID: 17145876
Can you display what the Me.x & y and b.x & y values are, please. That may tell what the problem is.
0

LVL 1

Author Comment

ID: 17148979
Here is what the values are when it breaks,

+            Me      {NZMGCalc.Complex}      NZMGCalc.Complex
Me.x      &H283E100      Integer
Me.y      &HFA98A000      Integer
+            b      {NZMGCalc.Complex}      NZMGCalc.Complex
b.x      &H283E100      Integer
b.y      &HFA98A000      Integer
multiply      Nothing      NZMGCalc.Complex
0

LVL 15

Expert Comment

ID: 17149201
Wow! They are biiiiiiiiiiig! No wonder there's an overflow. The multiply method itself should be OK, so the problem is where it's called from. Which method are you testing?
0

LVL 1

Author Comment

ID: 17151555
Yep, it sure is!!

Here is the sub, which is the code from the Geo2Grid function, with the variables hardcoded, well, not really hard coded, but taken from a textbox.

The values for example are:
latDeg = -34 latMin = 22 latSec = 2
lonDeg = 174 lonMin = 32 lonSec = 0

'/Begin Code
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim a As Double = 6378388.0
Dim n0 As Double = 6023150.0
Dim e0 As Double = 2510000.0
Dim lt0 As Double = -41.0
Dim ln0 As Double = 173.0

Dim latddd As Double = dms2ddd(Val(Me.latDeg.Text), Val(Me.latMin.Text), Val(Me.latSec.Text))  '  convert latitude of point to decimal degrees then radians
Dim londdd As Double = dms2ddd(Val(Me.lonDeg.Text), Val(Me.lonMin.Text), Val(Me.lonSec.Text))  '  likewise for longitude

Debug.Print(latddd)
Debug.Print(londdd)

Dim lt As Double = (latddd - lt0) * 0.036
Dim sum As Double = 0
Dim i As Integer
For i = 0 To 9 'was 10
sum = sum + cfi(i) * Math.Pow(lt, i + 1)
Next i

Dim z1 As Complex = New Complex(sum, deg2rad(londdd - ln0))

Dim z0 As Complex = New Complex(0, 0)
Dim z2 As Complex = New Complex(0, 0)
Dim z3 As Complex = New Complex(0, 0)

Dim ij As Integer
For ij = 0 To 5 'was 6
z2 = z1.power(ij + 1)
z3 = z2.multiply(cfb1(ij))
Next ij
Me.North.Text = n0 + z0.x * a
Me.East.Text = e0 + z0.y * a
End Sub

'/End code
0

LVL 15

Expert Comment

ID: 17152545
It seems to work OK for me - can you check your implementations of these:

Function dms2ddd(ByVal d As Double, ByVal m As Double, ByVal s As Double) As Double
Dim x As Double = Math.Abs(d) + (Math.Abs(m) / 60) + (Math.Abs(s) / 3600)  ' convert to decimal degrees
If ((d < 0) Or (m < 0) Or (s < 0)) Then
x = -x
End If
Return x
End Function

Function deg2rad(ByVal x As Double) As Double                ' convert decimal degrees to radians
x = x * pi / 180
Return x
End Function
0

LVL 15

Expert Comment

ID: 17152552
Oh, the Debug.print statements output this:
-34.3672222222222
104.533333333333
-34.3672222222222
104.533333333333
0

LVL 1

Author Comment

ID: 17171555
i changed that function to the code you supplied above and the answers now give:

North 6023150
East 2510000

Even if I change the latitude/longitude within reason ie a few degrees, I get the same answer!!

In the web page I get the following, (Using the above lat long)

The answer should be North = 6758066.224704542 and East = 2652129.2868528683

Sorry that this is such a hassle Brendan. I really appreciate your help.

Sean
0

LVL 15

Expert Comment

ID: 17178400
Since the results are integral, it looks like some value has been converted to an integer and lost its precision. The results are within a few percent of the expected values, so this seems very likely. Perhaps the best solution is to go through the classes and change any integer to a double. The Complex types seem OK to me, so it's really only the other calculations that need to be tweaked.
0

LVL 1

Author Comment

ID: 17179556
Okie dokie, Here is an update.

I have changed the offending Ints and get better results with using doubles, but still a bit off...

I've been comparing what I should get with the js version and about 500 odd metres off, so maybe again a precision thing.

Cheers,
Sean
0

LVL 1

Author Comment

ID: 17179930
Second update: Changing the types in the complex class changes it. I found that changing the ints in the following gave more of the right answer.

Public Sub New(ByVal real As Double, ByVal imaginary As Double) 'both int
x = real
y = imaginary
End Sub
0

LVL 15

Expert Comment

ID: 17180178
That's interesting: it shouldn't really be an issue, although division would result in rounded results, which may be where the error occurs. If this is the case, you should also update all Integers in that class file to Double.
0

LVL 1

Author Comment

ID: 17180947
Yep, tried that and still get a small error when I compare the values I get back from this code against the js version.

Any suggestions on how to debug it....well I should say "tweak" :)
0

LVL 15

Expert Comment

ID: 17182962
UNfortunately, I don't know what you actually have as code any more :-)

Perhaps this small difference is in the UI to internal value conversion? That's a common place to lose accuracy. Try a debug display of some of the calculations, and compare these with the equivalents in the web page - use alert() calls there.
0

LVL 1

Author Comment

ID: 17188121
Thats exactly what I will do...

I'm going to accept this now anyway and if I still have any queries I might have to post back. :)

Thanks a million
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Whether youâ€™re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
If you are a mobile app developer and especially develop hybrid mobile apps then these 4 mistakes you must avoid for hybrid app development to be the more genuine app developer.
Six Sigma Control Plans
Progress
###### Suggested Courses
Course of the Month9 days, 6 hours left to enroll