This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,25 @@
{{Wikipedia}}The '''haversine formula''' is an equation important in navigation, giving great-circle distances between two points on a sphere from their longitudes and latitudes. It is a special case of a more general formula in spherical trigonometry, the '''law of haversines''', relating the sides and angles of spherical "triangles".
'''Task:''' Implement a great-circle distance function, or use a library function, to show the great-circle distance between Nashville International Airport (BNA) in Nashville, TN, USA: N 36°7.2', W 86°40.2' (36.12, -86.67) and Los Angeles International Airport (LAX) in Los Angeles, CA, USA: N 33°56.4', W 118°24.0' (33.94, -118.40).
<pre>
User Kaimbridge clarified on the Talk page:
-- 6371.0 km is the authalic radius based on/extracted from surface area;
-- 6372.8 km is an approximation of the radius of the average circumference
(i.e., the average great-elliptic or great-circle radius), where the
boundaries are the meridian (6367.45 km) and the equator (6378.14 km).
Using either of these values results, of course, in differing distances:
6371.0 km -> 2886.44444283798329974715782394574671655 km;
6372.8 km -> 2887.25995060711033944886005029688505340 km;
(results extended for accuracy check: Given that the radii are only
approximations anyways, .01' ≈ 1.0621333 km and .001" ≈ .00177 km,
practical precision required is certainly no greater than about
.0000001——i.e., .1 mm!)
As distances are segments of great circles/circumferences, it is
recommended that the latter value (r = 6372.8 km) be used (which
most of the given solutions have already adopted, anyways).
</pre>

View file

@ -0,0 +1,22 @@
#!/usr/local/bin/a68g --script #
REAL r = 20 000/pi + 6.6 # km #,
to rad = pi/180;
PROC dist = (REAL th1 deg, ph1 deg, th2 deg, ph2 deg)REAL:
(
REAL ph1 = (ph1 deg - ph2 deg) * to rad,
th1 = th1 deg * to rad, th2 = th2 deg * to rad,
dz = sin(th1) - sin(th2),
dx = cos(ph1) * cos(th1) - cos(th2),
dy = sin(ph1) * cos(th1);
arc sin(sqrt(dx * dx + dy * dy + dz * dz) / 2) * 2 * r
);
main:
(
REAL d = dist(36.12, -86.67, 33.94, -118.4);
# Americans don't know kilometers #
printf(($"dist: "g(0,1)" km ("g(0,1)" mi.)"l$, d, d / 1.609344))
)

View file

@ -0,0 +1,18 @@
# syntax: GAWK -f HAVERSINE_FORMULA.AWK
# converted from Python
BEGIN {
distance(36.12,-86.67,33.94,-118.40) # BNA to LAX
exit(0)
}
function distance(lat1,lon1,lat2,lon2, a,c,dlat,dlon) {
dlat = radians(lat2-lat1)
dlon = radians(lon2-lon1)
lat1 = radians(lat1)
lat2 = radians(lat2)
a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
c = 2 * atan2(sqrt(a),sqrt(1-a))
printf("distance: %.4f km\n",6372.8 * c)
}
function radians(degree) { # degrees to radians
return degree * (3.1415926 / 180.)
}

View file

@ -0,0 +1,31 @@
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Long_Float_Text_IO; use Ada.Long_Float_Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
procedure Haversine_Formula is
package Math is new Ada.Numerics.Generic_Elementary_Functions (Long_Float); use Math;
-- Compute great circle distance, given latitude and longitude of two points, in radians
function Great_Circle_Distance (lat1, long1, lat2, long2 : Long_Float) return Long_Float is
Earth_Radius : constant := 6371.0; -- in kilometers
a : Long_Float := Sin (0.5 * (lat2 - lat1));
b : Long_Float := Sin (0.5 * (long2 - long1));
begin
return 2.0 * Earth_Radius * ArcSin (Sqrt (a * a + Cos (lat1) * Cos (lat2) * b * b));
end Great_Circle_Distance;
-- convert degrees, minutes and seconds to radians
function DMS_To_Radians (Deg, Min, Sec : Long_Float := 0.0) return Long_Float is
Pi_Over_180 : constant := 0.017453_292519_943295_769236_907684_886127;
begin
return (Deg + Min/60.0 + Sec/3600.0) * Pi_Over_180;
end DMS_To_Radians;
begin
Put_Line("Distance in kilometers between BNA and LAX");
Put (Great_Circle_Distance (
DMS_To_Radians (36.0, 7.2), DMS_To_Radians (86.0, 40.2), -- Nashville International Airport (BNA)
DMS_To_Radians (33.0, 56.4), DMS_To_Radians (118.0, 24.0)), -- Los Angeles International Airport (LAX)
Aft=>3, Exp=>0);
end Haversine_Formula;

View file

@ -0,0 +1,9 @@
PRINT "Distance = " ; FNhaversine(36.12, -86.67, 33.94, -118.4) " km"
END
DEF FNhaversine(n1, e1, n2, e2)
LOCAL d() : DIM d(2)
d() = COSRAD(e1-e2) * COSRAD(n1) - COSRAD(n2), \
\ SINRAD(e1-e2) * COSRAD(n1), \
\ SINRAD(n1) - SINRAD(n2)
= ASN(MOD(d()) / 2) * 6372.8 * 2

View file

@ -0,0 +1,26 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define R 6371
#define TO_RAD (3.1415926536 / 180)
double dist(double th1, double ph1, double th2, double ph2)
{
double dx, dy, dz;
ph1 -= ph2;
ph1 *= TO_RAD, th1 *= TO_RAD, th2 *= TO_RAD;
dz = sin(th1) - sin(th2);
dx = cos(ph1) * cos(th1) - cos(th2);
dy = sin(ph1) * cos(th1);
return asin(sqrt(dx * dx + dy * dy + dz * dz) / 2) * 2 * R;
}
int main()
{
double d = dist(36.12, -86.67, 33.94, -118.4);
/* Americans don't know kilometers */
printf("dist: %.1f km (%.1f mi.)\n", d, d / 1.609344);
return 0;
}

View file

@ -0,0 +1,21 @@
(defparameter *earth-radius* 6372.8)
(defparameter *rad-conv* (/ pi 180))
(defun deg->rad (x)
(* x *rad-conv*))
(defun haversine (x)
(expt (sin (/ x 2)) 2))
(defun dist-rad (lat1 lng1 lat2 lng2)
(let* ((hlat (haversine (- lat2 lat1)))
(hlng (haversine (- lng2 lng1)))
(root (sqrt (+ hlat (* (cos lat1) (cos lat2) hlng)))))
(* 2 *earth-radius* (asin root))))
(defun dist-deg (lat1 lng1 lat2 lng2)
(dist-rad (deg->rad lat1)
(deg->rad lng1)
(deg->rad lat2)
(deg->rad lng2)))

View file

@ -0,0 +1,24 @@
import std.stdio, std.math;
real haversineDistance(in real dth1, in real dph1,
in real dth2, in real dph2) pure nothrow {
enum real R = 6371;
enum real TO_RAD = PI / 180;
alias imr = immutable(real);
imr ph1d = dph1 - dph2;
imr ph1 = ph1d * TO_RAD;
imr th1 = dth1 * TO_RAD;
imr th2 = dth2 * TO_RAD;
imr dz = sin(th1) - sin(th2);
imr dx = cos(ph1) * cos(th1) - cos(th2);
imr dy = sin(ph1) * cos(th1);
return asin(sqrt(dx ^^ 2 + dy ^^ 2 + dz ^^ 2) / 2) * 2 * R;
}
void main() {
writefln("Haversine distance: %.1f km",
haversineDistance(36.12, -86.67, 33.94, -118.4));
}

View file

@ -0,0 +1,11 @@
USING: arrays kernel math math.constants math.functions math.vectors sequences ;
: haversin ( x -- y ) cos 1 swap - 2 / ;
: haversininv ( y -- x ) 2 * 1 swap - acos ;
: haversineDist ( as bs -- d )
[ [ 180 / pi * ] map ] bi@
[ [ swap - haversin ] 2map ]
[ [ first cos ] bi@ * 1 swap 2array ]
2bi
v.
haversininv R_earth * ;

View file

@ -0,0 +1,2 @@
( scratchpad ) { 36.12 -86.67 } { 33.94 -118.4 } haversineDist .
2887.259950607113

View file

@ -0,0 +1,15 @@
: s>f s>d d>f ;
: deg>rad 174532925199433e-16 f* ;
: difference f- deg>rad 2 s>f f/ fsin fdup f* ;
: haversine ( lat1 lon1 lat2 lon2 -- haversine)
frot difference ( lat1 lat2 dLon^2)
frot frot fover fover ( dLon^2 lat1 lat2 lat1 lat2)
fswap difference ( dLon^2 lat1 lat2 dLat^2)
fswap deg>rad fcos ( dLon^2 lat1 dLat^2 lat2)
frot deg>rad fcos f* ( dLon^2 dLat2 lat1*lat2)
frot f* f+ ( lat1*lat2*dLon^2+dLat^2)
fsqrt fasin 127456 s>f f* 10 s>f f/ ( haversine)
;
36.12e -86.67e 33.94e -118.40e haversine cr f.

View file

@ -0,0 +1,34 @@
program example
implicit none
real :: d
d = haversine(36.12,-86.67,33.94,-118.40) ! BNA to LAX
print '(A,F9.4,A)', 'distance: ',d,' km' ! distance: 2887.2600 km
contains
function to_radian(degree) result(rad)
! degrees to radians
real,intent(in) :: degree
real :: rad,pi
pi = 4*atan(1.0) ! exploit intrinsic atan to generate pi
rad = degree*pi/180
end function to_radian
function haversine(deglat1,deglon1,deglat2,deglon2) result (dist)
! great circle distance -- adapted from Matlab
real,intent(in) :: deglat1,deglon1,deglat2,deglon2
real :: a,c,dist,dlat,dlon,lat1,lat2
real,parameter :: radius = 6372.8
dlat = to_radian(deglat2-deglat1)
dlon = to_radian(deglon2-deglon1)
lat1 = to_radian(deglat1)
lat2 = to_radian(deglat2)
a = (sin(dlat/2))**2 + cos(lat1)*cos(lat2)*(sin(dlon/2))**2
c = 2*atan2(sqrt(a),sqrt(1-a))
dist = radius*c
end function haversine
end program example

View file

@ -0,0 +1,6 @@
haversine[theta] := (1-cos[theta])/2
dist[lat1, long1, lat2, long2] := 2 earthradius arcsin[sqrt[haversine[lat2-lat1] + cos[lat1] cos[lat2] haversine[long2-long1]]]
d = dist[36.12 deg, -86.67 deg, 33.94 deg, -118.40 deg]
println[d-> "km"]

View file

@ -0,0 +1,4 @@
use navigation.frink
d = earthDistance[36.12 deg North, 86.67 deg West, 33.94 deg North, 118.40 deg West]
println[d-> "km"]

View file

@ -0,0 +1,30 @@
package main
import (
"fmt"
"math"
)
func haversine(θ float64) float64 {
return .5 * (1 - math.Cos(θ))
}
type pos struct {
φ float64 // latitude, radians
ψ float64 // longitude, radians
}
func degPos(lat, lon float64) pos {
return pos{lat * math.Pi / 180, lon * math.Pi / 180}
}
const rEarth = 6372.8 // km
func hsDist(p1, p2 pos) float64 {
return 2 * rEarth * math.Asin(math.Sqrt(haversine(p2.φ-p1.φ)+
math.Cos(p1.φ)*math.Cos(p2.φ)*haversine(p2.ψ-p1.ψ)))
}
func main() {
fmt.Println(hsDist(degPos(36.12, -86.67), degPos(33.94, -118.40)))
}

View file

@ -0,0 +1,16 @@
def haversine(lat1, lon1, lat2, lon2) {
def R = 6372.8
// In kilometers
def dLat = Math.toRadians(lat2 - lat1)
def dLon = Math.toRadians(lon2 - lon1)
lat1 = Math.toRadians(lat1)
lat2 = Math.toRadians(lat2)
def a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2)
def c = 2 * Math.asin(Math.sqrt(a))
R * c
}
haversine(36.12, -86.67, 33.94, -118.40)
> 2887.25995060711

View file

@ -0,0 +1,28 @@
import Text.Printf
-- The haversine of an angle.
hsin t = let u = sin (t/2) in u*u
-- The distance between two points, given by latitude and longtitude, on a
-- circle. The points are specified in radians.
distRad radius (lat1, lng1) (lat2, lng2) =
let hlat = hsin (lat2 - lat1)
hlng = hsin (lng2 - lng1)
root = sqrt (hlat + cos lat1 * cos lat2 * hlng)
in 2 * radius * asin (min 1.0 root)
-- The distance between two points, given by latitude and longtitude, on a
-- circle. The points are specified in degrees.
distDeg radius p1 p2 = distRad radius (deg2rad p1) (deg2rad p2)
where deg2rad (t, u) = (d2r t, d2r u)
d2r t = t * pi / 180
-- The approximate distance, in kilometers, between two points on Earth. The
-- latitude and longtitude are assumed to be in degrees.
earthDist = distDeg 6372.8
main = do
let bna = (36.12, -86.67)
lax = (33.94, -118.40)
dst = earthDist bna lax :: Double
printf "The distance between BNA and LAX is about %0.f km.\n" dst

View file

@ -0,0 +1,15 @@
link printf
procedure main() #: Haversine formula
printf("BNA to LAX is %d km (%d miles)\n",
d := gcdistance([36.12, -86.67],[33.94, -118.40]),d*3280/5280) # with cute km2mi conversion
end
procedure gcdistance(a,b)
a[2] -:= b[2]
every (x := a|b)[i := 1 to 2] := dtor(x[i])
dz := sin(a[1]) - sin(b[1])
dx := cos(a[2]) * cos(a[1]) - cos(b[1])
dy := sin(a[2]) * cos(a[1])
return asin(sqrt(dx * dx + dy * dy + dz * dz) / 2) * 2 * 6371
end

View file

@ -0,0 +1,4 @@
require 'trig'
haversin=: 0.5 * 1 - cos
Rearth=: 6372.8
haversineDist=: Rearth * haversin^:_1@((1 , *&(cos@{.)) +/ .* [: haversin -)&rfd

View file

@ -0,0 +1,2 @@
36.12 _86.67 haversineDist 33.94 _118.4
2887.26

View file

@ -0,0 +1,16 @@
public class Haversine {
public static final double R = 6372.8; // In kilometers
public static double haversine(double lat1, double lon1, double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return R * c;
}
public static void main(String[] args) {
System.out.println(haversine(36.12, -86.67, 33.94, -118.40));
}
}

View file

@ -0,0 +1,5 @@
julia> haversine(lat1,lon1,lat2,lon2) = 2 * 6372.8 * asin(sqrt(sind((lat2-lat1)/2)^2 + cosd(lat1) * cosd(lat2) * sind((lon2 - lon1)/2)^2))
# method added to generic function haversine
julia> haversine(36.12,-86.67,33.94,-118.4)
2887.2599506071106

View file

@ -0,0 +1,13 @@
print "Haversine distance: "; using( "####.###########", havDist( 36.12, -86.67, 33.94, -118.4)); " km."
end
function havDist( th1, ph1, th2, ph2)
degtorad = acs(-1)/180
diameter = 2 * 6372.8
LgD = degtorad * (ph1 - ph2)
th1 = degtorad * th1
th2 = degtorad * th2
dz = sin( th1) - sin( th2)
dx = cos( LgD) * cos( th1) - cos( th2)
dy = sin( LgD) * cos( th1)
havDist = asn( ( dx^2 +dy^2 +dz^2)^0.5 /2) *diameter
end function

View file

@ -0,0 +1,17 @@
function rad = radians(degree)
% degrees to radians
rad = degree * pi / 180;
end;
function [a,c,dlat,dlon]=haversine(lat1,lon1,lat2,lon2)
% HAVERSINE_FORMULA.AWK - converted from AWK
dlat = radians(lat2-lat1);
dlon = radians(lon2-lon1);
lat1 = radians(lat1);
lat2 = radians(lat2);
a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2;
c = 2 * atan2(sqrt(a),sqrt(1-a));
printf("distance: %.4f km\n",6372.8 * c);
end
[a,c,dlat,dlon] = haversine(36.12,-86.67,33.94,-118.40); % BNA to LAX

View file

@ -0,0 +1,4 @@
distance[{theta1_, phi1_}, {theta2_, phi2_}] :=
2*6378.14 ArcSin@
Sqrt[Haversine[(theta2 - theta1) Degree] +
Cos[theta1*Degree] Cos[theta2*Degree] Haversine[(phi2 - phi1) Degree]]

View file

@ -0,0 +1,12 @@
dms(d, m, s) := (d + m/60 + s/3600)*%pi/180$
great_circle_distance(lat1, long1, lat2, long2) :=
12742*asin(sqrt(sin((lat2 - lat1)/2)^2 + cos(lat1)*cos(lat2)*sin((long2 - long1)/2)^2))$
/* Coordinates are found here:
http://www.airport-data.com/airport/BNA/
http://www.airport-data.com/airport/LAX/ */
great_circle_distance(dms( 36, 7, 28.10), -dms( 86, 40, 41.50),
dms( 33, 56, 32.98), -dms(118, 24, 29.05)), numer;
/* 2886.326609413624 */

View file

@ -0,0 +1,21 @@
class POI {
private $latitude;
private $longitude;
public function __construct($latitude, $longitude) {
$this->latitude = deg2rad($latitude);
$this->longitude = deg2rad($longitude);
}
public function getLatitude() return $this->latitude;
public function getLongitude() return $this->longitude;
public function getDistanceInMetersTo(POI $other) {
$radiusOfEarth = 6371000;// Earth's radius in meters.
$diffLatitude = $other->getLatitude() - $this->latitude;
$diffLongitude = $other->getLongitude() - $this->longitude;
$a = sin($diffLatitude / 2) * sin($diffLatitude / 2) +
cos($this->latitude) * cos($other->getLatitude()) *
sin($diffLongitude / 2) * sin($diffLongitude / 2);
$c = 2 * asin(sqrt($a));
$distance = $radiusOfEarth * $c;
return $distance;
}
}

View file

@ -0,0 +1,3 @@
$user = new POI($_GET["latitude"], $_GET["longitude"]);
$poi = new POI(19,69276, -98,84350); // Piramide del Sol, Mexico
echo $user->getDistanceInMetersTo($poi);

View file

@ -0,0 +1,17 @@
(scl 12)
(load "@lib/math.l")
(de haversine (Th1 Ph1 Th2 Ph2)
(setq
Ph1 (*/ (- Ph1 Ph2) pi 180.0)
Th1 (*/ Th1 pi 180.0)
Th2 (*/ Th2 pi 180.0) )
(let
(DX (- (*/ (cos Ph1) (cos Th1) 1.0) (cos Th2))
DY (*/ (sin Ph1) (cos Th1) 1.0)
DZ (- (sin Th1) (sin Th2)) )
(* `(* 2 6371)
(asin
(/
(sqrt (+ (* DX DX) (* DY DY) (* DZ DZ)))
2 ) ) ) ) )

View file

@ -0,0 +1,4 @@
(prinl
"Haversine distance: "
(round (haversine 36.12 -86.67 33.94 -118.4))
" km" )

View file

@ -0,0 +1,16 @@
>>> import math
>>> def haversine(lat1, lon1, lat2, lon2):
R = 6372.8
# In kilometers
dLat = math.radians(lat2 - lat1)
dLon = math.radians(lon2 - lon1)
lat1 = math.radians(lat1)
lat2 = math.radians(lat2)
a = math.sin(dLat / 2) * math.sin(dLat / 2) + math.sin(dLon / 2) * math.sin(dLon / 2) * math.cos(lat1) * math.cos(lat2)
c = 2 * math.asin(math.sqrt(a))
return R * c
>>> haversine(36.12, -86.67, 33.94, -118.40)
2887.2599506071106
>>>

View file

@ -0,0 +1,20 @@
dms_to_rad <- function(d, m, s) (d + m / 60 + s / 3600) * pi / 180
# Volumetric mean radius is 6371 km, see http://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html
# The diameter is thus 12742 km
great_circle_distance <- function(lat1, long1, lat2, long2) {
a <- sin(0.5 * (lat2 - lat1))
b <- sin(0.5 * (long2 - long1))
12742 * asin(sqrt(a * a + cos(lat1) * cos(lat2) * b * b))
}
# Coordinates are found here:
# http://www.airport-data.com/airport/BNA/
# http://www.airport-data.com/airport/LAX/
great_circle_distance(
dms_to_rad(36, 7, 28.10), dms_to_rad( 86, 40, 41.50), # Nashville International Airport (BNA)
dms_to_rad(33, 56, 32.98), dms_to_rad(118, 24, 29.05)) # Los Angeles International Airport (LAX)
# Output: 2886.327

View file

@ -0,0 +1,89 @@
/*REXX pgm calculates distance between Nashville & Los Angles airports. */
say " Nashville: north 36º 7.2', west 86º 40.2' = 36.12º, -86.67º"
say "Los Angles: north 33º 56.4', west 118º 24.0' = 33.94º, -118.40º"
say
$.= /*set defaults for subroutines. */
dist=surfaceDistance(36.12, -86.67, 33.94, -118.4)
kdist=format(dist/1 ,,2) /*show 2 digs past decimal point.*/
mdist=format(dist/1.609344,,2) /* " " " " " " */
ndist=format(mdist*5280/6076.1,,2) /* " " " " " " */
say ' distance between= ' kdist " kilometers,"
say ' or ' mdist " statute miles,"
say ' or ' ndist " nautical or air miles."
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────SURFACEDISTANCE subroutine──────────*/
surfaceDistance: arg th1,ph1,th2,ph2 /*use haversine formula for dist.*/
numeric digits digits()*2 /*double the number of digits. */
radius = 6372.8 /*earth's mean radius in km */
ph1 = d2r(ph1-ph2) /*convert degs──►radians & reduce*/
ph2 = d2r(ph2) /* " " " " " */
th1 = d2r(th1) /* " " " " " */
th2 = d2r(th2)
x = cos(ph1) * cos(th1) - cos(th2)
y = sin(ph1) * cos(th1)
z = sin(th1) - sin(th2)
return radius * 2 * aSin(sqrt(x**2+y**2+z**2)/2 )
/*═════════════════════════════general 1-line subs══════════════════════*/
d2d: return arg(1) // 360 /*normalize degrees. */
d2r: return r2r(arg(1)*pi() / 180) /*normalize and convert deg──►rad*/
r2d: return d2d((arg(1)*180 / pi())) /*normalize and convert rad──►deg*/
r2r: return arg(1) // (2*pi()) /*normalize radians. */
p: return word(arg(1),1) /*pick the first of two words. */
pi: if $.pipi=='' then $.pipi=$pi(); return $.pipi /*return π.*/
aCos: procedure expose $.; arg x; if x<-1|x>1 then call $81r -1,1,x,"ACOS"
return .5*pi()-aSin(x) /*$81R says arg is out of range,*/
/* and it isn't included here.*/
aSin: procedure expose $.; parse arg x
if x<-1 | x>1 then call $81r -1,1,x,"ASIN"; s=x*x
if abs(x)>=.7 then return sign(x)*aCos(sqrt(1-s),'-ASIN')
z=x; o=x; p=z; do j=2 by 2; o=o*s*(j-1)/j; z=z+o/(j+1)
if z=p then leave; p=z; end; return z
cos: procedure expose $.; parse arg x; x=r2r(x); a=abs(x)
numeric fuzz min(9,digits()-9); if a=pi() then return -1
if a=pi()/2 | a=2*pi() then return 0; if a=pi()/3 then return .5
if a=2*pi()/3 then return -.5; return .sinCos(1,1,-1)
sin: procedure expose $.; parse arg x; x=r2r(x);
numeric fuzz min(5,digits()-3)
if abs(x)=pi() then return 0; return .sinCos(x,x,1)
.sinCos: parse arg z,_,i; x=x*x; p=z; do k=2 by 2; _=-_*x/(k*(k+i)); z=z+_
if z=p then leave; p=z; end; return z /*used by SIN & COS.*/
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits()
numeric digits 11; g=.sqrtGuess(); do j=0 while p>9; m.j=p; p=p%2+1; end
do k=j+5 to 0 by -1; if m.k>11 then numeric digits m.k; g=.5*(g+x/g);end
numeric digits d; return g/1
.sqrtGuess: numeric form; m.=11; p=d+d%4+2
parse value format(x,2,1,,0) 'E0' with g 'E' _ .; return g*.5'E'_%2
$pi: return ,
'3.1415926535897932384626433832795028841971693993751058209749445923078'||,
'164062862089986280348253421170679821480865132823066470938446095505822'||,
'3172535940812848111745028410270193852110555964462294895493038196'
/*┌───────────────────────────────────────────────────────────────────────┐
A note on built-in functions. REXX doesn't have a lot of mathmatical
or (particularly) trigomentric functions, so REXX programmers have
to write their own. Usually, this is done once, or most likely, one
is borrowed from another program. Knowing this, the one that is used
has a lot of boilerplate in it. Once coded and throughly debugged, I
put those commonly-used subroutines into the "1-line sub" section.
Programming note: the "general 1-line" subroutines are taken from
other programs that I wrote, but I broke up their one line of source
so it can be viewed without shifting the viewing window.
The "er 81" [which won't happen here] just shows an error telling
the legal range for ARCxxx functions (in this case: -1 +1).
Similarly, the SQRT function checks for a negative argument
[which again, won't happen here].
The pi constant (as used here) is actually a much more robust function
and will return up to one million digits in the real version.
One bad side effect is that, like a automobile without a hood, you see
all the dirty stuff going on. Also, don't visit a sausage factory.
*/

View file

@ -0,0 +1,15 @@
#lang racket
(require math)
(define earth-radius 6371)
(define (distance lat1 long1 lat2 long2)
(define (h a b) (sqr (sin (/ (- b a) 2))))
(* 2 earth-radius
(asin (sqrt (+ (h lat1 lat2)
(* (cos lat1) (cos lat2) (h long1 long2)))))))
(define (deg-to-rad d m s)
(* (/ pi 180) (+ d (/ m 60) (/ s 3600))))
(distance (deg-to-rad 36 7.2 0) (deg-to-rad 86 40.2 0)
(deg-to-rad 33 56.4 0) (deg-to-rad 118 24.0 0))

View file

@ -0,0 +1,18 @@
include Math
Radius = 6371 # rough radius of the Earth, in kilometers
def spherical_distance(start_coords, end_coords)
lat1, long1 = deg2rad *start_coords
lat2, long2 = deg2rad *end_coords
2 * Radius * asin(sqrt(sin((lat2-lat1)/2)**2 + cos(lat1) * cos(lat2) * sin((long2 - long1)/2)**2))
end
def deg2rad(lat, long)
[lat * PI / 180, long * PI / 180]
end
bna = [36.12, -86.67]
lax = [33.94, -118.4]
puts "%.1f" % spherical_distance(bna, lax)

View file

@ -0,0 +1,18 @@
import math._
object Haversine {
val R = 6372.8 //radius in km
def haversine(lat1:Double, lon1:Double, lat2:Double, lon2:Double)={
val dLat=(lat2 - lat1).toRadians
val dLon=(lon2 - lon1).toRadians
val a = pow(sin(dLat/2),2) + pow(sin(dLon/2),2) * cos(lat1.toRadians) * cos(lat2.toRadians)
val c = 2 * asin(sqrt(a))
R * c
}
def main(args: Array[String]): Unit = {
println(haversine(36.12, -86.67, 33.94, -118.40))
}
}

View file

@ -0,0 +1,12 @@
(define earth-radius 6371)
(define pi (acos -1))
(define (distance lat1 long1 lat2 long2)
(define (h a b) (expt (sin (/ (- b a) 2)) 2))
(* 2 earth-radius (asin (sqrt (+ (h lat1 lat2) (* (cos lat1) (cos lat2) (h long1 long2)))))))
(define (deg-to-rad d m s) (* (/ pi 180) (+ d (/ m 60) (/ s 3600))))
(distance (deg-to-rad 36 7.2 0) (deg-to-rad 86 40.2 0)
(deg-to-rad 33 56.4 0) (deg-to-rad 118 24.0 0))
; 2886.444442837984

View file

@ -0,0 +1,17 @@
package require Tcl 8.5
proc haversineFormula {lat1 lon1 lat2 lon2} {
set rads [expr atan2(0,-1)/180]
set R 6372.8 ;# In kilometers
set dLat [expr {($lat2-$lat1) * $rads}]
set dLon [expr {($lon2-$lon1) * $rads}]
set lat1 [expr {$lat1 * $rads}]
set lat2 [expr {$lat2 * $rads}]
set a [expr {sin($dLat/2)**2 + sin($dLon/2)**2*cos($lat1)*cos($lat2)}]
set c [expr {2*asin(sqrt($a))}]
return [expr {$R * $c}]
}
# Don't bother with too much inappropriate accuracy!
puts [format "distance=%.1f km" [haversineFormula 36.12 -86.67 33.94 -118.40]]