converting javascript function, values dont match

BlitzMax Forums/BlitzMax Programming/converting javascript function, values dont match

NoOdle(Posted 2011) [#1]
I am attempting to convert the functions found on this website:

www.movable-type.co.uk/scripts/latlong.html

I decided to start with the distance function using the values and code extract from the bottom of the website.

The values I get from my conversion do not match and the conversion seemed pretty straight forward... am I missing something?

I have checked on another website to ensure that my implementation is the problem, and it is.


GfK(Posted 2011) [#2]
Haven't seen your code but the one on that site calculates in radians, rather than degrees (which Blitzmax uses). I assume you're taking that into consideration?


NoOdle(Posted 2011) [#3]
I am, well after the 3rd rewrite it works, not sure what I have done that is different but nvm...

Function Distance : Double ( lon1 : Double, lat1 : Double, lon2 : Double, lat2 : Double )
	Local RADIUS : Double = 6371
	Local dLon : Double = ((lon2 - lon1) * Pi ) / 180.0
	Local dLat : Double = ((lat2 - lat1) * Pi ) / 180.0
	Local a : Double = (Sin( dLat / 2 ) * Sin( dLat / 2 )) + Cos( lat1 ) * Cos( lat2 ) * (Sin( dLon / 2 ) * Sin( dLon / 2 ))
	Local angle : Double = 2 * ATan2( Sqr( a ), Sqr( 1 - a ))
	Return angle * RADIUS
End Function

Print Distance( -0.0983, 51.5136, -0.0015, 51.4778 )


Last edited 2011


NoOdle(Posted 2011) [#4]
http://www.movable-type.co.uk/scripts/latlong.html

I have successfully converted a few more of the functions contained on the website but I am having trouble with this:

/** 

 * Returns the destination point from this point having travelled the given distance (in km) on the  

 * given initial bearing (bearing may vary before destination is reached) 

 *   see http://williams.best.vwh.net/avform.htm#LL 

 * @param   {Number} brng: Initial bearing in degrees 

 * @param   {Number} dist: Distance in km 

 * @returns {LatLon} Destination point 

 */ 

LatLon.prototype.destinationPoint = Function(brng, dist) { 
  dist = dist/this._radius;  // convert dist To angular distance in radians 
  brng = brng.toRad();  //  
  Var lat1 = this._lat.toRad(), lon1 = this._lon.toRad(); 
  Var lat2 = ASin( Sin(lat1)*Cos(dist) + Cos(lat1)*Sin(dist)*Cos(brng) ); 
  Var lon2 = lon1 + ATan2(Sin(brng)*Sin(dist)*Cos(lat1), Cos(dist)-Sin(lat1)*Sin(lat2)); 
  lon2 = (lon2+3*Math.Pi)%(2*Math.Pi) - Math.Pi;  // normalise To -180...+180 
  Return New LatLon(lat2.toDeg(), lon2.toDeg()); 
}


On the website if you scroll down it shows all the different formulas with an example for each. I have been using dummy data to see if I can get my values to match. (if you scroll even further down you can select the format, you will need it in decimal degrees)

The values I'm using are: latitude 51.5136 longitude -0.0983 and anything for the bearing and distance.

Type GLoc
	Global EARTH_RADIUS : Double = 6371
	Field Latitude : Double
	Field Longitude : Double
	Function Create : GLoc( lat : Double, lon : Double )
		Local this : GLoc = New GLoc
		this.Latitude = lat
		this.Longitude = lon
		Return this
	End Function
End Type

Function DestinationPoint : GLoc( lon1 : Double, lat1 : Double, brng : Double, dist : Double )
	dist = dist / GLoc.EARTH_RADIUS
	Local lat2 : Double = ASin(( Sin( lat1 ) * Cos( dist )) + ( Cos( lat1 ) * Sin( dist ) * Cos( brng )))
	Local a : Double = Sin( brng ) * Sin( dist ) * Cos( lat1 )
	Local b : Double = Cos( dist ) - ( Sin( lat1 ) * Sin( lat2 ))
	Local lon2 : Double = lon1 + ATan2( a, b )
	lon2 = ( lon2 + 3.0 * Pi ) Mod ( 2.0 * Pi ) - Pi
	Return GLoc.Create( lat2, lon2)
End Function


The code above is wrong, I can't work out how to do it, my maths is really bad these days!

Would greatly appreciate any help on this :)

Last edited 2011


Jesse(Posted 2011) [#5]
I believe this line:
 
 lon2 = (lon2+3*Math.Pi)%(2*Math.Pi) - Math.Pi;  // normalise To -180...+180 

should be:
lon2 = (lon2+3*180.0) mod (2*180.0) - 180.0

or
lon2 =  (lon2+540.0) mod 360.0 - 180.0


Last edited 2011


NoOdle(Posted 2011) [#6]
thanks Jesse, after putting that in and fiddling a bit more, the longitude returns results that kind of work but something is still not quite right. Ill need to take a fresh look at this tomorrow. Typical to get stuck on the function I really needed :P

Function DestinationPoint : GLoc( lon1 : Double, lat1 : Double, brng : Double, dist : Double )
	dist = dist / GLoc.EARTH_RADIUS
	Local a : Double = Sin( lat1 ) * Cos( dist )
	Local b : Double = Cos( lat1 ) * Sin( dist ) * Cos( brng )
	Local lat2 : Double = ASin( a + b )
	Local c : Double = Sin( brng ) * Sin( dist ) * Cos( lat1 )
	Local d : Double = Cos( dist ) - Sin( lat1 ) * Sin( lat2 )
	Local lon2 : Double = lon1 + ATan2( c, d )
	lon2 = (( lon2 + 540.0 ) Mod 360.0 ) - 180.0
	Return GLoc.Create( lat2, lon2 )
End Function


does anyone else have any suggestions?

Last edited 2011

Last edited 2011


Jesse(Posted 2011) [#7]
I believe this is the right way to do it but not sure. untested!:
Function destinationPoint(brng:Double, dist:Double) 
  dist = dist/this._radius*(180.0/Pi);  ' convert dist To angular distance in degrees
  Local lat1:Double = this._lat, lon1:Double = this._lon 
  Local lat2:Double = ASin( Sin(lat1)*Cos(dist) + Cos(lat1)*Sin(dist)*Cos(brng) ); 
  Local lon2:Double = lon1 + ATan2(Sin(brng)*Sin(dist)*Cos(lat1), Cos(dist)-Sin(lat1)*Sin(lat2)); 
  lon2 = (lon2+3*180) Mod (2*180) - 180; ' normalise To -180...+180 
  Return New LatLon(lat2, lon2); 
End Function



NoOdle(Posted 2011) [#8]
Thanks Jesse, I completely forgot to change that part! I'll test it some more but it looks like the addition of dist = dist/radius*(180.0/Pi) was the missing bit.

Thanks again!