Link to home
Start Free TrialLog in
Avatar of nzfire
nzfire

asked on

Convert this JS to VB

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; };

//add two complex numbers
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
  }
  ddd2dms(form, in4, rad2deg(x));
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
  x = deg2rad(x);             //convert to radians
  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;
}


function deg2rad(x){                //convert decimal degrees to radians
   
  x = x * pi / 180;
  return x;
}

function rad2deg(x){                //convert radians to decimal degrees
   
  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 latrad = deg2rad(latddd);
  var londdd = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude
  var lonrad = deg2rad(londdd);

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);  
  z0 =  Complex.add(z0,z3);
}
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);
  z1 = Complex.add(z1, z3);
}
for (kk=0; kk<2; kk++) {
z2 = new Complex(0,0);
for (ij=2; ij<7; ij++) {
  z2 = Complex.add(z2,(Complex.multiply(Complex.power(z1,ij),Complex.scale(cfb1[ij-1],(ij-1)))));
}


 z3 = new Complex(cfb1[0].x, cfb1[0].y);
 z3 = Complex.add(z3, Complex.multiply(Complex.scale(cfb1[1],2),z1));
 z3 = Complex.add(z3, Complex.multiply(Complex.scale(cfb1[2],3),Complex.power(z1,2)));
 z3 = Complex.add(z3, Complex.multiply(Complex.scale(cfb1[3],4),Complex.power(z1,3)));
 z3 = Complex.add(z3, Complex.multiply(Complex.scale(cfb1[4],5),Complex.power(z1,4)));
 z3 = Complex.add(z3, Complex.multiply(Complex.scale(cfb1[5],6),Complex.power(z1,5)));

 z1 = Complex.divide(Complex.add(z,z2),z3);
}
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;

  ddd2dms(form, in1, rad2deg(latrad));
 
// 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;
  var longrad = deg2rad(parseFloat(form.cmlong.value)) + w;

  ddd2dms(form, in2, rad2deg(longrad));

// 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;

  ddd2dms(form, in4, rad2deg(gridconv));

// 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 latrad1 = deg2rad(latddd1);
  var londdd1 = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude
  var lonrad1 = deg2rad(londdd1);
  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 latrad2 = deg2rad(latddd2);
  var londdd2 = dms2ddd(form.degreevalue[in4].value, form.minutevalue[in4].value, form.secondvalue[in4].value);  // likewise for longitude
  var lonrad2 = deg2rad(londdd2);

  var w = lonrad2 - lonrad1;

  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
   }
}
  ddd2dms(form, in6, rad2deg(x));
   
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 latrad1 = deg2rad(latddd1);
  var londdd1 = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude
  var lonrad1 = deg2rad(londdd1);
  var x12 = dms2ddd(form.degreevalue[in6].value, form.minutevalue[in6].value, form.secondvalue[in6].value);  //convert to decimal degrees
  x12 = deg2rad(x12);             //convert to radians
  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 lonrad2 = lonrad1 + w;
  ddd2dms(form, in4, rad2deg(lonrad2));

  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);
  var latrad2 = Math.atan(tanlat2);
  ddd2dms(form, in3, rad2deg(latrad2));

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;
}
 
 

function updateSpheroid(form){

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 = "";
     alert("\n  Please enter a UTM Zone number\n between 1 and 60.");
     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 = "";
     alert("\n Please enter a Longitude of Central Meridian between +/- 180\260");
     form.cmlong.focus();
  }
  else {
     form.zone.value = roundoff(((cmlong + 183) / 6), 2);
  }
}


'End JS Code

Avatar of nzfire
nzfire

ASKER

Alternatively, I have 'C' source code to the above...
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

    ' add two complex numbers
    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
Avatar of nzfire

ASKER

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>
<head>
<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; };

//add two complex numbers
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
  }
  ddd2dms(form, in4, rad2deg(x));
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
  x = deg2rad(x);             //convert to radians
  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;
}


function deg2rad(x){                //convert decimal degrees to radians
   
  x = x * pi / 180;
  return x;
}

function rad2deg(x){                //convert radians to decimal degrees
   
  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 latrad = deg2rad(latddd);
  var londdd = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude
  var lonrad = deg2rad(londdd);

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);  
  z0 =  Complex.add(z0,z3);
}
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);
  z1 = Complex.add(z1, z3);
}
for (kk=0; kk<2; kk++) {
z2 = new Complex(0,0);
for (ij=2; ij<7; ij++) {
  z2 = Complex.add(z2,(Complex.multiply(Complex.power(z1,ij),Complex.scale(cfb1[ij-1],(ij-1)))));
}


 z3 = new Complex(cfb1[0].x, cfb1[0].y);
 z3 = Complex.add(z3, Complex.multiply(Complex.scale(cfb1[1],2),z1));
 z3 = Complex.add(z3, Complex.multiply(Complex.scale(cfb1[2],3),Complex.power(z1,2)));
 z3 = Complex.add(z3, Complex.multiply(Complex.scale(cfb1[3],4),Complex.power(z1,3)));
 z3 = Complex.add(z3, Complex.multiply(Complex.scale(cfb1[4],5),Complex.power(z1,4)));
 z3 = Complex.add(z3, Complex.multiply(Complex.scale(cfb1[5],6),Complex.power(z1,5)));

 z1 = Complex.divide(Complex.add(z,z2),z3);
}
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;

  ddd2dms(form, in1, rad2deg(latrad));
 
// 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;
  var longrad = deg2rad(parseFloat(form.cmlong.value)) + w;

  ddd2dms(form, in2, rad2deg(longrad));

// 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;

  ddd2dms(form, in4, rad2deg(gridconv));

// 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 latrad1 = deg2rad(latddd1);
  var londdd1 = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude
  var lonrad1 = deg2rad(londdd1);
  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 latrad2 = deg2rad(latddd2);
  var londdd2 = dms2ddd(form.degreevalue[in4].value, form.minutevalue[in4].value, form.secondvalue[in4].value);  // likewise for longitude
  var lonrad2 = deg2rad(londdd2);

  var w = lonrad2 - lonrad1;

  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
   }
}
  ddd2dms(form, in6, rad2deg(x));
   
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 latrad1 = deg2rad(latddd1);
  var londdd1 = dms2ddd(form.degreevalue[in2].value, form.minutevalue[in2].value, form.secondvalue[in2].value);  // likewise for longitude
  var lonrad1 = deg2rad(londdd1);
  var x12 = dms2ddd(form.degreevalue[in6].value, form.minutevalue[in6].value, form.secondvalue[in6].value);  //convert to decimal degrees
  x12 = deg2rad(x12);             //convert to radians
  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 lonrad2 = lonrad1 + w;
  ddd2dms(form, in4, rad2deg(lonrad2));

  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);
  var latrad2 = Math.atan(tanlat2);
  ddd2dms(form, in3, rad2deg(latrad2));

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;
}
 
 

function updateSpheroid(form){

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 = "";
     alert("\n  Please enter a UTM Zone number\n between 1 and 60.");
     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 = "";
     alert("\n Please enter a Longitude of Central Meridian between +/- 180\260");
     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">
</head>

<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>
                <TD> <TABLE cellPadding=0 width="100%" border=0>
                    <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>
                        <td><input readonly size=12 value=6378388.0 name=a></td>
                      </tr>
                      <tr>
                        <td>Inverse Flattening:</td>
                        <td><input readonly size=12 value=297 name=invf></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>
                        <td colspan=9> <hr noshade> </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, 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>
                        <td colspan=9> <hr noshade> </td>
                      </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
ASKER CERTIFIED SOLUTION
Avatar of bpmurray
bpmurray
Flag of Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nzfire

ASKER

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?
Avatar of nzfire

ASKER

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 latrad As Double = deg2rad(latddd)
        Dim londdd As Double = dms2ddd(Val(Me.lonDeg.Text), Val(Me.lonMin.Text), Val(Me.lonSec.Text))  '  likewise for longitude
        Dim lonrad As Double = deg2rad(londdd)

        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))
            z0 = z3.add(z0)
        Next ij
        Me.North.Text = n0 + z0.x * a
        Me.East.Text = e0 + z0.y * a
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.
Avatar of nzfire

ASKER

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.

Can you display what the Me.x & y and b.x & y values are, please. That may tell what the problem is.
Avatar of nzfire

ASKER

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
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?
Avatar of nzfire

ASKER

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 latrad As Double = deg2rad(latddd)
        Dim londdd As Double = dms2ddd(Val(Me.lonDeg.Text), Val(Me.lonMin.Text), Val(Me.lonSec.Text))  '  likewise for longitude
        Dim lonrad As Double = deg2rad(londdd)

        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))
            z0 = z3.add(z0)
        Next ij
        Me.North.Text = n0 + z0.x * a
        Me.East.Text = e0 + z0.y * a
    End Sub

'/End code
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
Oh, the Debug.print statements output this:
-34.3672222222222
104.533333333333
-34.3672222222222
104.533333333333
Avatar of nzfire

ASKER

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
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.
Avatar of nzfire

ASKER

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
Avatar of nzfire

ASKER

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
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.
Avatar of nzfire

ASKER

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" :)
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.
Avatar of nzfire

ASKER

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