mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-18 03:15:34 +08:00
Fixed all issues detected by the test cases under MinGW - such as usage of abs() -> changed to qAbs(), rounding issues detected during calculations, and changed streaming methods with qDebug() (QDebug vs &QDebug issue).
This commit is contained in:
@@ -17,6 +17,7 @@ namespace BlackMiscTest
|
|||||||
int CSamplesAviation::samples()
|
int CSamplesAviation::samples()
|
||||||
{
|
{
|
||||||
// CSpeed s1(10, CSpeedUnit::kts());
|
// CSpeed s1(10, CSpeedUnit::kts());
|
||||||
|
|
||||||
CMeasurementPrefix p1 = CMeasurementPrefix::G();
|
CMeasurementPrefix p1 = CMeasurementPrefix::G();
|
||||||
CAngle a(10, CAngleUnit::deg());
|
CAngle a(10, CAngleUnit::deg());
|
||||||
qDebug() << a;
|
qDebug() << a;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
using namespace BlackMisc::Math;
|
using namespace BlackMisc::Math;
|
||||||
|
|
||||||
/*!
|
/*
|
||||||
* Run the samples
|
* Run the samples
|
||||||
*/
|
*/
|
||||||
int BlackMiscTest::CSamplesVectorMatrix::samples()
|
int BlackMiscTest::CSamplesVectorMatrix::samples()
|
||||||
|
|||||||
@@ -20,12 +20,27 @@ template <class UsingClass> class CBaseStreamStringifier
|
|||||||
* \param uc
|
* \param uc
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
friend QDebug &operator<<(QDebug &debug, const UsingClass &uc)
|
friend QDebug operator<<(QDebug debug, const UsingClass &uc)
|
||||||
{
|
{
|
||||||
const CBaseStreamStringifier &s = uc;
|
const CBaseStreamStringifier &sf = uc; // allows to acces protected method
|
||||||
debug << s.stringForStreaming();
|
debug << sf.stringForStreaming();
|
||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
// msvc2010: friend QDebug &operator<<(QDebug &debug, const UsingClass &uc)
|
||||||
|
// MinGW: No reference
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Operator << based on text stream
|
||||||
|
* \param textStream
|
||||||
|
* \param uc
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
friend QTextStream &operator<<(QTextStream &textStream, const UsingClass &uc)
|
||||||
|
{
|
||||||
|
const CBaseStreamStringifier &sf = uc; // allows to acces protected method
|
||||||
|
textStream << sf.stringForStreaming();
|
||||||
|
return textStream;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Operator << when there is no debug stream
|
* \brief Operator << when there is no debug stream
|
||||||
@@ -46,8 +61,8 @@ template <class UsingClass> class CBaseStreamStringifier
|
|||||||
*/
|
*/
|
||||||
friend QDataStream &operator<<(QDataStream &stream, const UsingClass &uc)
|
friend QDataStream &operator<<(QDataStream &stream, const UsingClass &uc)
|
||||||
{
|
{
|
||||||
const CBaseStreamStringifier &s = uc;
|
const CBaseStreamStringifier &sf = uc; // allows to acces protected method
|
||||||
stream << s.stringForStreaming();
|
stream << sf.stringForStreaming();
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,8 +74,8 @@ template <class UsingClass> class CBaseStreamStringifier
|
|||||||
*/
|
*/
|
||||||
friend CLogMessage &operator<<(CLogMessage &log, const UsingClass &uc)
|
friend CLogMessage &operator<<(CLogMessage &log, const UsingClass &uc)
|
||||||
{
|
{
|
||||||
const CBaseStreamStringifier &s = uc;
|
const CBaseStreamStringifier &sf = uc; // allows to acces protected method
|
||||||
log << s.stringForStreaming();
|
log << sf.stringForStreaming();
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,8 +87,8 @@ template <class UsingClass> class CBaseStreamStringifier
|
|||||||
*/
|
*/
|
||||||
friend std::ostream &operator<<(std::ostream &ostr, const UsingClass &uc)
|
friend std::ostream &operator<<(std::ostream &ostr, const UsingClass &uc)
|
||||||
{
|
{
|
||||||
const CBaseStreamStringifier &s = uc;
|
const CBaseStreamStringifier &sf = uc; // allows to acces protected method
|
||||||
ostr << s.stringForStreaming().toStdString();
|
ostr << sf.stringForStreaming().toStdString();
|
||||||
return ostr;
|
return ostr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,8 +66,6 @@ CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateNed &ned)
|
|||||||
*/
|
*/
|
||||||
CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateGeodetic &geo)
|
CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateGeodetic &geo)
|
||||||
{
|
{
|
||||||
// TODO: Clarify the comparisons with fixed angles (==90, ==180) -> what happens here
|
|
||||||
|
|
||||||
CLatitude lat = geo.latitude();
|
CLatitude lat = geo.latitude();
|
||||||
CLongitude lon = geo.longitude();
|
CLongitude lon = geo.longitude();
|
||||||
|
|
||||||
@@ -96,10 +94,9 @@ CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateGeodetic &geo
|
|||||||
*/
|
*/
|
||||||
CCoordinateNed CCoordinateTransformation::toNed(const CCoordinateEcef &ecef, const CCoordinateGeodetic &referencePosition)
|
CCoordinateNed CCoordinateTransformation::toNed(const CCoordinateEcef &ecef, const CCoordinateGeodetic &referencePosition)
|
||||||
{
|
{
|
||||||
|
|
||||||
CLatitude lat = referencePosition.latitude();
|
CLatitude lat = referencePosition.latitude();
|
||||||
CLongitude lon = referencePosition.longitude();
|
CLongitude lon = referencePosition.longitude();
|
||||||
double angleRad = - (lat.value(CAngleUnit::rad())) - CMath::PI() / 2;
|
double angleRad = - (lat.value(CAngleUnit::rad())) - CMath::PIHALF();
|
||||||
|
|
||||||
CMatrix3x3 dcm1;
|
CMatrix3x3 dcm1;
|
||||||
CMatrix3x3 dcm2(0.0);
|
CMatrix3x3 dcm2(0.0);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
static const double &Flattening()
|
static const double &Flattening()
|
||||||
{
|
{
|
||||||
static double f = 1 / 298.257223563;
|
static double f = 1.0 / 298.257223563;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
static const double &e2abs()
|
static const double &e2abs()
|
||||||
{
|
{
|
||||||
static double e2abs = abs(e2());
|
static double e2abs = qAbs(e2());
|
||||||
return e2abs;
|
return e2abs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
static const double &e2m()
|
static const double &e2m()
|
||||||
{
|
{
|
||||||
static double e2m = BlackMisc::Math::CMath::square(1 - Flattening());
|
static double e2m = BlackMisc::Math::CMath::square(1.0 - Flattening());
|
||||||
return e2m;
|
return e2m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +95,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
CCoordinateTransformation() {}
|
CCoordinateTransformation() {}
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
* \brief NED to ECEF
|
* \brief NED to ECEF
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/* Copyright (C) 2013 VATSIM Community / authors
|
/* Copyright (C) 2013 VATSIM Community / contributors
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "blackmisc/mathematics.h"
|
#include "blackmisc/mathematics.h"
|
||||||
#include <algorithm> // std::max
|
#include <algorithm> // std::max
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
@@ -17,8 +17,8 @@ namespace Math
|
|||||||
*/
|
*/
|
||||||
double CMath::hypot(double x, double y)
|
double CMath::hypot(double x, double y)
|
||||||
{
|
{
|
||||||
x = abs(x);
|
x = qAbs(x);
|
||||||
y = abs(y);
|
y = qAbs(y);
|
||||||
double max = std::max(x, y);
|
double max = std::max(x, y);
|
||||||
double min = std::min(x, y);
|
double min = std::min(x, y);
|
||||||
double r = min / max;
|
double r = min / max;
|
||||||
@@ -31,7 +31,7 @@ double CMath::hypot(double x, double y)
|
|||||||
double CMath::cubicRootReal(double x)
|
double CMath::cubicRootReal(double x)
|
||||||
{
|
{
|
||||||
double result;
|
double result;
|
||||||
result = std::pow(std::abs(x), (double)1 / 3);
|
result = std::pow(qAbs(x), (double)1.0 / 3.0);
|
||||||
return x < 0 ? -result : result;
|
return x < 0 ? -result : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
static double roundEpsilon(double value, double epsilon);
|
static double roundEpsilon(double value, double epsilon);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief PI
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
static const double &PIHALF()
|
||||||
|
{
|
||||||
|
static double pi = 2.0 * qAtan(1.0);
|
||||||
|
return pi;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief PI
|
* \brief PI
|
||||||
* \return
|
* \return
|
||||||
@@ -86,7 +96,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
static const double &PI2()
|
static const double &PI2()
|
||||||
{
|
{
|
||||||
static double pi2 = PI();
|
static double pi2 = 8.0 * qAtan(1.0);
|
||||||
return pi2;
|
return pi2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,26 +57,29 @@ template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::operator ==(const
|
|||||||
// some special cases for best quality
|
// some special cases for best quality
|
||||||
double diff;
|
double diff;
|
||||||
const double lenient = 1.001; // even diff already has a rounding issue to be avoided
|
const double lenient = 1.001; // even diff already has a rounding issue to be avoided
|
||||||
|
bool eq = false;
|
||||||
if (this->m_unit == otherQuantity.m_unit)
|
if (this->m_unit == otherQuantity.m_unit)
|
||||||
{
|
{
|
||||||
// same unit
|
// same unit
|
||||||
if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue)
|
if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue)
|
||||||
{
|
{
|
||||||
// pure integer comparison, no rounding issues
|
// pure integer comparison, no rounding issues
|
||||||
return this->m_unitValueI == otherQuantity.m_unitValueI;
|
eq = this->m_unitValueI == otherQuantity.m_unitValueI;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
diff = abs(this->m_unitValueD - otherQuantity.m_unitValueD);
|
// same unit, comparison based on double
|
||||||
return diff <= (lenient * this->m_unit.getEpsilon());
|
diff = qAbs(this->m_unitValueD - otherQuantity.m_unitValueD);
|
||||||
|
eq = diff <= (lenient * this->m_unit.getEpsilon());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// based on SI value
|
// based on SI value
|
||||||
diff = abs(this->m_convertedSiUnitValueD - otherQuantity.m_convertedSiUnitValueD);
|
diff = qAbs(this->m_convertedSiUnitValueD - otherQuantity.m_convertedSiUnitValueD);
|
||||||
return diff <= (lenient * this->m_unit.getEpsilon());
|
eq = diff <= (lenient * this->m_conversionSiUnit.getEpsilon());
|
||||||
}
|
}
|
||||||
|
return eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -89,7 +92,7 @@ template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::operator !=(const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Assigment operator =
|
* Assignment operator =
|
||||||
*/
|
*/
|
||||||
template <class MU, class PQ> CPhysicalQuantity<MU, PQ>& CPhysicalQuantity<MU, PQ>::operator=(const CPhysicalQuantity<MU, PQ> &otherQuantity)
|
template <class MU, class PQ> CPhysicalQuantity<MU, PQ>& CPhysicalQuantity<MU, PQ>::operator=(const CPhysicalQuantity<MU, PQ> &otherQuantity)
|
||||||
{
|
{
|
||||||
@@ -238,9 +241,11 @@ template <class MU, class PQ> PQ CPhysicalQuantity<MU, PQ>::operator /(double di
|
|||||||
*/
|
*/
|
||||||
template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::operator <(const CPhysicalQuantity<MU, PQ> &otherQuantity) const
|
template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::operator <(const CPhysicalQuantity<MU, PQ> &otherQuantity) const
|
||||||
{
|
{
|
||||||
if (this == &otherQuantity) return false;
|
if ((*this) == otherQuantity) return false;
|
||||||
|
|
||||||
|
// == considers epsilon, so we now have a diff > epsilon here
|
||||||
double diff = this->m_convertedSiUnitValueD - otherQuantity.m_convertedSiUnitValueD;
|
double diff = this->m_convertedSiUnitValueD - otherQuantity.m_convertedSiUnitValueD;
|
||||||
return (diff < 0 && abs(diff) >= this->m_unit.getEpsilon());
|
return (diff < 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -249,7 +254,7 @@ template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::operator <(const C
|
|||||||
template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::operator >(const CPhysicalQuantity<MU, PQ> &otherQuantity) const
|
template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::operator >(const CPhysicalQuantity<MU, PQ> &otherQuantity) const
|
||||||
{
|
{
|
||||||
if (this == &otherQuantity) return false;
|
if (this == &otherQuantity) return false;
|
||||||
return otherQuantity < *this;
|
return otherQuantity < (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ void CTestAviation::headingBasics()
|
|||||||
h4 = h1;
|
h4 = h1;
|
||||||
QVERIFY2(h1 != h2, "Magnetic and true heading are not the same");
|
QVERIFY2(h1 != h2, "Magnetic and true heading are not the same");
|
||||||
QVERIFY2(h1 < h3, "180deg are less than 181deg");
|
QVERIFY2(h1 < h3, "180deg are less than 181deg");
|
||||||
QVERIFY2(a1 > h3, "200deg are more than 200deg");
|
QVERIFY2(h3 > h1, "181deg are more than 181deg");
|
||||||
|
QVERIFY2(a1 > h3, "200deg are more than 181deg");
|
||||||
QVERIFY2(h4 == h1, "Values shall be equal");
|
QVERIFY2(h4 == h1, "Values shall be equal");
|
||||||
|
|
||||||
h1 -= h1;
|
h1 -= h1;
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ void CTestGeo::geoBasics()
|
|||||||
CCoordinateGeodetic startGeoVec(lat, lon, h);
|
CCoordinateGeodetic startGeoVec(lat, lon, h);
|
||||||
CCoordinateEcef mediumEcefVec = CCoordinateTransformation::toEcef(startGeoVec);
|
CCoordinateEcef mediumEcefVec = CCoordinateTransformation::toEcef(startGeoVec);
|
||||||
CCoordinateGeodetic endGeoVec = CCoordinateTransformation::toGeodetic(mediumEcefVec);
|
CCoordinateGeodetic endGeoVec = CCoordinateTransformation::toGeodetic(mediumEcefVec);
|
||||||
|
|
||||||
|
// this == contains some implicit rounding, since it is based on PQs
|
||||||
QVERIFY2(startGeoVec == endGeoVec, "Reconverted geo vector should be equal ");
|
QVERIFY2(startGeoVec == endGeoVec, "Reconverted geo vector should be equal ");
|
||||||
|
|
||||||
CCoordinateNed nedVec = CCoordinateTransformation::toNed(mediumEcefVec, startGeoVec);
|
CCoordinateNed nedVec = CCoordinateTransformation::toNed(mediumEcefVec, startGeoVec);
|
||||||
CCoordinateEcef ecefReconvert = CCoordinateTransformation::toEcef(nedVec);
|
CCoordinateEcef ecefReconvert = CCoordinateTransformation::toEcef(nedVec);
|
||||||
|
|
||||||
QVERIFY2(mediumEcefVec != ecefReconvert, "Reconverted geo vector, expect some minor rounding issues");
|
// check against rounded reconvert
|
||||||
QVERIFY2(mediumEcefVec.round() == ecefReconvert.round(), "Reconverted geo vector should be equal");
|
QVERIFY2(mediumEcefVec.round() == ecefReconvert.round(), "Reconverted geo vector should be equal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,12 +53,14 @@ void CTestPhysicalQuantities::lengthBasics()
|
|||||||
QVERIFY2(!(d1 > d2), "Nothing shall be less / greater");
|
QVERIFY2(!(d1 > d2), "Nothing shall be less / greater");
|
||||||
|
|
||||||
// epsilon tests
|
// epsilon tests
|
||||||
|
d1 = d2; // both in same unit
|
||||||
d1.addUnitValue(d1.getUnit().getEpsilon()); // this should be still the same
|
d1.addUnitValue(d1.getUnit().getEpsilon()); // this should be still the same
|
||||||
QVERIFY2(d1 == d2, "Epsilon: 1meter+epsilon shall be 100cm");
|
QVERIFY2(d1 == d2, "Epsilon: 100cm + epsilon shall be 100cm");
|
||||||
QVERIFY2(!(d1 != d2), "Epsilon: 1meter+epsilon shall be 100cm");
|
QVERIFY2(!(d1 != d2), "Epsilon: 100cm + epsilon shall be still 100cm");
|
||||||
|
QVERIFY2(!(d1 > d2), "d1 shall not be greater");
|
||||||
|
|
||||||
d1.addUnitValue(d1.getUnit().getEpsilon()); // now over epsilon threshold
|
d1.addUnitValue(d1.getUnit().getEpsilon()); // now over epsilon threshold
|
||||||
QVERIFY2(d1 != d2, "Epsilon exceeded: 1meter+2epsilon shall not be 100cm");
|
QVERIFY2(d1 != d2, "Epsilon exceeded: 100 cm + 2 epsilon shall not be 100cm");
|
||||||
QVERIFY2(d1 > d2, "d1 shall be greater");
|
QVERIFY2(d1 > d2, "d1 shall be greater");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user