diff --git a/samples/blackmiscquantities/samplesaviation.cpp b/samples/blackmiscquantities/samplesaviation.cpp index 77204bef9..054cc1302 100644 --- a/samples/blackmiscquantities/samplesaviation.cpp +++ b/samples/blackmiscquantities/samplesaviation.cpp @@ -17,6 +17,7 @@ namespace BlackMiscTest int CSamplesAviation::samples() { // CSpeed s1(10, CSpeedUnit::kts()); + CMeasurementPrefix p1 = CMeasurementPrefix::G(); CAngle a(10, CAngleUnit::deg()); qDebug() << a; diff --git a/samples/blackmiscvectorgeo/samplesvectormatrix.cpp b/samples/blackmiscvectorgeo/samplesvectormatrix.cpp index ff49e1b27..8ac657a21 100644 --- a/samples/blackmiscvectorgeo/samplesvectormatrix.cpp +++ b/samples/blackmiscvectorgeo/samplesvectormatrix.cpp @@ -2,7 +2,7 @@ using namespace BlackMisc::Math; -/*! +/* * Run the samples */ int BlackMiscTest::CSamplesVectorMatrix::samples() diff --git a/src/blackmisc/basestreamstringifier.h b/src/blackmisc/basestreamstringifier.h index 714062e6f..d75e88acd 100644 --- a/src/blackmisc/basestreamstringifier.h +++ b/src/blackmisc/basestreamstringifier.h @@ -20,12 +20,27 @@ template class CBaseStreamStringifier * \param uc * \return */ - friend QDebug &operator<<(QDebug &debug, const UsingClass &uc) + friend QDebug operator<<(QDebug debug, const UsingClass &uc) { - const CBaseStreamStringifier &s = uc; - debug << s.stringForStreaming(); + const CBaseStreamStringifier &sf = uc; // allows to acces protected method + debug << sf.stringForStreaming(); 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 @@ -46,8 +61,8 @@ template class CBaseStreamStringifier */ friend QDataStream &operator<<(QDataStream &stream, const UsingClass &uc) { - const CBaseStreamStringifier &s = uc; - stream << s.stringForStreaming(); + const CBaseStreamStringifier &sf = uc; // allows to acces protected method + stream << sf.stringForStreaming(); return stream; } @@ -59,8 +74,8 @@ template class CBaseStreamStringifier */ friend CLogMessage &operator<<(CLogMessage &log, const UsingClass &uc) { - const CBaseStreamStringifier &s = uc; - log << s.stringForStreaming(); + const CBaseStreamStringifier &sf = uc; // allows to acces protected method + log << sf.stringForStreaming(); return log; } @@ -72,8 +87,8 @@ template class CBaseStreamStringifier */ friend std::ostream &operator<<(std::ostream &ostr, const UsingClass &uc) { - const CBaseStreamStringifier &s = uc; - ostr << s.stringForStreaming().toStdString(); + const CBaseStreamStringifier &sf = uc; // allows to acces protected method + ostr << sf.stringForStreaming().toStdString(); return ostr; } diff --git a/src/blackmisc/coordinatetransformation.cpp b/src/blackmisc/coordinatetransformation.cpp index 29a72abbb..a79483ce9 100644 --- a/src/blackmisc/coordinatetransformation.cpp +++ b/src/blackmisc/coordinatetransformation.cpp @@ -66,8 +66,6 @@ CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateNed &ned) */ CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateGeodetic &geo) { - // TODO: Clarify the comparisons with fixed angles (==90, ==180) -> what happens here - CLatitude lat = geo.latitude(); CLongitude lon = geo.longitude(); @@ -96,10 +94,9 @@ CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateGeodetic &geo */ CCoordinateNed CCoordinateTransformation::toNed(const CCoordinateEcef &ecef, const CCoordinateGeodetic &referencePosition) { - CLatitude lat = referencePosition.latitude(); CLongitude lon = referencePosition.longitude(); - double angleRad = - (lat.value(CAngleUnit::rad())) - CMath::PI() / 2; + double angleRad = - (lat.value(CAngleUnit::rad())) - CMath::PIHALF(); CMatrix3x3 dcm1; CMatrix3x3 dcm2(0.0); diff --git a/src/blackmisc/coordinatetransformation.h b/src/blackmisc/coordinatetransformation.h index 581a29ec9..b4e9a62e3 100644 --- a/src/blackmisc/coordinatetransformation.h +++ b/src/blackmisc/coordinatetransformation.h @@ -46,7 +46,7 @@ private: */ static const double &Flattening() { - static double f = 1 / 298.257223563; + static double f = 1.0 / 298.257223563; return f; } @@ -76,7 +76,7 @@ private: */ static const double &e2abs() { - static double e2abs = abs(e2()); + static double e2abs = qAbs(e2()); return e2abs; } @@ -86,7 +86,7 @@ private: */ 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; } @@ -95,7 +95,6 @@ private: */ CCoordinateTransformation() {} - public: /*! * \brief NED to ECEF diff --git a/src/blackmisc/mathematics.cpp b/src/blackmisc/mathematics.cpp index fed3cc7a3..8e5b86646 100644 --- a/src/blackmisc/mathematics.cpp +++ b/src/blackmisc/mathematics.cpp @@ -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 * 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/. */ #include "blackmisc/mathematics.h" -#include // std::max +#include // std::max #include namespace BlackMisc @@ -17,8 +17,8 @@ namespace Math */ double CMath::hypot(double x, double y) { - x = abs(x); - y = abs(y); + x = qAbs(x); + y = qAbs(y); double max = std::max(x, y); double min = std::min(x, y); double r = min / max; @@ -31,7 +31,7 @@ double CMath::hypot(double x, double y) double CMath::cubicRootReal(double x) { 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; } diff --git a/src/blackmisc/mathematics.h b/src/blackmisc/mathematics.h index 9105bd9f0..e97a72382 100644 --- a/src/blackmisc/mathematics.h +++ b/src/blackmisc/mathematics.h @@ -70,6 +70,16 @@ public: */ 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 * \return @@ -86,7 +96,7 @@ public: */ static const double &PI2() { - static double pi2 = PI(); + static double pi2 = 8.0 * qAtan(1.0); return pi2; } diff --git a/src/blackmisc/pqphysicalquantity.cpp b/src/blackmisc/pqphysicalquantity.cpp index ff65846f8..78be3743c 100644 --- a/src/blackmisc/pqphysicalquantity.cpp +++ b/src/blackmisc/pqphysicalquantity.cpp @@ -57,26 +57,29 @@ template bool CPhysicalQuantity::operator ==(const // some special cases for best quality double diff; 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) { // same unit if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue) { // pure integer comparison, no rounding issues - return this->m_unitValueI == otherQuantity.m_unitValueI; + eq = this->m_unitValueI == otherQuantity.m_unitValueI; } else { - diff = abs(this->m_unitValueD - otherQuantity.m_unitValueD); - return diff <= (lenient * this->m_unit.getEpsilon()); + // same unit, comparison based on double + diff = qAbs(this->m_unitValueD - otherQuantity.m_unitValueD); + eq = diff <= (lenient * this->m_unit.getEpsilon()); } } else { // based on SI value - diff = abs(this->m_convertedSiUnitValueD - otherQuantity.m_convertedSiUnitValueD); - return diff <= (lenient * this->m_unit.getEpsilon()); + diff = qAbs(this->m_convertedSiUnitValueD - otherQuantity.m_convertedSiUnitValueD); + eq = diff <= (lenient * this->m_conversionSiUnit.getEpsilon()); } + return eq; } /* @@ -89,7 +92,7 @@ template bool CPhysicalQuantity::operator !=(const } /* - * Assigment operator = + * Assignment operator = */ template CPhysicalQuantity& CPhysicalQuantity::operator=(const CPhysicalQuantity &otherQuantity) { @@ -238,9 +241,11 @@ template PQ CPhysicalQuantity::operator /(double di */ template bool CPhysicalQuantity::operator <(const CPhysicalQuantity &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; - return (diff < 0 && abs(diff) >= this->m_unit.getEpsilon()); + return (diff < 0); } /* @@ -249,7 +254,7 @@ template bool CPhysicalQuantity::operator <(const C template bool CPhysicalQuantity::operator >(const CPhysicalQuantity &otherQuantity) const { if (this == &otherQuantity) return false; - return otherQuantity < *this; + return otherQuantity < (*this); } /* diff --git a/tests/blackmisc/testaviation.cpp b/tests/blackmisc/testaviation.cpp index b03c72a06..4652a9100 100644 --- a/tests/blackmisc/testaviation.cpp +++ b/tests/blackmisc/testaviation.cpp @@ -32,7 +32,8 @@ void CTestAviation::headingBasics() h4 = h1; QVERIFY2(h1 != h2, "Magnetic and true heading are not the same"); 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"); h1 -= h1; diff --git a/tests/blackmisc/testgeo.cpp b/tests/blackmisc/testgeo.cpp index 26d6c15e4..57c0fab60 100644 --- a/tests/blackmisc/testgeo.cpp +++ b/tests/blackmisc/testgeo.cpp @@ -20,12 +20,14 @@ void CTestGeo::geoBasics() CCoordinateGeodetic startGeoVec(lat, lon, h); CCoordinateEcef mediumEcefVec = CCoordinateTransformation::toEcef(startGeoVec); 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 "); CCoordinateNed nedVec = CCoordinateTransformation::toNed(mediumEcefVec, startGeoVec); 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"); } diff --git a/tests/blackmisc/testphysicalquantities.cpp b/tests/blackmisc/testphysicalquantities.cpp index 94cf5b5c0..6dabc06cb 100644 --- a/tests/blackmisc/testphysicalquantities.cpp +++ b/tests/blackmisc/testphysicalquantities.cpp @@ -53,12 +53,14 @@ void CTestPhysicalQuantities::lengthBasics() QVERIFY2(!(d1 > d2), "Nothing shall be less / greater"); // epsilon tests + d1 = d2; // both in same unit d1.addUnitValue(d1.getUnit().getEpsilon()); // this should be still the same - QVERIFY2(d1 == d2, "Epsilon: 1meter+epsilon shall be 100cm"); - QVERIFY2(!(d1 != d2), "Epsilon: 1meter+epsilon shall be 100cm"); + QVERIFY2(d1 == d2, "Epsilon: 100cm + 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 - 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"); }