2016-10-25 7 views
1

Я работаю с 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 для края моего круга?

+2

У меня нет времени, чтобы написать полезный ответ, но вы должны учитывать, что для круга с радиусом более нескольких километров в любой точке за пределами тропиков он * будет * перекошен, потому что продольный линии пересекаются на полюсах. Вам нужно либо проецировать свой круг на сфероид, либо проектировать свою систему координат из геоида, который вы используете, обратно в 3D-пространство, прежде чем вы вычисляете круг, если вы хотите избежать хрящей. – greyfade

+0

О, я знаю, что проблема скрежет. Меня укусили несколько раз. Однако, я не думаю, что это проблема. Я должен добавить расстояние до моего первоначального сообщения, но радиус горизонтально составляет ~ 190 метров, по вертикали - около 340 метров (когда оба должны быть одинаковыми).Я бы не подумал, что скрежет будет такой крайностью – Acorn

ответ

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

Этот код 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 объект с {широта: N, долгота: м}

Please see the jsFiddle here, где вы сможете найти недостающие биты, как постоянные значения и функции полезности.

EARTH_RADIUS в метрах, так поэтому вы задаете расстояние в метрах

Результат долготы зажат в диапазоне -180 -> +180 градусов

Если вы хотите точек, равномерно распределенных по окружности, рип из случайной опорной части и передать чисел от 0 до TWO_PI

EDIT: следует отметить, что этот код основан на алгоритмах из this page

0

Ну, понял это - я (глупо) думал, что радиус, рассчитанный с помощью лат-лона, будет однородным. Чтобы устранить проблему, я вместо этого получил расстояние в метрах от начала до остановки и использовал это как свой радиус, чтобы найти правильные точки lat, lon.