rhumb line calculation - javascript to php

2020-08-26 14:33发布

问题:

This example and java script code is from link text
Look at the section on rhumb lines.


Given a start point and a distance d along constant bearing θ, this will calculate the destination point. If you maintain a constant bearing along a rhumb line, you will gradually spiral in towards one of the poles.

Formula:

  α = d/R (angular distance)   
  lat2 = lat1 + α.cos(θ)   
  Δφ = ln(tan(lat2/2+π/4)/tan(lat1/2+π/4)) [= the ‘stretched’ latitude difference] 
if E:W line q = cos(lat1)    
otherwise q = Δlat/Δφ   
  Δlon = α.sin(θ)/q   
  lon2 = (lon1+Δlon+π) % 2.π − π   
  where ln is natural log and % is modulo, Δlon is taking shortest route (<180°), and R is the earth’s radius 

JavaScript:

lat2 = lat1 + d*Math.cos(brng);
var dPhi = Math.log(Math.tan(lat2/2+Math.PI/4)/Math.tan(lat1/2+Math.PI/4));
var q = (!isNaN(dLat/dPhi)) ? dLat/dPhi : Math.cos(lat1);  // E-W line gives dPhi=0
var dLon = d*Math.sin(brng)/q;
// check for some daft bugger going past the pole, normalise latitude if so
if (Math.abs(lat2) > Math.PI/2) lat2 = lat2>0 ? Math.PI-lat2 : -(Math.PI-lat2);
lon2 = (lon1+dLon+Math.PI)%(2*Math.PI) - Math.PI; 

I am trying to convert it into php syntax but I am not getting the desired result. I have the latitude part working fine. I also included my test data.


MY PHP CODE

// test data
$R = 6371;
$tlatitude = 50.7;
$tlongitude = -105.214;
$theading = 124;
$d = 50;  

$projlat = $tlatitude +  rad2deg(($d/$R)*COS(deg2rad($theading)));

//Δφ = ln(tan(lat2/2+π/4)/tan(lat1/2+π/4))
$delta_phi = log(tan(deg2rad($projlat/2) + pi()/4)/(tan(deg2rad($tlatitude/2) + pi()/4)));

//q = Δlat/Δφ 
$delta_lat = deg2rad($projlat - $tlatitude);

$q = $delta_lat/$delta_phi;


//Δlon = α.sin(θ)/q
$delta_long = rad2deg($d/$R*sin(deg2rad($theading))/$q);

$projlong = $tlongitude + $delta_long;

I get $projlong = -104.84

according to the referenced page the answer should be -104.63.

Now I am trying to get this to work disregarding the east-west and over the pole possibilities.

回答1:

I had some problems when making distance calculations where my errors would grow quite a bit after a while. I discovered that if I made a cast to (double) in my code the precision increased. I have not looked in to the C-code in PHP to see what caused this though. I could after this scrap my BC-version of the code.

If you need additional precision please check out the BC-functions in PHP. http://php.net/manual/en/book.bc.php

Also, please remember that the order that you make calculations in a computer will affect your precision. That is, the calculation bellow

$d/$R*sin(deg2rad($theading))/$q

will not render the same result as

$d*sin(deg2rad($theading))/$q/$R

and this can also give a third result

 $d*sin(deg2rad($theading))/($q*$R)

This has to do with the limited precision for numbers close to zero (0) in computers.



回答2:

javascript has more precision than php look at this joke http://ru2.php.net/manual/en/function.doubleval.php

I once needed to check some IBAN with the Luhn's algorithm. My javascript code worked nicely. But my php failed, so after some research, i found the joke and had to recode basic operations (add, sub, compute, divide, modulo) based on string and not number.

Maybe should you recode it too, to get your expected precision. We should not use php for high precision calculations.