EDIT: это неинициализированный переменное ... :(несовместимый выход фиксируется путем размещения отладочного
Объяснение: Конструктор PointLLA я использовал только прошел через широту и долготы, но я никогда не явно установить внутренний элемент высоты переменная до 0. Ошибка новичков ...
Оригинальный вопрос: У меня довольно жуткое время с ошибкой в моем коде. Я вычисляю расстояния между одной точкой и углами прямоугольника. случай, точка центрирована по прямоугольнику, поэтому я должен получить четыре равных расстояния. Я получаю три равных расстояния, а одно почти равное значение расстояния - это несоответствие палатка (разная при каждом ее запуске).
Если у меня есть несколько ключевых операторов отладки (в основном это просто вызов std :: cout), которые явно распечатывают местоположение каждого прямоугольника, я получаю ожидаемое значение расстояния и несогласованность исчезает. Вот соответствующий код:
// calculate the minimum and maximum distance to
// camEye within the available lat/lon bounds
Vec3 viewBoundsNE; convLLAToECEF(PointLLA(maxLat,maxLon),viewBoundsNE);
Vec3 viewBoundsNW; convLLAToECEF(PointLLA(maxLat,minLon),viewBoundsNW);
Vec3 viewBoundsSW; convLLAToECEF(PointLLA(minLat,minLon),viewBoundsSW);
Vec3 viewBoundsSE; convLLAToECEF(PointLLA(minLat,maxLon),viewBoundsSE);
// begin comment this block out, and buggy output
OSRDEBUG << "INFO: NE (" << viewBoundsNE.x
<< " " << viewBoundsNE.y
<< " " << viewBoundsNE.z << ")";
OSRDEBUG << "INFO: NW (" << viewBoundsNW.x
<< " " << viewBoundsNW.y
<< " " << viewBoundsNW.z << ")";
OSRDEBUG << "INFO: SE (" << viewBoundsSW.x
<< " " << viewBoundsSW.y
<< " " << viewBoundsSW.z << ")";
OSRDEBUG << "INFO: SW (" << viewBoundsSE.x
<< " " << viewBoundsSE.y
<< " " << viewBoundsSE.z << ")";
// --------------- end
// to get the maximum distance, find the maxima
// of the distances to each corner of the bounding box
double distToNE = camEye.DistanceTo(viewBoundsNE);
double distToNW = camEye.DistanceTo(viewBoundsNW); // <-- inconsistent
double distToSE = camEye.DistanceTo(viewBoundsSE);
double distToSW = camEye.DistanceTo(viewBoundsSW);
std::cout << "INFO: distToNE: " << distToNE << std::endl;
std::cout << "INFO: distToNW: " << distToNW << std::endl; // <-- inconsistent
std::cout << "INFO: distToSE: " << distToSE << std::endl;
std::cout << "INFO: distToSW: " << distToSW << std::endl;
double maxDistToViewBounds = distToNE;
if(distToNW > maxDistToViewBounds)
{ maxDistToViewBounds = distToNW; }
if(distToSE > maxDistToViewBounds)
{ maxDistToViewBounds = distToSE; }
if(distToSW > maxDistToViewBounds)
{ maxDistToViewBounds = distToSW; }
OSRDEBUG << "INFO: maxDistToViewBounds: " << maxDistToViewBounds;
Так что, если я бегу показано выше код, я получить выход следующим образом:
INFO: NE (6378137 104.12492 78.289415)
INFO: NW (6378137 -104.12492 78.289415)
INFO: SE (6378137 -104.12492 -78.289415)
INFO: SW (6378137 104.12492 -78.289415)
INFO: distToNE: 462.71851
INFO: distToNW: 462.71851
INFO: distToSE: 462.71851
INFO: distToSW: 462.71851
INFO: maxDistToViewBounds: 462.71851
Точно так, как ожидалось. Обратите внимание, что все значения distTo * совпадают. Я могу запускать программу снова и снова, и получаю точно такой же результат. Но теперь, если я закомментировать блок, который я отметил в приведенном выше коде, я получаю что-то вроде этого:
INFO: distToNE: 462.71851
INFO: distToNW: 463.85601
INFO: distToSE: 462.71851
INFO: distToSW: 462.71851
INFO: maxDistToViewBounds: 463.85601
Каждый пробег будет немного отличаться distToNW. Почему distToNW, а не другие значения? Я не знаю. Еще несколько прогонов:
463.06218
462.79352
462.76194
462.74772
463.09787
464.04648
Итак ... что здесь происходит? Я попробовал очистить/перестроить свой проект, чтобы увидеть, произошло ли что-то странное, но это не помогло. Я использую GCC 4.6.3 с целью x86.
EDIT: добавление определений соответствующих функций.
void MapRenderer::convLLAToECEF(const PointLLA &pointLLA, Vec3 &pointECEF)
{
// conversion formula from...
// hxxp://www.microem.ru/pages/u_blox/tech/dataconvert/GPS.G1-X-00006.pdf
// remember to convert deg->rad
double sinLat = sin(pointLLA.lat * K_PI/180.0f);
double sinLon = sin(pointLLA.lon * K_PI/180.0f);
double cosLat = cos(pointLLA.lat * K_PI/180.0f);
double cosLon = cos(pointLLA.lon * K_PI/180.0f);
// v = radius of curvature (meters)
double v = ELL_SEMI_MAJOR/(sqrt(1-(ELL_ECC_EXP2*sinLat*sinLat)));
pointECEF.x = (v + pointLLA.alt) * cosLat * cosLon;
pointECEF.y = (v + pointLLA.alt) * cosLat * sinLon;
pointECEF.z = ((1-ELL_ECC_EXP2)*v + pointLLA.alt)*sinLat;
}
// and from the Vec3 class defn
inline double DistanceTo(Vec3 const &otherVec) const
{
return sqrt((x-otherVec.x)*(x-otherVec.x) +
(y-otherVec.y)*(y-otherVec.y) +
(z-otherVec.z)*(z-otherVec.z));
}
Просто ужасно. Мне жаль вас. –
Вы пытались выборочно удалить инструкции отладки? Выйдя в функцию 'DistanceTo', чтобы узнать, что пошло не так? –
Обеспечьте реализацию «convLLAToECEF» и «DistanceTo» –