计算投射到地球上的圆上的点

时间:2016-10-25 21:23:04

标签: c++ geometry geospatial geo

我正在使用osgEarth,我正在尝试绘制从单个点突出到圆圈的线条。 起初,我尝试执行以下操作(其中m_x_start_lon和m_y_start_lat是一些任意的起点):

    double x_lon = 0.0f;
    double y_lat = 0.0f;
    if (!GetPointFromScreen(args, x_lon, y_lat)) return true;

    m_stop_x_lon = x_lon;
    m_stop_y_lat = y_lat;

    double x_dist = abs(m_stop_x_lon - m_start_x_lon);
    double y_dist = abs(m_stop_y_lat - m_start_y_lat);

        m_radius = sqrtf(x_dist * x_dist + y_dist * y_dist);

    std::vector<double> x_points(m_slices);
    std::vector<double> y_points(m_slices);

    //m_slices = 30, which is the number of lines to represent the circle
    for (std::size_t i = 0u; i < m_slices; ++i)
    {
        double new_x = m_start_x_lon + m_radius * cos(i);
        double new_y = m_start_y_lat + m_radius * sin(i);

        x_points.at(i) = new_x;
        y_points.at(i) = new_y;
    }

然而,这只是一种工作。我可以得出的唯一结论是,使用纬度和经度以某种方式扭曲结果。 Please see the attached picture.

水平半径约为190米,垂直半径约为340米。我知道当你离更远的地方时会发生压扁,但是在它超过至少几公里的长度之后我才认为这是极端的。即便如此,水平和垂直方向的半径应该匹配。

那么,我必须做些什么来获得正确的lon,我的圆圈边缘的lat坐标?

3 个答案:

答案 0 :(得分:1)

当您计算m_slices循环时,不是将角度切割为(2 * PI / m_slices),而是计算 sin() cos i的(),从0到m_slices。

double dAngle = (2 * PI / m_slices); // in radian

for (std::size_t i = 0u; i < m_slices; ++i)
{
    double new_x = m_start_x_lon + m_radius * cos(i * dAngle);
    double new_y = m_start_y_lat + m_radius * sin(i * dAngle);

    x_points.at(i) = new_x;
    y_points.at(i) = new_y;
}

答案 1 :(得分:1)

这个javascript代码(抱歉没有C ++)选择一个随机方位,并在该方向的特定起点处绘制一个点。

function pointAtDistance(inputCoords, distance) {
    const result = {}
    const coords = toRadians(inputCoords)
    const sinLat =  Math.sin(coords.latitude)
    const cosLat =  Math.cos(coords.latitude)

    const bearing = Math.random() * TWO_PI
    const theta = distance/EARTH_RADIUS
    const sinBearing = Math.sin(bearing)
    const cosBearing =  Math.cos(bearing)
    const sinTheta = Math.sin(theta)
    const cosTheta =    Math.cos(theta)

    result.latitude = Math.asin(sinLat*cosTheta+cosLat*sinTheta*cosBearing);
    result.longitude = coords.longitude + 
    Math.atan2( sinBearing*sinTheta*cosLat, cosTheta-sinLat*Math.sin(result.latitude )
        );
    result.longitude = ((result.longitude+THREE_PI)%TWO_PI)-Math.PI

    return toDegrees(result)
}

inputCoords是{latitude:n,经度:m}

的对象

Please see the jsFiddle here您可以在其中找到丢失的位,例如常量值和效用函数。

EARTH_RADIUS以米为单位,因此您指定以米为单位的距离

结果经度被限制在-180的范围内 - > +180度

如果你想要在圆圈周围有规律地分布点,请撕掉随机轴承部分并传入介于0和TWO_PI之间的数字

编辑:我应该提一下,此代码基于this page的算法

答案 2 :(得分:0)

好吧,想通了 - 我(愚蠢地)认为用lat,lon计算的半径是均匀的。 为了解决这个问题,我改为从开始到停止以米为单位的距离,并将其用作我的半径以找到正确的纬度,离点。