#include <stdio.h>
#include <math.h>
const double earth_R = 6356.752; // 地球の平均半径
const double PI = 3.141592653589793238462643383279; // 円周率
typedef struct { // 地点データ
double ido;
double keido;
double v[3]; // 単位ベクトル x,y,z 成分
} POS;
int main()
{
int i;
POS pos[2]; // 地点の情報
double angle; // 単位ベクトルのなす角度
double dv[3]; // 2点を結ぶベクトル (x,y,z)
// 入力
printf("地球上の2点間の距離を求める(地球の平均半径=%.1fkmと仮定)\n\n", earth_R
); printf(" 2地点の緯度経度をDegree(-180.0~180.0)で入力\n"); printf(" (※ 北緯 35度30分・西経 100度の場合、'35.5 -100' と入力\n"); printf(" 南緯 35度30分・東経 100度の場合、'-35.5 100' と入力 )\n"); for (i = 0; i < 2; i++) {
printf("・地点 %d の緯度経度:", i
+ 1); scanf("%lf %lf", &pos
[i
].
ido, &pos
[i
].
keido); }
// それぞれの単位ベクトルをを求める
for (i = 0; i < 2; i++) {
pos
[i
].
v[0] = cos(pos
[i
].
keido * PI
/ 180.0) * cos(pos
[i
].
ido * PI
/ 180.0); pos
[i
].
v[1] = sin(pos
[i
].
keido * PI
/ 180.0) * cos(pos
[i
].
ido * PI
/ 180.0); pos
[i
].
v[2] = sin(pos
[i
].
ido * PI
/ 180.0); }
// 2地点を結ぶベクトル dv[] (x,y,z) を求める
for (i = 0; i < 3; i++) {
dv[i] = pos[1].v[i] - pos[0].v[i];
}
// 単位ベクトルのなす角度 angle[rad] を求める
angle = 0.0; // 内積計算temp
for (i = 0; i < 3; i++) {
angle += pos[0].v[i] * pos[1].v[i];
}
// 表示
printf("・球面上の最短距離 = %fkm\n", earth_R
* angle
); printf("・最短距離(地下トンネル) = %fkm\n", earth_R
* sqrt(dv
[0] * dv
[0] + dv
[1] * dv
[1] + dv
[2] * dv
[2]));
// 終了
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+Cgpjb25zdCBkb3VibGUgZWFydGhfUiA9IDYzNTYuNzUyOyAgICAvLyDlnLDnkIPjga7lubPlnYfljYrlvoQKY29uc3QgZG91YmxlIFBJID0gMy4xNDE1OTI2NTM1ODk3OTMyMzg0NjI2NDMzODMyNzk7IC8vIOWGhuWRqOeOhwoKdHlwZWRlZiBzdHJ1Y3QgeyAgICAgICAgICAgICAgICAvLyDlnLDngrnjg4fjg7zjgr8KICAgIGRvdWJsZSBpZG87CiAgICBkb3VibGUga2VpZG87CiAgICBkb3VibGUgdlszXTsgICAgICAgICAgICAgICAgLy8g5Y2Y5L2N44OZ44Kv44OI44OrIHgseSx6IOaIkOWIhgp9IFBPUzsKCmludCBtYWluKCkKewogICAgaW50IGk7CiAgICBQT1MgcG9zWzJdOyAgICAgICAgICAgICAgICAgLy8g5Zyw54K544Gu5oOF5aCxCiAgICBkb3VibGUgYW5nbGU7ICAgICAgICAgICAgICAgLy8g5Y2Y5L2N44OZ44Kv44OI44Or44Gu44Gq44GZ6KeS5bqmCiAgICBkb3VibGUgZHZbM107ICAgICAgICAgICAgICAgLy8gMueCueOCkue1kOOBtuODmeOCr+ODiOODqyAoeCx5LHopCgogICAgLy8g5YWl5YqbCiAgICBwcmludGYoIuWcsOeQg+S4iuOBrjLngrnplpPjga7ot53pm6LjgpLmsYLjgoHjgoso5Zyw55CD44Gu5bmz5Z2H5Y2K5b6EPSUuMWZrbeOBqOS7ruWumilcblxuIiwgZWFydGhfUik7CiAgICBwcmludGYoIiAgMuWcsOeCueOBrue3r+W6pue1jOW6puOCkkRlZ3JlZSgtMTgwLjDvvZ4xODAuMCnjgaflhaXliptcbiIpOwogICAgcHJpbnRmKCIgICAgKOKAuyDljJfnt68gMzXluqYzMOWIhuODu+ilv+e1jCAxMDDluqbjga7loLTlkIjjgIEnMzUuNSAtMTAwJyDjgajlhaXliptcbiIpOwogICAgcHJpbnRmKCIgICAgICAgIOWNl+e3ryAzNeW6pjMw5YiG44O75p2x57WMIDEwMOW6puOBruWgtOWQiOOAgSctMzUuNSAxMDAnIOOBqOWFpeWKmyApXG4iKTsKICAgIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgICAgICBwcmludGYoIuODu+WcsOeCuSAlZCDjga7nt6/luqbntYzluqbvvJoiLCBpICsgMSk7CiAgICAgICAgc2NhbmYoIiVsZiAlbGYiLCAmcG9zW2ldLmlkbywgJnBvc1tpXS5rZWlkbyk7CiAgICB9CiAgICAvLyDjgZ3jgozjgZ7jgozjga7ljZjkvY3jg5njgq/jg4jjg6vjgpLjgpLmsYLjgoHjgosKICAgIGZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKICAgICAgICBwb3NbaV0udlswXSA9IGNvcyhwb3NbaV0ua2VpZG8gKiBQSSAvIDE4MC4wKSAqIGNvcyhwb3NbaV0uaWRvICogUEkgLyAxODAuMCk7CiAgICAgICAgcG9zW2ldLnZbMV0gPSBzaW4ocG9zW2ldLmtlaWRvICogUEkgLyAxODAuMCkgKiBjb3MocG9zW2ldLmlkbyAqIFBJIC8gMTgwLjApOwogICAgICAgIHBvc1tpXS52WzJdID0gc2luKHBvc1tpXS5pZG8gKiBQSSAvIDE4MC4wKTsKICAgIH0KICAgIC8vIDLlnLDngrnjgpLntZDjgbbjg5njgq/jg4jjg6sgZHZbXSAoeCx5LHopIOOCkuaxguOCgeOCiwogICAgZm9yIChpID0gMDsgaSA8IDM7IGkrKykgewogICAgICAgIGR2W2ldID0gcG9zWzFdLnZbaV0gLSBwb3NbMF0udltpXTsKICAgIH0KICAgIC8vIOWNmOS9jeODmeOCr+ODiOODq+OBruOBquOBmeinkuW6piBhbmdsZVtyYWRdIOOCkuaxguOCgeOCiwogICAgYW5nbGUgPSAwLjA7ICAgICAgICAgICAgICAgIC8vIOWGheepjeioiOeul3RlbXAKICAgIGZvciAoaSA9IDA7IGkgPCAzOyBpKyspIHsKICAgICAgICBhbmdsZSArPSBwb3NbMF0udltpXSAqIHBvc1sxXS52W2ldOwogICAgfQogICAgYW5nbGUgPSBhY29zKGFuZ2xlKTsKICAgIC8vIOihqOekugogICAgcHJpbnRmKCJcbuWcsOeCuSAx4oaSMuOBrlxuIik7CiAgICBwcmludGYoIuODu+eQg+mdouS4iuOBruacgOefrei3nemboiAgICAgICA9ICVma21cbiIsIGVhcnRoX1IgKiBhbmdsZSk7CiAgICBwcmludGYoIuODu+acgOefrei3nemboijlnLDkuIvjg4jjg7Pjg43jg6spID0gJWZrbVxuIiwgZWFydGhfUiAqIHNxcnQoZHZbMF0gKiBkdlswXSArIGR2WzFdICogZHZbMV0gKyBkdlsyXSAqIGR2WzJdKSk7CgogICAgLy8g57WC5LqGCiAgICByZXR1cm4gMDsKfQ==