title: Golang 緯度経度 DMS の実際の問題の解決
date: 2022-05-30 10:53:00
toc: false
index_img: https://puep.qpic.cn/coral/Q3auHgzwzM4fgQ41VTF2rGpUMPpyPrsMm6TJcdtuTd00Qp3a7jkPEg/0
category:
- Go
tags: - 計算
- フォーマット
タイトル#
プログラムを作成し、表「火星の着陸地点」の各着陸地点間の距離を計算し、以下の質問に答えることができるようにしてください:
- どの 2 つの着陸地点の距離が最も近いですか?
- どの 2 つの着陸地点の距離が最も遠いですか?
その後、「各惑星の測定半径の表」に基づいて新しい世界を定義し、以下の計算を実行してください。
- イギリスのロンドン(北緯 51°31'、西経 0°08')からフランスのパリ(北緯 48°51'、東経 2°21')までの距離を計算します。
- 自分のいる都市と首都の距離を計算します。
- 火星のシャープ山(南緯 5°4'48"、東経 137°51')とオリンパス山(北緯 18°39'、東経 226°12')の距離を計算します。
火星の着陸地点#
探査機または着陸機 | 着陸地点 | 緯度 | 経度 |
---|---|---|---|
ローバー号 | コロンビア記念館 | 南緯 14°34'6.2" | 東経 175°28'21.5" |
ローバー号 | チャレンジャー記念館 | 南緯 1°56'46.3" | 東経 354°28'24.2" |
キュリオシティ号 | ブラッドバリ着陸地 | 南緯 4°35'22.2" | 東経 137°26'30.1" |
インサイト号 | エリシウム平原 | 北緯 4°30'0.0" | 東経 135°54'0" |
各惑星の測定半径#
惑星 | 半径 /km | 惑星 | 半径 /km |
---|---|---|---|
水星 | 2439.7 | 木星 | 69911 |
金星 | 6051.8 | 土星 | 58232 |
地球 | 6371.0 | 天王星 | 25362 |
火星 | 3389.5 | 海王星 | 24622 |
コード#
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() {
// 南緯14°34'6.2"、東経175°28'21.5"
spirit := newLocation(coordinate{d: 14, m: 34, s: 6.2, h: 'S'}, coordinate{d: 175, m: 28, s: 21.5, h: 'E'})
// 南緯1°56'46.3"、東経354°28'24.2"
opportunity := newLocation(coordinate{d: 1, m: 56, s: 46.3, h: 'S'}, coordinate{d: 354, m: 28, s: 24.2, h: 'E'})
// 南緯4°35'22.2"、東経137°26'30.1"
curiosity := newLocation(coordinate{d: 4, m: 35, s: 22.2, h: 'S'}, coordinate{d: 137, m: 26, s: 30.1, h: 'E'})
// 北緯4°30'0.0"、東経135°54'0"
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))
// Ref: https://map.jiqrxx.com/jingweidu/
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))
}
結果#
Spirit to Opportunity 9669.71 km
Spirit to Curiosity 2291.55 km
Spirit to Insight 2580.13 km
Opportunity to Curiosity 8425.63 km
Opportunity to Insight 8365.45 km
Curiosity to Insight 545.38 km
Lindon to Paris 343.62 km
Chengdu to Home 11.80 km
Mount Sharp to Olympus Mons 5328.08 km
結論#
- Go 言語は、組み合わせ構造とメソッドを使用して、伝統的な言語のオブジェクト指向の特性をほぼ実現しています。
- Go 言語は、コンストラクタに特別な言語機能を提供していません。コンストラクタは他の関数と同じく普通の関数です。
- Go 言語では、
newType
またはNewType
という形式の関数を使用して、特定の型の値を構築するための関数を定義します。先頭の文字の大文字小文字は、関数が他のパッケージから利用可能かどうかによって決まります。 - DMS 形式(度 / 分 / 秒)は、位置を表すものであり、時間を表すものではありません。ここで、60 秒(")は 1 分、60 分(')は 1 度を表します。例えば、ブラッドバリ着陸地の位置は DMS 形式で「南緯 4°35'22.2"、東経 137°26'30.1"」と表されます。