1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| package main
import ( "fmt" "math" "strings" )
type location struct { lat, long float64 }
func newLocation(lat, long coordinate) location { return location{ lat: lat.decimal(), long: long.decimal(), } }
type coordinate struct { d, m, s float64 h rune }
func (c coordinate) decimal() float64 { sign := 1.0 switch strings.ToLower(string(c.h)) { case "s", "w": sign = -1 } return sign * (c.d + c.m/60 + c.s/3600) }
type world struct { radius float64 }
func (w world) distance(p1, p2 location) float64 { s1, c1 := math.Sincos(rad(p1.lat)) s2, c2 := math.Sincos(rad(p2.lat)) clong := math.Cos(rad(p1.long - p2.long)) return w.radius * math.Acos(s1*s2+c1*c2*clong) }
func rad(deg float64) float64 { return deg * math.Pi / 180 }
var ( mars = world{radius: 3389.5} earth = world{radius: 6371} )
func main() { spirit := newLocation(coordinate{d: 14, m: 34, s: 6.2, h: 'S'}, coordinate{d: 175, m: 28, s: 21.5, h: 'E'}) opportunity := newLocation(coordinate{d: 1, m: 56, s: 46.3, h: 'S'}, coordinate{d: 354, m: 28, s: 24.2, h: 'E'}) curiosity := newLocation(coordinate{d: 4, m: 35, s: 22.2, h: 'S'}, coordinate{d: 137, m: 26, s: 30.1, h: 'E'}) insight := newLocation(coordinate{d: 4, m: 30, s: 0.0, h: 'N'}, coordinate{d: 135, m: 54, s: 0, h: 'E'})
fmt.Printf("Spirit to Opportunity %.2f km\n", mars.distance(spirit, opportunity)) fmt.Printf("Spirit to Curiosity %.2f km\n", mars.distance(spirit, curiosity)) fmt.Printf("Spirit to Insight %.2f km\n", mars.distance(spirit, insight))
fmt.Printf("Opportunity to Curiosity %.2f km\n", mars.distance(opportunity, curiosity)) fmt.Printf("Opportunity to Insight %.2f km\n", mars.distance(opportunity, insight))
fmt.Printf("Curiosity to Insight %.2f km\n", mars.distance(curiosity, insight))
london := newLocation(coordinate{d: 51, m: 30, s: 0, h: 'N'}, coordinate{d: 0, m: 8, s: 0, h: 'W'}) paris := newLocation(coordinate{d: 48, m: 51, s: 0, h: 'N'}, coordinate{d: 2, m: 21, s: 0, h: 'E'}) fmt.Printf("Lindon to Paris %.2f km\n", earth.distance(london, paris))
chengdu := newLocation(coordinate{d: 30, m: 39, s: 3.24, h: 'N'}, coordinate{d: 104, m: 04, s: 35.16, h: 'E'}) home := newLocation(coordinate{d: 30, m: 32, s: 51.02, h: 'N'}, coordinate{d: 104, m: 06, s: 15.70, h: 'E'}) fmt.Printf("Chengdu to Home %.2f km\n", earth.distance(chengdu, home))
mountSharp := newLocation(coordinate{5, 4, 48, 'S'}, coordinate{137, 51, 0, 'E'}) olympusMons := newLocation(coordinate{18, 39, 0, 'N'}, coordinate{226, 12, 0, 'E'}) fmt.Printf("Mount Sharp to Olympus Mons %.2f km\n", mars.distance(mountSharp, olympusMons)) }
|