Created
July 25, 2011 16:17
-
-
Save alexreisner/1104495 to your computer and use it in GitHub Desktop.
Compare two trig-less distance approximation formulas.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# This script is a rough test of two trig-less distance approximation formulas. | |
# | |
# Each formula takes two sets of lat/lon coordinates and returns the approximate | |
# number of miles between them, without using trigonometry. | |
# | |
require 'geocoder' # geocoder ruby gem | |
def dx(c1, c2) | |
d = Geocoder::Calculations.longitude_degree_distance(30) | |
d * (c1[1] - c2[1]).abs | |
end | |
def dy(c1, c2) | |
d = Geocoder::Calculations.latitude_degree_distance | |
d * (c1[0] - c2[0]).abs | |
end | |
def actual(c1, c2) | |
Geocoder::Calculations.distance_between(c1, c2) | |
end | |
# Alex Reisner's formula | |
def reisner(c1, c2) | |
(dy(c1, c2) * Math.sin(Math::PI / 4)) + (dx(c1, c2) * Math.sin(Math::PI / 4)) | |
end | |
# Rob Poor's formula | |
def rdpoor(c1, c2) | |
[dx(c1, c2), dy(c1, c2)].max + ([dx(c1, c2), dy(c1, c2)].min * 0.5) | |
end | |
# Rafael Baptista's formula (rdpoor with better coefficients) | |
def baptista(c1, c2) | |
k1 = 1007.0 / 1024.0 | |
k2 = 441.0 / 1024.0 | |
([dx(c1, c2), dy(c1, c2)].max * k1) + ([dx(c1, c2), dy(c1, c2)].min * k2) | |
end | |
systems = [:reisner, :rdpoor, :baptista] | |
errors = {}; systems.each{ |s| errors[s] = [] } | |
c1 = [40, -80] | |
(0...10).each do |i| | |
c2 = [c1[0] + i, c1[1] + 10 - i] | |
bearing = Geocoder::Calculations.bearing_between(c1, c2) | |
puts "%s --> %s (%d degrees)" % [c1.inspect, c2.inspect, bearing] | |
systems.each do |s| | |
errors[s] << 100.0 * (send(s, c1, c2) - actual(c1, c2)) / actual(c1, c2) | |
puts "#{s} error: %.1f%%" % errors[s].last | |
end | |
puts "" | |
end | |
systems.each do |s| | |
avg = errors[s].inject(0){ |t,i| t + i } / errors[s].size | |
puts "avg #{s} error: %.1f" % avg | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment