Skip to content

Instantly share code, notes, and snippets.

@frankvilhelmsen
Created February 10, 2012 07:40
Show Gist options
  • Save frankvilhelmsen/1787462 to your computer and use it in GitHub Desktop.
Save frankvilhelmsen/1787462 to your computer and use it in GitHub Desktop.
The haversine formular
(ns util
(:use clojure.contrib.generic.math-functions))
; http://en.wikipedia.org/wiki/Earth_radius
(def R 6367)
; rad argument to haversine function (180° d/πR).
(defn rad [x]
(* x (/ Math/PI 180)))
; haversine function
(defn
#^{:test (fn []
(assert (= 1.2920680792922851 (haversine
{:lat 55.449780 :lon 11.823392} {:lat 55.451021 :lon 11.803007} ))))}
haversine
[position destination]
"Calculate the distance between two coordinates, with the haversine formula"
(let [square_half_chord
(+ (pow (sin (/ (rad (- (destination :lat)(position :lat))) 2)) 2)
(* (cos (rad (position :lat)))
(cos (rad (destination :lat)))
(pow (sin (/ (rad (- (destination :lon)(position :lon))) 2)) 2)))
angular_distance
(* (asin (sqrt square_half_chord)) 2) ]
(* angular_distance R)))
(defn meter [x] (* x 1000))
(def p1 {:name "Artilleristen" :lat 55.449780 :lon 11.823392})
(def p2 {:name "Rundkørslen" :lat 55.451021 :lon 11.803007})
(meter (haversine p1 p2))
@frankvilhelmsen
Copy link
Author

samaaron>

Looks good - although typically you'd see a literal docstring rather than explicitly adding it to the metadata.
The let binding would benefit from more declarative names - a b c d f don't communicate much to me. However, the idea of having consecutive steps in your let binding is pretty common and can be useful to describe the process to readers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment