经纬度(几何)

#include <iostream>
#include <cstdio>
#include <cmath>

using namespace std;

const double PI = acos(-1);

const double R = 6371009;

//角度转化为弧度
double torad(double deg)
{
    return deg / 180 * PI;
}

//经纬度(角度)转化为空间坐标
// lat 纬度
// lng 经度
void get_coord(double R, double lat, double lng, double &x, double &y, double &z)
{
    lat = torad(lat);
    lng = torad(lng);
    x = R * cos(lat) * cos(lng);
    y = R * cos(lat) * sin(lng);
    z = R * sin(lat);
}

//x1,x2是纬度
//y1,y2是经度
double dis(double R, double x1, double y1, double x2, double y2)
{
    double a1, b1, a2, b2, c1, c2;
    get_coord(R, x1, y1, a1, b1, c1);
    get_coord(R, x2, y2, a2, b2, c2);
    return sqrt((a1 - a2) * (a1 - a2) + (b1 - b2) * (b1 - b2) + (c1 - c2) * (c1 - c2));
}

int main()
{
    int T;
    scanf("%d", &T);
    double x1, y1, x2, y2;
    while(T--)
    {
        scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
        double d1, d2;
        d1 = dis(R, x1, y1, x2, y2);
        d2 = 2 * R * asin(d1 / (2 * R));
        int dif = (int)(d2 - d1 + 0.5);
        printf("%d\n", dif);

    }
    return 0;
}

链接: https://www.nowcoder.com/acm/contest/109/D
来源:牛客网

题目描述

给定地球的两个经纬度坐标,问这两个点的球面距离和直线距离的差。假设地球为球体,半径为6371009米。

输入描述:

第一行一个整数T表示数据组数。
接下来n行,每行四个数lat1, lng1, lat2, lng2分别表示两个点的经纬度。
正数表示北纬和东经。
负数表示南纬和西经。
数据保证合法。

输出描述:

n行表示答案。
答案保留到米。

分析:计算几何、大地坐标系。利用公式可直接解得两点的空间距离:

            d = r*sqrt(2-2*(cos(lat1)*cos(lat2)*cos(lon1-lon2)+sin(lat1)*sin(lat2)))

            推导过程如下:

                      

            如图,C,D为已知两点则有如下推导:            

            AB = r*cos(lat1);DE = r*cos(lat2);BE = r*sin(lat1) + r*sin(lat2);

            AD*AD = BE*BE + (AB-DE)*(AB-DE) = 2*r*r - 2*r*r*sin(lat1)*sin(lat2) - 2*r*r*cos(lat1)*cos(lat2);

            AC*AC = 2*AB*AB - 2*AB*AB*cos(lon1-lon2) = 2*r*r*cos(lat1)*cos(lat1)*(1-cos(lon1-lon2));

            DF*DF = 2*DE*DE - 2*DE*DE*cos(lon1-lon2) = 2*r*r*cos(lat2)*cos(lat2)*(1-cos(lon1-lon2));

            AC*DF = 2*r*r*cos(lat1)*cos(lat2)*(1-cos(lon1-lon2));

扫描二维码关注公众号,回复: 2587244 查看本文章

            由托勒密定理有 AC*DF + AD*AD = CD*CD 整理有:

            CD = r*sqrt(2-2*(cos(lat1)*cos(lat2)*cos(lon1-lon2)+sin(lat1)*sin(lat2)));

注意:输出最近的整数,%.0lf即可。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
	double r = 6371009;
	double p = acos(-1.0);
	
	int    n;
	double l1,d1,l2,d2;
	while ( scanf("%d",&n) != EOF )
	while ( n -- ) {
		scanf("%lf%lf%lf%lf",&l1,&d1,&l2,&d2);
		l1 *= p/180.0; l2 *= p/180.0;
		d1 *= p/180.0; d2 *= p/180.0;
		
		double d = r*sqrt(2-2*(cos(l1)*cos(l2)*cos(d1-d2)+sin(l1)*sin(l2)));
		printf("%.0lf\n",2*asin(d/(2*r))*r-d);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/MallowFlower/article/details/80200672
今日推荐