mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
Further details on classes like epsilon compare, further unit tests.
This commit is contained in:
@@ -22,12 +22,12 @@ int CSamplesPhysicalQuantities::samples()
|
|||||||
|
|
||||||
CMeasurementPrefix pf1 = CMeasurementPrefix::h();
|
CMeasurementPrefix pf1 = CMeasurementPrefix::h();
|
||||||
CMeasurementPrefix pf2 = CMeasurementPrefix::M();
|
CMeasurementPrefix pf2 = CMeasurementPrefix::M();
|
||||||
qDebug() << pf1 << pf2 << 1.0 * pf1;
|
qDebug() << pf1 << pf2 << (1.0 * pf1.toDouble());
|
||||||
|
|
||||||
CLengthUnit lu1(CLengthUnit::cm());
|
CLengthUnit lu1(CLengthUnit::cm());
|
||||||
CLengthUnit lu2(CLengthUnit::ft());
|
CLengthUnit lu2(CLengthUnit::ft());
|
||||||
QString lu1s = lu1;
|
QString lu1s = lu1.toQString();
|
||||||
QString lu2s = lu2;
|
QString lu2s = lu2.toQString();
|
||||||
qDebug() << lu1 << lu2 << lu1s << lu2s;
|
qDebug() << lu1 << lu2 << lu1s << lu2s;
|
||||||
const CLength l1(5.0, CLengthUnit::ft()); // 5 ft
|
const CLength l1(5.0, CLengthUnit::ft()); // 5 ft
|
||||||
CLength l2(1, CLengthUnit::NM()); // 1NM
|
CLength l2(1, CLengthUnit::NM()); // 1NM
|
||||||
|
|||||||
@@ -75,8 +75,9 @@ public:
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Cast as QString
|
* \brief Cast as QString
|
||||||
|
* \remarks operator cast caused too many ambiguity trouble
|
||||||
*/
|
*/
|
||||||
operator QString() const
|
QString toQString() const
|
||||||
{
|
{
|
||||||
return this->stringForConverter();
|
return this->stringForConverter();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateNed &ned)
|
|||||||
*/
|
*/
|
||||||
CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateGeodetic &geo)
|
CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateGeodetic &geo)
|
||||||
{
|
{
|
||||||
// TODO: Clarify the comparions with fixed angles (==90, ==180) -> what happens here
|
// 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();
|
||||||
|
|||||||
@@ -34,5 +34,33 @@ qreal CMath::cubicRootReal(qreal x)
|
|||||||
return x < 0 ? -result : result;
|
return x < 0 ? -result : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Round utility method
|
||||||
|
*/
|
||||||
|
double CMath::round(double value, int digits)
|
||||||
|
{
|
||||||
|
// gosh, is there no Qt method for this??? It's year 2013
|
||||||
|
double fractpart, intpart;
|
||||||
|
fractpart = modf(value, &intpart);
|
||||||
|
if (fractpart == 0) return value; // do not mess any "integers" to the worse
|
||||||
|
double m = pow(10.0, digits);
|
||||||
|
qint64 ri = qRound(value * m); // do not loose any range here
|
||||||
|
double rv = double(ri) / m;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Round by given epsilon value
|
||||||
|
*/
|
||||||
|
double CMath::roundEpsilon(double value, double epsilon)
|
||||||
|
{
|
||||||
|
double fractpart, intpart;
|
||||||
|
fractpart = modf(value, &intpart);
|
||||||
|
if (fractpart == 0) return value; // do not mess any "integers" to the worse
|
||||||
|
qint64 ri = qRound(value / epsilon);
|
||||||
|
double rv = double(ri) * epsilon; // do not loose any range here
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ namespace Math
|
|||||||
// Some namespace wide constant values
|
// Some namespace wide constant values
|
||||||
|
|
||||||
//! Mathematical constant Pi
|
//! Mathematical constant Pi
|
||||||
const qreal PI = 4.0 * qAtan(1.0);
|
const double PI = 4.0 * qAtan(1.0);
|
||||||
|
|
||||||
//! 2 * Pi
|
//! 2 * Pi
|
||||||
const qreal TwoPI = 2.0 * PI;
|
const double TwoPI = 2.0 * PI;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Math utils
|
* \brief Math utils
|
||||||
@@ -33,14 +33,14 @@ public:
|
|||||||
* \param y
|
* \param y
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
static qreal hypot(qreal x, qreal y);
|
static double hypot(double x, double y);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Calculates the square of x
|
* \brief Calculates the square of x
|
||||||
* \param x
|
* \param x
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
static inline qreal square(qreal x)
|
static inline double square(double x)
|
||||||
{
|
{
|
||||||
return x * x;
|
return x * x;
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ public:
|
|||||||
* \param x
|
* \param x
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
static inline qreal cubic(const qreal x)
|
static inline double cubic(const double x)
|
||||||
{
|
{
|
||||||
return x * x * x;
|
return x * x * x;
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,23 @@ public:
|
|||||||
* \param x
|
* \param x
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
static qreal cubicRootReal(qreal x);
|
static double cubicRootReal(double x);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Utility round method
|
||||||
|
* \param value
|
||||||
|
* \param digits
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
static double round(double value, int digits);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Round by given epsilon, e.g.
|
||||||
|
* \param value
|
||||||
|
* \param epsilon
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
static double roundEpsilon(double value, double epsilon);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
@@ -69,11 +69,11 @@ template<class ImplMatrix, int Rows, int Columns> bool CMatrixBase<ImplMatrix, R
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All values zero?
|
* All values equal?
|
||||||
*/
|
*/
|
||||||
template<class ImplMatrix, int Rows, int Columns> bool CMatrixBase<ImplMatrix, Rows, Columns>::allValuesEqual() const
|
template<class ImplMatrix, int Rows, int Columns> bool CMatrixBase<ImplMatrix, Rows, Columns>::allValuesEqual() const
|
||||||
{
|
{
|
||||||
double v = this->getElement(0,0);
|
double v = this->getElement(0, 0);
|
||||||
for (int r = 0; r < Rows; r++)
|
for (int r = 0; r < Rows; r++)
|
||||||
{
|
{
|
||||||
for (int c = 0; c < Columns; c++)
|
for (int c = 0; c < Columns; c++)
|
||||||
@@ -84,6 +84,19 @@ template<class ImplMatrix, int Rows, int Columns> bool CMatrixBase<ImplMatrix, R
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Round all values
|
||||||
|
*/
|
||||||
|
template<class ImplMatrix, int Rows, int Columns> void CMatrixBase<ImplMatrix, Rows, Columns>::round()
|
||||||
|
{
|
||||||
|
for (int r = 0; r < Rows; r++)
|
||||||
|
{
|
||||||
|
for (int c = 0; c < Columns; c++)
|
||||||
|
{
|
||||||
|
this->m_matrix(r, c) = CMath::roundEpsilon(this->m_matrix(r, c), 1E-10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert to string
|
* Convert to string
|
||||||
|
|||||||
@@ -203,6 +203,18 @@ public:
|
|||||||
return this->m_matrix.isIdentity();
|
return this->m_matrix.isIdentity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Is identity matrix? Epsilon considered.
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
bool isIdentityEpsilon() const
|
||||||
|
{
|
||||||
|
ImplMatrix m(0.0);
|
||||||
|
m += (*this);
|
||||||
|
m.round();
|
||||||
|
return m.isIdentity();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Set as identity matrix
|
* \brief Set as identity matrix
|
||||||
* \return
|
* \return
|
||||||
@@ -228,6 +240,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isZero() const;
|
bool isZero() const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Is identity matrix? Epsilon considered.
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
bool isZeroEpsilon() const
|
||||||
|
{
|
||||||
|
ImplMatrix m(0.0);
|
||||||
|
m += (*this);
|
||||||
|
m.round();
|
||||||
|
return m.isZero();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief All values equal, if so matirx is not invertible
|
* \brief All values equal, if so matirx is not invertible
|
||||||
* \return
|
* \return
|
||||||
@@ -240,6 +264,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void fill(double value) { this->m_matrix.fill(value); }
|
void fill(double value) { this->m_matrix.fill(value); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Round all values
|
||||||
|
*/
|
||||||
|
void round();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Get element
|
* \brief Get element
|
||||||
* \param row
|
* \param row
|
||||||
|
|||||||
@@ -92,13 +92,13 @@ template <class ImplClass> void CVector3DBase<ImplClass>::setElement(size_t row,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Corss product
|
* Cross product
|
||||||
*/
|
*/
|
||||||
template <class ImplClass> ImplClass CVector3DBase<ImplClass>::crossProduct(const ImplClass &otherVector) const
|
template <class ImplClass> ImplClass CVector3DBase<ImplClass>::crossProduct(const ImplClass &otherVector) const
|
||||||
{
|
{
|
||||||
ImplClass v(otherVector);
|
ImplClass v(otherVector);
|
||||||
v.m_i = this->m_j * otherVector.m_k - this->m_k * otherVector.m_j;
|
v.m_i = this->m_j * otherVector.m_k - this->m_k * otherVector.m_j;
|
||||||
v.m_j = this->m_k * otherVector.m_i - this->m_j * otherVector.m_k;
|
v.m_j = this->m_k * otherVector.m_i - this->m_i * otherVector.m_k;
|
||||||
v.m_k = this->m_i * otherVector.m_j - this->m_j * otherVector.m_i;
|
v.m_k = this->m_i * otherVector.m_j - this->m_j * otherVector.m_i;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#define BLACKMISC_MATHVECTOR3DBASE_H
|
#define BLACKMISC_MATHVECTOR3DBASE_H
|
||||||
|
|
||||||
#include "blackmisc/basestreamstringifier.h"
|
#include "blackmisc/basestreamstringifier.h"
|
||||||
|
#include "blackmisc/mathematics.h"
|
||||||
|
|
||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
{
|
{
|
||||||
@@ -75,6 +76,26 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setZero();
|
void setZero();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set zeros
|
||||||
|
*/
|
||||||
|
bool isZero() const
|
||||||
|
{
|
||||||
|
return this->m_i == 0 && this->m_j == 0 && this->m_k == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Is identity matrix? Epsilon considered.
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
bool isZeroEpsilon() const
|
||||||
|
{
|
||||||
|
ImplClass v;
|
||||||
|
v += (*this);
|
||||||
|
v.round();
|
||||||
|
return v.isZero();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Set zeros
|
* \brief Set zeros
|
||||||
*/
|
*/
|
||||||
@@ -370,6 +391,18 @@ public:
|
|||||||
{
|
{
|
||||||
return sqrt(this->lengthSquared());
|
return sqrt(this->lengthSquared());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Round this vector
|
||||||
|
*/
|
||||||
|
void round()
|
||||||
|
{
|
||||||
|
const double epsilon = 1E-10;
|
||||||
|
this->m_i = BlackMisc::Math::CMath::roundEpsilon(this->m_i, epsilon);
|
||||||
|
this->m_j = BlackMisc::Math::CMath::roundEpsilon(this->m_j, epsilon);
|
||||||
|
this->m_k = BlackMisc::Math::CMath::roundEpsilon(this->m_k, epsilon);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#ifndef BLACKMISC_PQANGLE_H
|
#ifndef BLACKMISC_PQANGLE_H
|
||||||
#define BLACKMISC_PQANGLE_H
|
#define BLACKMISC_PQANGLE_H
|
||||||
#include "blackmisc/pqphysicalquantity.h"
|
#include "blackmisc/pqphysicalquantity.h"
|
||||||
|
#include "blackmisc/mathematics.h"
|
||||||
|
|
||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
{
|
{
|
||||||
@@ -46,15 +47,17 @@ public:
|
|||||||
* \brief Convenience method PI
|
* \brief Convenience method PI
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
const static double pi() {
|
const static double pi()
|
||||||
|
{
|
||||||
return M_PI;
|
return M_PI;
|
||||||
}
|
}
|
||||||
/*!
|
/*!
|
||||||
* \brief Value as factor of PI (e.g. 0.5PI)
|
* \brief Value as factor of PI (e.g. 0.5PI)
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
double piFactor() const {
|
double piFactor() const
|
||||||
return CMeasurementUnit::round(this->convertedSiValueToDouble() / M_PI, 6);
|
{
|
||||||
|
return BlackMisc::Math::CMath::round(this->convertedSiValueToDouble() / M_PI, 6);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
/* Copyright (C) 2013 VATSIM Community
|
/* 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/pqbase.h"
|
#include "blackmisc/pqbase.h"
|
||||||
|
#include "blackmisc/mathematics.h"
|
||||||
|
|
||||||
|
using namespace BlackMisc::Math;
|
||||||
|
|
||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
{
|
{
|
||||||
@@ -35,7 +38,7 @@ CMeasurementPrefix::CMeasurementPrefix(const CMeasurementPrefix &otherMultiplier
|
|||||||
/*
|
/*
|
||||||
* Assignment operator
|
* Assignment operator
|
||||||
*/
|
*/
|
||||||
CMeasurementPrefix& CMeasurementPrefix::operator=(const CMeasurementPrefix &otherMultiplier)
|
CMeasurementPrefix &CMeasurementPrefix::operator=(const CMeasurementPrefix &otherMultiplier)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (this == &otherMultiplier) return *this; // Same object? Yes, so skip assignment, and just return *this
|
if (this == &otherMultiplier) return *this; // Same object? Yes, so skip assignment, and just return *this
|
||||||
@@ -170,7 +173,7 @@ QString CMeasurementUnit::valueRoundedWithUnit(double value, int digits) const
|
|||||||
double CMeasurementUnit::valueRounded(double value, int digits) const
|
double CMeasurementUnit::valueRounded(double value, int digits) const
|
||||||
{
|
{
|
||||||
if (digits < 0) digits = this->m_displayDigits;
|
if (digits < 0) digits = this->m_displayDigits;
|
||||||
return CMeasurementUnit::round(value, digits);
|
return CMath::round(value, digits);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -179,30 +182,19 @@ double CMeasurementUnit::valueRounded(double value, int digits) const
|
|||||||
QString CMeasurementUnit::toQStringRounded(double value, int digits) const
|
QString CMeasurementUnit::toQStringRounded(double value, int digits) const
|
||||||
{
|
{
|
||||||
if (digits < 0) digits = this->m_displayDigits;
|
if (digits < 0) digits = this->m_displayDigits;
|
||||||
double v = CMeasurementUnit::round(value, digits);
|
double v = CMath::round(value, digits);
|
||||||
QString s = QLocale::system().toString(v, 'f', digits);
|
QString s = QLocale::system().toString(v, 'f', digits);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Round utility method
|
|
||||||
*/
|
|
||||||
double CMeasurementUnit::round(double value, int digits)
|
|
||||||
{
|
|
||||||
// gosh, is there no Qt method for this???
|
|
||||||
// It's year 2013
|
|
||||||
double m = pow(10.0, digits);
|
|
||||||
double rv = double(qRound(value * m) / m);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Epsilon rounding
|
* Epsilon rounding
|
||||||
*/
|
*/
|
||||||
double CMeasurementUnit::epsilonRounding(double value) const
|
double CMeasurementUnit::epsilonUpRounding(double value) const
|
||||||
{
|
{
|
||||||
// does notwork reliable with qRound for some reason
|
// Rounds a little up in order to avoid fractions
|
||||||
double v = floor((value + this->m_epsilon) / this->m_epsilon);
|
double eps = value > 0 ? this->m_epsilon : -1.0 * this->m_epsilon;
|
||||||
|
double v = floor((value + eps) / this->m_epsilon);
|
||||||
v *= this->m_epsilon;
|
v *= this->m_epsilon;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,10 +93,6 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief Cast as double
|
* \brief Cast as double
|
||||||
*/
|
*/
|
||||||
operator double() const
|
|
||||||
{
|
|
||||||
return this->m_factor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Factor, e.g.1000 for "kilo"
|
* \brief Factor, e.g.1000 for "kilo"
|
||||||
@@ -106,6 +102,16 @@ public:
|
|||||||
{
|
{
|
||||||
return this->m_factor;
|
return this->m_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Factor
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
double toDouble() const
|
||||||
|
{
|
||||||
|
return this->getFactor();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Name, e.g. "kilo"
|
* \brief Name, e.g. "kilo"
|
||||||
* \return
|
* \return
|
||||||
@@ -114,6 +120,7 @@ public:
|
|||||||
{
|
{
|
||||||
return this->m_name;
|
return this->m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Prefix, e.g. "k" for "kilo"
|
* \brief Prefix, e.g. "k" for "kilo"
|
||||||
* \return
|
* \return
|
||||||
@@ -464,25 +471,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
double conversionToUnit(double value, const CMeasurementUnit &to) const;
|
double conversionToUnit(double value, const CMeasurementUnit &to) const;
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
// -- static
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Utility round method
|
|
||||||
* \param value
|
|
||||||
* \param digits
|
|
||||||
* \return
|
|
||||||
*/
|
|
||||||
static double round(double value, int digits);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Epsilon rounding. In some conversion rouding is required to avoid
|
* Epsilon rounding. In some conversion rouding is required to avoid
|
||||||
* periodical numbers.
|
* periodical numbers.
|
||||||
* \param value
|
* \param value
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
double epsilonRounding(double value) const;
|
double epsilonUpRounding(double value) const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
// -- static
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Unit is not specified
|
* \brief Unit is not specified
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#ifndef BLACKMISC_PQPHYSICALQUANTITY_H
|
#ifndef BLACKMISC_PQPHYSICALQUANTITY_H
|
||||||
#define BLACKMISC_PQPHYSICALQUANTITY_H
|
#define BLACKMISC_PQPHYSICALQUANTITY_H
|
||||||
|
|
||||||
|
#include "blackmisc/mathematics.h"
|
||||||
#include "blackmisc/pqbase.h"
|
#include "blackmisc/pqbase.h"
|
||||||
#include "blackmisc/pqunits.h"
|
#include "blackmisc/pqunits.h"
|
||||||
#include "blackmisc/debug.h"
|
#include "blackmisc/debug.h"
|
||||||
@@ -217,7 +218,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
qint32 convertedSiValueToInteger() const
|
qint32 convertedSiValueToInteger() const
|
||||||
{
|
{
|
||||||
return static_cast<qint32>(CMeasurementUnit::round(this->m_convertedSiUnitValueD, 0));
|
return static_cast<qint32>(
|
||||||
|
BlackMisc::Math::CMath::round(this->m_convertedSiUnitValueD, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -255,15 +257,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void substractUnitValue(double value);
|
void substractUnitValue(double value);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Cast as QString
|
|
||||||
*/
|
|
||||||
operator QString() const
|
|
||||||
{
|
|
||||||
return this->unitValueRoundedWithUnit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Multiply operator *=
|
* \brief Multiply operator *=
|
||||||
* \param multiply
|
* \param multiply
|
||||||
* \return
|
* \return
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ double CAngleUnit::conversionSexagesimalFromSi(const CMeasurementUnit &angleUnit
|
|||||||
{
|
{
|
||||||
// using rounding here, since fractions can lead to ugly sexagesimal conversion
|
// using rounding here, since fractions can lead to ugly sexagesimal conversion
|
||||||
// e.g. 185.499999 gives 185 29' 59.9999"
|
// e.g. 185.499999 gives 185 29' 59.9999"
|
||||||
value = angleUnit.epsilonRounding(value * 180 / M_PI); // degree
|
value = angleUnit.epsilonUpRounding(value * 180 / M_PI); // degree
|
||||||
double v = floor(value);
|
double v = floor(value);
|
||||||
double c = value - v;
|
double c = value - v;
|
||||||
double mr = c * 60.0;
|
double mr = c * 60.0;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* 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/. */
|
||||||
@@ -649,4 +649,4 @@ public:
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace
|
} // namespace
|
||||||
#endif // BLACKMISC_PQUNITS_H
|
#endif // guard
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ void CTestPhysicalQuantitiesBase::frequencyTests()
|
|||||||
QVERIFY2(f1.valueRounded(CFrequencyUnit::kHz(), 2) == 1000, "Mega is 1000kHz");
|
QVERIFY2(f1.valueRounded(CFrequencyUnit::kHz(), 2) == 1000, "Mega is 1000kHz");
|
||||||
QVERIFY2(f1.unitValueToDouble() == 1 , "1MHz");
|
QVERIFY2(f1.unitValueToDouble() == 1 , "1MHz");
|
||||||
QVERIFY2(f1.convertedSiValueToDouble() == 1000000 , "1E6 Hz");
|
QVERIFY2(f1.convertedSiValueToDouble() == 1000000 , "1E6 Hz");
|
||||||
CFrequency f2(CMeasurementPrefix::M(), CFrequencyUnit::Hz()) ; // 1 Megahertz
|
CFrequency f2(CMeasurementPrefix::M().toDouble(), CFrequencyUnit::Hz()) ; // 1 Megahertz
|
||||||
QVERIFY2(f1 == f2 , "MHz is 1E6 Hz");
|
QVERIFY2(f1 == f2 , "MHz is 1E6 Hz");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,15 @@ void CTestVectorMatrixBase::vectorBasics()
|
|||||||
CVector3D v1(1);
|
CVector3D v1(1);
|
||||||
v1 *= 2.0;
|
v1 *= 2.0;
|
||||||
CVector3D v2(2);
|
CVector3D v2(2);
|
||||||
QVERIFY2(v1 == v2, "Matrix should be zero");
|
QVERIFY2(v1 == v2, "Vectors should be equal");
|
||||||
|
CVector3D v3(1, 1, 1);
|
||||||
|
CVector3D v4(2, 2, 2);
|
||||||
|
CVector3D v5 = v3.crossProduct(v4);
|
||||||
|
QVERIFY2(v5.isZeroEpsilon(), "Cross product shall be {0, 0, 0}");
|
||||||
|
CVector3D v6(1, 2, 3);
|
||||||
|
CVector3D v7(3, 4, 5);
|
||||||
|
QVERIFY2(v6.crossProduct(v7) == CVector3D(-2, 4, -2), "Cross product is wrong");
|
||||||
|
QVERIFY2(v6.dotProduct(v7) == 26, "Dot product is wrong, 26 expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -58,7 +66,8 @@ void CTestVectorMatrixBase::matrixBasics()
|
|||||||
QVERIFY2(m1(0, 0) == 1 && m1(1, 0) == 2 && m1(0, 2) == 3, "Index error");
|
QVERIFY2(m1(0, 0) == 1 && m1(1, 0) == 2 && m1(0, 2) == 3, "Index error");
|
||||||
CMatrix3x3 mi = m1.inverse(invertible);
|
CMatrix3x3 mi = m1.inverse(invertible);
|
||||||
CMatrix3x3 mid = m1 * mi;
|
CMatrix3x3 mid = m1 * mi;
|
||||||
QVERIFY2(mid.isIdentity(), qPrintable(QString("Multiply with inverse should be identity: %1").arg(mid)));
|
mid.round();
|
||||||
|
QVERIFY2(mid.isIdentity(), qPrintable(QString("Multiply with inverse should be identity: %1").arg(mid.toQString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
Reference in New Issue
Block a user