mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 23:05:36 +08:00
First major wave of PQ refactoring, including but not limited to:
* Default unit is more clearly stated in one place, not restated in many different places, and is not always the SI unit * Converter strategy pattern in CMeasurementUnit, covering linear, affine, and different kinds of sexagesimal units * General reorganization of CMeasurementUnit construction and CPhysicalQuantity methods, not removing any behvaiour * Move duplicated method unitFromSymbol from derived classes into base class CMeasurementUnit * For DBus, CPhysicalQuantity marshals both in its own unit and in the default unit
This commit is contained in:
@@ -57,7 +57,7 @@ int CSamplesPhysicalQuantities::samples()
|
||||
CSpeed s2 = CSpeed(1000, CSpeedUnit::ft_min());
|
||||
CSpeed s3 = CSpeed(s2);
|
||||
s3.switchUnit(CSpeedUnit::m_s());
|
||||
qDebug() << s1 << s1.convertedSiValueRoundedWithUnit() << s1.valueRoundedWithUnit(CSpeedUnit::NM_h());
|
||||
qDebug() << s1 << s1.valueRoundedWithUnit(CSpeedUnit::defaultUnit()) << s1.valueRoundedWithUnit(CSpeedUnit::NM_h());
|
||||
qDebug() << s2 << s3;
|
||||
|
||||
CAngle a1(180, CAngleUnit::deg());
|
||||
@@ -72,7 +72,7 @@ int CSamplesPhysicalQuantities::samples()
|
||||
a2 = a1 + a1;
|
||||
|
||||
a2.switchUnit(CAngleUnit::deg());
|
||||
qDebug() << a1.unitValueRoundedWithUnit() << a1.piFactor();
|
||||
qDebug() << a1.valueRoundedWithUnit() << a1.piFactor();
|
||||
qDebug() << a2;
|
||||
a3.switchUnit(CAngleUnit::sexagesimalDeg());
|
||||
a4.switchUnit(CAngleUnit::deg());
|
||||
@@ -89,8 +89,8 @@ int CSamplesPhysicalQuantities::samples()
|
||||
CTemperature t1;
|
||||
CTemperature t2(20, CTemperatureUnit::C());
|
||||
CTemperature t3(1, CTemperatureUnit::F());
|
||||
qDebug() << t1 << t2 << t2.convertedSiValueRoundedWithUnit(true);
|
||||
qDebug() << t3.valueRoundedWithUnit(CTemperatureUnit::F(), -1 ,true) << t3.valueRoundedWithUnit(CTemperatureUnit::C(), -1, true) << "I18N/UTF";
|
||||
qDebug() << t1 << t2 << t2.valueRoundedWithUnit(CTemperatureUnit::defaultUnit(), -1, true);
|
||||
qDebug() << t3.valueRoundedWithUnit(CTemperatureUnit::F(), -1, true) << t3.valueRoundedWithUnit(CTemperatureUnit::C(), -1, true) << "I18N/UTF";
|
||||
|
||||
// some logging with CLogMessage
|
||||
// bDebug << p1;
|
||||
@@ -108,10 +108,13 @@ int CSamplesPhysicalQuantities::samples()
|
||||
CTime ti1(1, CTimeUnit::h());
|
||||
CTime ti2(ti1);
|
||||
ti2.switchUnit(CTimeUnit::ms());
|
||||
qDebug() << ti1 << ti2;
|
||||
CTime ti3(1.0101, CTimeUnit::hms());
|
||||
CTime ti4(1.15, CTimeUnit::hrmin());
|
||||
CTime ti5(1.30, CTimeUnit::minsec());
|
||||
qDebug() << ti1 << ti2 << ti3 << ti4 << ti5;
|
||||
|
||||
CAcceleration ac1(10, CAccelerationUnit::m_s2());
|
||||
qDebug() << ac1 << ac1.unitValueRoundedWithUnit(-1, true) << "I18N/UTF";
|
||||
qDebug() << ac1 << ac1.valueRoundedWithUnit(-1, true) << "I18N/UTF";
|
||||
|
||||
// bye
|
||||
qDebug() << "-----------------------------------------------";
|
||||
|
||||
@@ -114,7 +114,7 @@ int main(int argc, char *argv[])
|
||||
qDebug() << "Send speed via interface" << speed;
|
||||
TestserviceTool::sleep(2500);
|
||||
speed.switchUnit(CSpeedUnit::km_h());
|
||||
speed.addUnitValue(1.0);
|
||||
speed.addValueSameUnit(1.0);
|
||||
|
||||
// Aviation
|
||||
CComSystem comSystem = CComSystem("DBUS COM1", CPhysicalQuantitiesConstants::FrequencyInternationalAirDistress(), CPhysicalQuantitiesConstants::FrequencyUnicom());
|
||||
@@ -125,7 +125,7 @@ int main(int argc, char *argv[])
|
||||
testserviceInterface.receiveVariant(qv);
|
||||
testserviceInterface.receiveAltitude(al);
|
||||
qDebug() << "Send altitude via interface" << al;
|
||||
al.addUnitValue(1);
|
||||
al.addValueSameUnit(1);
|
||||
|
||||
CTransponder transponder("transponder", 7000, CTransponder::ModeC);
|
||||
testserviceInterface.receiveTransponder(transponder);
|
||||
|
||||
@@ -85,8 +85,8 @@ protected:
|
||||
virtual QString convertToQString(bool i18n = false) const
|
||||
{
|
||||
QString s(this->getName());
|
||||
s.append(" Active: ").append(this->m_frequencyActive.unitValueRoundedWithUnit(3, i18n));
|
||||
s.append(" Standby: ").append(this->m_frequencyStandby.unitValueRoundedWithUnit(3, i18n));
|
||||
s.append(" Active: ").append(this->m_frequencyActive.valueRoundedWithUnit(3, i18n));
|
||||
s.append(" Standby: ").append(this->m_frequencyStandby.valueRoundedWithUnit(3, i18n));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Geo
|
||||
QString CCoordinateGeodetic::convertToQString(bool i18n) const
|
||||
{
|
||||
QString s = "Geodetic: {%1, %2, %3}";
|
||||
return s.arg(this->m_latitude.unitValueRoundedWithUnit(6, i18n)).arg(this->m_longitude.unitValueRoundedWithUnit(6, i18n)).arg(this->m_height.unitValueRoundedWithUnit(i18n));
|
||||
return s.arg(this->m_latitude.valueRoundedWithUnit(6, i18n)).arg(this->m_longitude.valueRoundedWithUnit(6, i18n)).arg(this->m_height.valueRoundedWithUnit(i18n));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -80,7 +80,7 @@ CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateGeodetic &geo
|
||||
|
||||
double clambda = cos(lambdaRad);
|
||||
|
||||
double h = geo.height().convertedSiValueToDouble();
|
||||
double h = geo.height().value(CLengthUnit::m());
|
||||
double x = (n + h) * cphi;
|
||||
double y = x * slambda;
|
||||
x *= clambda;
|
||||
|
||||
@@ -75,7 +75,7 @@ protected:
|
||||
*/
|
||||
virtual QString convertToQString() const
|
||||
{
|
||||
return this->unitValueRoundedWithUnit(6);
|
||||
return this->valueRoundedWithUnit(6);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef BLACKMISC_MATHEMATICS_H
|
||||
#define BLACKMISC_MATHEMATICS_H
|
||||
#include <QtCore/qmath.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
@@ -70,6 +71,26 @@ public:
|
||||
*/
|
||||
static double roundEpsilon(double value, double epsilon);
|
||||
|
||||
/*!
|
||||
* \brief Nearest integer not greater in magnitude than value, correcting for epsilon
|
||||
* \param value
|
||||
* \param epsilon
|
||||
*/
|
||||
static inline double trunc(double value, double epsilon = 1e-10)
|
||||
{
|
||||
return value < 0 ? ceil(value - epsilon) : floor(value + epsilon);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Fractional part of value
|
||||
* \param value
|
||||
*/
|
||||
static inline double fract(double value)
|
||||
{
|
||||
double unused;
|
||||
return modf(value, &unused);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief PI
|
||||
* \return
|
||||
|
||||
@@ -21,14 +21,14 @@ public:
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
*/
|
||||
CAcceleration() : CPhysicalQuantity(0, CAccelerationUnit::m_s2(), CAccelerationUnit::m_s2()) {}
|
||||
CAcceleration() : CPhysicalQuantity(0, CAccelerationUnit::defaultUnit()) {}
|
||||
|
||||
/*!
|
||||
* \brief Init by double value
|
||||
* \param value
|
||||
* \param unit
|
||||
*/
|
||||
CAcceleration(double value, const CAccelerationUnit &unit) : CPhysicalQuantity(value, unit, CAccelerationUnit::m_s2()) {}
|
||||
CAcceleration(double value, const CAccelerationUnit &unit) : CPhysicalQuantity(value, unit) {}
|
||||
|
||||
/*!
|
||||
* \brief Copy constructor by base type
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
*/
|
||||
CAngle() : CPhysicalQuantity(0, CAngleUnit::rad(), CAngleUnit::rad()) {}
|
||||
CAngle() : CPhysicalQuantity(0, CAngleUnit::defaultUnit()) {}
|
||||
|
||||
/*!
|
||||
* \brief Copy constructor from base type
|
||||
@@ -34,18 +34,30 @@ public:
|
||||
* \param value
|
||||
* \param unit
|
||||
*/
|
||||
CAngle(double value, const CAngleUnit &unit): CPhysicalQuantity(value, unit, CAngleUnit::rad()) {}
|
||||
CAngle(double value, const CAngleUnit &unit): CPhysicalQuantity(value, unit) {}
|
||||
|
||||
/*!
|
||||
* \brief Intir as sexagesimal degrees
|
||||
* \brief Init as sexagesimal degrees, minutes, seconds
|
||||
* The sign of all parameters must be the same, either all positive or all negative.
|
||||
* \param degrees
|
||||
* \param minutes
|
||||
* \param seconds
|
||||
*/
|
||||
CAngle(qint32 degrees, qint32 minutes, double seconds) :
|
||||
CAngle(int degrees, int minutes, double seconds) :
|
||||
CPhysicalQuantity(
|
||||
degrees + minutes / 100.0 + seconds / 10000.0,
|
||||
CAngleUnit::sexagesimalDeg(), CAngleUnit::rad()) {}
|
||||
CAngleUnit::sexagesimalDeg()) {}
|
||||
|
||||
/*!
|
||||
* \brief Init as sexagesimal degrees, minutes
|
||||
* The sign of both parameters must be the same, either both positive or both negative.
|
||||
* \param degrees
|
||||
* \param minutes
|
||||
*/
|
||||
CAngle(int degrees, double minutes) :
|
||||
CPhysicalQuantity(
|
||||
degrees + minutes / 100.0,
|
||||
CAngleUnit::sexagesimalDegMin()) {}
|
||||
|
||||
/*!
|
||||
* \brief Virtual destructor
|
||||
@@ -58,7 +70,7 @@ public:
|
||||
*/
|
||||
double piFactor() const
|
||||
{
|
||||
return BlackMisc::Math::CMath::round(this->convertedSiValueToDouble() / BlackMisc::Math::CMath::PI() , 6);
|
||||
return BlackMisc::Math::CMath::round(this->value(CAngleUnit::rad()) / BlackMisc::Math::CMath::PI() , 6);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -14,14 +14,14 @@ namespace PhysicalQuantities
|
||||
{
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// --- Mulitplier --------------------------------------------------------
|
||||
// --- Prefix ------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
CMeasurementPrefix::CMeasurementPrefix(const QString &name, const QString &unitName, double factor) :
|
||||
m_name(name), m_prefix(unitName), m_factor(factor)
|
||||
CMeasurementPrefix::CMeasurementPrefix(const QString &name, const QString &symbol, double factor) :
|
||||
m_name(name), m_symbol(symbol), m_factor(factor)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ CMeasurementPrefix::CMeasurementPrefix(const QString &name, const QString &unitN
|
||||
* Constructor
|
||||
*/
|
||||
CMeasurementPrefix::CMeasurementPrefix(const CMeasurementPrefix &other) :
|
||||
m_name(other.m_name), m_prefix(other.m_prefix), m_factor(other.m_factor)
|
||||
m_name(other.m_name), m_symbol(other.m_symbol), m_factor(other.m_factor)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ CMeasurementPrefix &CMeasurementPrefix::operator=(const CMeasurementPrefix &othe
|
||||
{
|
||||
if (this == &other) return *this;
|
||||
this->m_name = other.m_name;
|
||||
this->m_prefix = other.m_prefix;
|
||||
this->m_symbol= other.m_symbol;
|
||||
this->m_factor = other.m_factor;
|
||||
return *this;
|
||||
}
|
||||
@@ -62,22 +62,6 @@ bool CMeasurementPrefix::operator !=(const CMeasurementPrefix &other) const
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/*
|
||||
* Greater?
|
||||
*/
|
||||
bool CMeasurementPrefix::operator >(const CMeasurementPrefix &other) const
|
||||
{
|
||||
return this->m_factor > other.m_factor;
|
||||
}
|
||||
|
||||
/*
|
||||
* Less?
|
||||
*/
|
||||
bool CMeasurementPrefix::operator <(const CMeasurementPrefix &other) const
|
||||
{
|
||||
return this->m_factor < other.m_factor;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// --- Measurement unit --------------------------------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
@@ -85,22 +69,40 @@ bool CMeasurementPrefix::operator <(const CMeasurementPrefix &other) const
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSIUnit, bool isSIBaseUnit,
|
||||
double conversionFactorToSI, const CMeasurementPrefix &multiplier, qint32 displayDigits, double epsilon,
|
||||
UnitConverter toSiConverter, UnitConverter fromSiConverter):
|
||||
m_name(name), m_unitName(unitName), m_type(type), m_isSiUnit(isSIUnit), m_isSiBaseUnit(isSIBaseUnit),
|
||||
m_conversionFactorToSIConversionUnit(conversionFactorToSI),
|
||||
m_epsilon(epsilon), m_displayDigits(displayDigits), m_multiplier(multiplier), m_fromSiConverter(fromSiConverter), m_toSiConverter(toSiConverter)
|
||||
CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &symbol, double factor, qint32 displayDigits, double epsilon) :
|
||||
m_name(name), m_symbol(symbol), m_epsilon(epsilon), m_displayDigits(displayDigits), m_prefix(CMeasurementPrefix::One()), m_converter(new LinearConverter(factor))
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &symbol, double factor, double offset, qint32 displayDigits, double epsilon) :
|
||||
m_name(name), m_symbol(symbol), m_epsilon(epsilon), m_displayDigits(displayDigits), m_prefix(CMeasurementPrefix::One()), m_converter(new AffineConverter(factor, offset))
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
CMeasurementUnit::CMeasurementUnit(const QString &name, const QString &symbol, Converter *converter, qint32 displayDigits, double epsilon) :
|
||||
m_name(name), m_symbol(symbol), m_epsilon(epsilon), m_displayDigits(displayDigits), m_prefix(CMeasurementPrefix::One()), m_converter(converter)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructor
|
||||
*/
|
||||
CMeasurementUnit::CMeasurementUnit(const CMeasurementUnit &base, const CMeasurementPrefix &prefix, qint32 displayDigits, double epsilon) :
|
||||
m_name(base.m_name), m_symbol(base.m_symbol), m_epsilon(epsilon), m_displayDigits(displayDigits), m_prefix(prefix), m_converter(base.m_converter->clone(prefix))
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy constructor
|
||||
*/
|
||||
CMeasurementUnit::CMeasurementUnit(const CMeasurementUnit &other):
|
||||
m_name(other.m_name), m_unitName(other.m_unitName), m_type(other.m_type), m_isSiUnit(other.m_isSiUnit),
|
||||
m_isSiBaseUnit(other.m_isSiBaseUnit), m_conversionFactorToSIConversionUnit(other.m_conversionFactorToSIConversionUnit),
|
||||
m_epsilon(other.m_epsilon), m_displayDigits(other.m_displayDigits), m_multiplier(other.m_multiplier), m_fromSiConverter(other.m_fromSiConverter), m_toSiConverter(other.m_toSiConverter)
|
||||
CMeasurementUnit::CMeasurementUnit(const CMeasurementUnit &other) :
|
||||
m_name(other.m_name), m_symbol(other.m_symbol), m_epsilon(other.m_epsilon), m_displayDigits(other.m_displayDigits), m_prefix(other.m_prefix), m_converter(other.m_converter)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -111,16 +113,11 @@ CMeasurementUnit &CMeasurementUnit::operator =(const CMeasurementUnit &other)
|
||||
{
|
||||
if (this == &other) return *this; // Same object? Yes, so skip assignment, and just return *this
|
||||
this->m_name = other.m_name;
|
||||
this->m_unitName = other.m_unitName;
|
||||
this->m_type = other.m_type;
|
||||
this->m_isSiUnit = other.m_isSiUnit;
|
||||
this->m_isSiBaseUnit = other.m_isSiBaseUnit;
|
||||
this->m_conversionFactorToSIConversionUnit = other.m_conversionFactorToSIConversionUnit;
|
||||
this->m_multiplier = other.m_multiplier;
|
||||
this->m_symbol = other.m_symbol;
|
||||
this->m_prefix = other.m_prefix;
|
||||
this->m_displayDigits = other.m_displayDigits;
|
||||
this->m_epsilon = other.m_epsilon;
|
||||
this->m_fromSiConverter = other.m_fromSiConverter;
|
||||
this->m_toSiConverter = other.m_toSiConverter;
|
||||
this->m_converter = other.m_converter;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -130,9 +127,7 @@ CMeasurementUnit &CMeasurementUnit::operator =(const CMeasurementUnit &other)
|
||||
bool CMeasurementUnit::operator ==(const CMeasurementUnit &other) const
|
||||
{
|
||||
if (this == &other) return true;
|
||||
if (this->m_type != other.m_type) return false;
|
||||
return this->m_multiplier == other.m_multiplier && this->m_name == other.m_name
|
||||
&& this->m_isSiUnit == other.m_isSiUnit;
|
||||
return this->m_prefix == other.m_prefix && this->m_name == other.m_name;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -144,28 +139,29 @@ bool CMeasurementUnit::operator !=(const CMeasurementUnit &other) const
|
||||
}
|
||||
|
||||
/*
|
||||
* Conversion factor from unit x to y
|
||||
* Conversion
|
||||
*/
|
||||
double CMeasurementUnit::conversionToUnit(double value, const CMeasurementUnit &to) const
|
||||
double CMeasurementUnit::convertFrom(double value, const CMeasurementUnit &unit) const
|
||||
{
|
||||
if (to == *this) return value;
|
||||
double siValue = this->convertToSiConversionUnit(value);
|
||||
return to.convertFromSiConversionUnit(siValue);
|
||||
Q_ASSERT(this->m_converter);
|
||||
Q_ASSERT(unit.m_converter);
|
||||
if (this->m_converter == unit.m_converter) return value;
|
||||
return this->m_converter->fromDefault(unit.m_converter->toDefault(value));
|
||||
}
|
||||
|
||||
/*
|
||||
* Value to QString with unit, e.g. "5.00m"
|
||||
* @return
|
||||
*/
|
||||
QString CMeasurementUnit::valueRoundedWithUnit(double value, int digits, bool i18n) const
|
||||
QString CMeasurementUnit::makeRoundedQStringWithUnit(double value, int digits, bool i18n) const
|
||||
{
|
||||
return this->toQStringRounded(value, digits).append(this->getUnitName(i18n));
|
||||
return this->makeRoundedQString(value, digits).append(this->getSymbol(i18n));
|
||||
}
|
||||
|
||||
/*
|
||||
* Value rounded
|
||||
*/
|
||||
double CMeasurementUnit::valueRounded(double value, int digits) const
|
||||
double CMeasurementUnit::roundValue(double value, int digits) const
|
||||
{
|
||||
if (digits < 0) digits = this->m_displayDigits;
|
||||
return CMath::round(value, digits);
|
||||
@@ -174,7 +170,7 @@ double CMeasurementUnit::valueRounded(double value, int digits) const
|
||||
/*
|
||||
* Rounded to QString
|
||||
*/
|
||||
QString CMeasurementUnit::toQStringRounded(double value, int digits, bool /* i18n */) const
|
||||
QString CMeasurementUnit::makeRoundedQString(double value, int digits, bool /* i18n */) const
|
||||
{
|
||||
if (digits < 0) digits = this->m_displayDigits;
|
||||
double v = CMath::round(value, digits);
|
||||
@@ -182,17 +178,5 @@ QString CMeasurementUnit::toQStringRounded(double value, int digits, bool /* i18
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Epsilon rounding
|
||||
*/
|
||||
double CMeasurementUnit::epsilonUpRounding(double value) const
|
||||
{
|
||||
// Rounds a little up in order to avoid fractions
|
||||
double eps = value > 0 ? this->m_epsilon : -1.0 * this->m_epsilon;
|
||||
double v = floor((value + eps) / this->m_epsilon);
|
||||
v *= this->m_epsilon;
|
||||
return v;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
|
||||
#include "blackmisc/basestreamstringifier.h"
|
||||
#include "blackmisc/debug.h"
|
||||
#include "blackmisc/mathematics.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QDBusArgument>
|
||||
#include <QString>
|
||||
#include <QtGlobal>
|
||||
#include <QDebug>
|
||||
|
||||
#include <QSharedData>
|
||||
#include <QSharedDataPointer>
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
@@ -23,13 +25,13 @@ namespace PhysicalQuantities
|
||||
/*!
|
||||
* \brief Typical prefixes (multipliers) such as kilo, mega, hecto.
|
||||
* See <a href="http://www.poynton.com/notes/units/index.html">here</a> for an overview.
|
||||
* Use the static values such CMeasurementMultiplier::k() as to specify values.
|
||||
* Use the static values such as CMeasurementPrefix::k() to specify values.
|
||||
*/
|
||||
class CMeasurementPrefix : public CBaseStreamStringifier
|
||||
{
|
||||
private:
|
||||
QString m_name; //!< name, e.g. "kilo"
|
||||
QString m_prefix; //!< prefix, e.g. "k" for kilo
|
||||
QString m_symbol; //!< prefix, e.g. "k" for kilo
|
||||
double m_factor; //!< factor, e.g. 1000 for kilo 1/100 for centi
|
||||
|
||||
/*!
|
||||
@@ -39,11 +41,11 @@ private:
|
||||
* \param prefixName
|
||||
* \param factor
|
||||
*/
|
||||
CMeasurementPrefix(const QString &name, const QString &prefixName, double factor);
|
||||
CMeasurementPrefix(const QString &name, const QString &symbol, double factor);
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* \brief Name as stringification
|
||||
* \brief Name as string
|
||||
* \param i18n
|
||||
* \return
|
||||
*/
|
||||
@@ -100,20 +102,6 @@ public:
|
||||
*/
|
||||
bool operator != (const CMeasurementPrefix &other) const;
|
||||
|
||||
/*!
|
||||
* \brief Greater operator >
|
||||
* \param other
|
||||
* \return
|
||||
*/
|
||||
bool operator > (const CMeasurementPrefix &other) const;
|
||||
|
||||
/*!
|
||||
* \brief Less operator <
|
||||
* \param other
|
||||
* \return
|
||||
*/
|
||||
bool operator < (const CMeasurementPrefix &other) const;
|
||||
|
||||
/*!
|
||||
* \brief Factor, e.g.1000 for "kilo"
|
||||
* \return
|
||||
@@ -136,26 +124,18 @@ public:
|
||||
* \brief Name, e.g. "kilo"
|
||||
* \return
|
||||
*/
|
||||
QString getName() const
|
||||
QString getName(bool i18n = false) const
|
||||
{
|
||||
return this->m_name;
|
||||
return i18n ? QCoreApplication::translate("CMeasurementPrefix", this->m_name.toStdString().c_str()) : this->m_name;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Prefix, e.g. "k" for "kilo"
|
||||
* \return
|
||||
*/
|
||||
QString getPrefix() const
|
||||
QString getSymbol(bool i18n = false) const
|
||||
{
|
||||
return this->m_prefix;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Operator as double
|
||||
*/
|
||||
operator double() const
|
||||
{
|
||||
return this->m_factor;
|
||||
return i18n ? QCoreApplication::translate("CMeasurementPrefix", this->m_symbol.toStdString().c_str()) : this->m_symbol;
|
||||
}
|
||||
|
||||
// --- static units, always use these for initialization
|
||||
@@ -178,7 +158,7 @@ public:
|
||||
*/
|
||||
static const CMeasurementPrefix &One()
|
||||
{
|
||||
static CMeasurementPrefix one("one", "", 1.0);
|
||||
static CMeasurementPrefix one(QT_TR_NOOP("one"), "", 1.0);
|
||||
return one;
|
||||
}
|
||||
|
||||
@@ -188,7 +168,7 @@ public:
|
||||
*/
|
||||
static const CMeasurementPrefix &M()
|
||||
{
|
||||
static CMeasurementPrefix mega("mega", "M", 1E6);
|
||||
static CMeasurementPrefix mega(QT_TR_NOOP("mega"), "M", 1E6);
|
||||
return mega;
|
||||
}
|
||||
|
||||
@@ -198,7 +178,7 @@ public:
|
||||
*/
|
||||
static const CMeasurementPrefix &k()
|
||||
{
|
||||
static CMeasurementPrefix kilo("kilo", "k", 1000.0);
|
||||
static CMeasurementPrefix kilo(QT_TR_NOOP("kilo"), "k", 1000.0);
|
||||
return kilo;
|
||||
}
|
||||
|
||||
@@ -208,7 +188,7 @@ public:
|
||||
*/
|
||||
static const CMeasurementPrefix &G()
|
||||
{
|
||||
static CMeasurementPrefix giga("giga", "G", 1E9);
|
||||
static CMeasurementPrefix giga(QT_TR_NOOP("giga"), "G", 1E9);
|
||||
return giga;
|
||||
}
|
||||
|
||||
@@ -218,7 +198,7 @@ public:
|
||||
*/
|
||||
static const CMeasurementPrefix &h()
|
||||
{
|
||||
static CMeasurementPrefix hecto("hecto", "h", 100.0);
|
||||
static CMeasurementPrefix hecto(QT_TR_NOOP("hecto"), "h", 100.0);
|
||||
return hecto;
|
||||
}
|
||||
|
||||
@@ -228,7 +208,7 @@ public:
|
||||
*/
|
||||
static const CMeasurementPrefix &c()
|
||||
{
|
||||
static CMeasurementPrefix centi("centi", "c", 0.01);
|
||||
static CMeasurementPrefix centi(QT_TR_NOOP("centi"), "c", 0.01);
|
||||
return centi;
|
||||
}
|
||||
|
||||
@@ -238,7 +218,7 @@ public:
|
||||
*/
|
||||
static const CMeasurementPrefix &m()
|
||||
{
|
||||
static CMeasurementPrefix milli("milli", "m", 1E-03);
|
||||
static CMeasurementPrefix milli(QT_TR_NOOP("milli"), "m", 1E-03);
|
||||
return milli;
|
||||
}
|
||||
|
||||
@@ -287,46 +267,171 @@ public:
|
||||
/*!
|
||||
* \brief Base class for all units, such as meter, hertz.
|
||||
*/
|
||||
class CMeasurementUnit: public CBaseStreamStringifier
|
||||
class CMeasurementUnit : public CBaseStreamStringifier
|
||||
{
|
||||
protected:
|
||||
/*!
|
||||
* \brief Points to an individual converter method
|
||||
* Conversion as perobject, as required for CAnglewith sexagesimal conversion
|
||||
* Abstract strategy pattern that encapsulates a unit conversion strategy.
|
||||
*/
|
||||
typedef double(*UnitConverter)(const CMeasurementUnit &, double);
|
||||
class Converter : public QSharedData
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Virtual destructor.
|
||||
*/
|
||||
virtual ~Converter() {}
|
||||
/*!
|
||||
* Convert from this unit to default unit.
|
||||
* \param factor
|
||||
* \return
|
||||
*/
|
||||
virtual double toDefault(double factor) const = 0;
|
||||
/*!
|
||||
* Convert from default unit to this unit.
|
||||
* \param factor
|
||||
* \return
|
||||
*/
|
||||
virtual double fromDefault(double factor) const = 0;
|
||||
/*!
|
||||
* Make a copy of this object with a different prefix.
|
||||
* \param prefix
|
||||
* \return
|
||||
*/
|
||||
virtual Converter *clone(const CMeasurementPrefix &prefix) const = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Concrete strategy pattern for converting unit with linear conversion.
|
||||
*/
|
||||
class LinearConverter : public Converter
|
||||
{
|
||||
double m_factor;
|
||||
public:
|
||||
/*!
|
||||
* Constructor
|
||||
* \param factor
|
||||
*/
|
||||
LinearConverter(double factor) : m_factor(factor) {}
|
||||
virtual double toDefault(double factor) const { return factor * m_factor; }
|
||||
virtual double fromDefault(double factor) const { return factor / m_factor; }
|
||||
virtual Converter *clone(const CMeasurementPrefix &prefix) const { auto ret = new LinearConverter(*this); ret->m_factor *= prefix.getFactor(); return ret; }
|
||||
};
|
||||
|
||||
/*!
|
||||
* Concrete strategy pattern for converting unit with affine conversion.
|
||||
*/
|
||||
class AffineConverter : public Converter
|
||||
{
|
||||
double m_factor;
|
||||
double m_offset;
|
||||
public:
|
||||
/*!
|
||||
* Constructor
|
||||
* \param factor
|
||||
* \param offset
|
||||
*/
|
||||
AffineConverter(double factor, double offset) : m_factor(factor), m_offset(offset) {}
|
||||
virtual double toDefault(double factor) const { return (factor - m_offset) * m_factor; }
|
||||
virtual double fromDefault(double factor) const { return factor / m_factor + m_offset; }
|
||||
virtual Converter *clone(const CMeasurementPrefix &prefix) const { auto ret = new AffineConverter(*this); ret->m_factor *= prefix.getFactor(); return ret; }
|
||||
};
|
||||
|
||||
/*!
|
||||
* Concrete strategy pattern for converting unit with subdivision conversion.
|
||||
*/
|
||||
template <int Num, int Den>
|
||||
class SubdivisionConverter : public Converter
|
||||
{
|
||||
double m_factor;
|
||||
public:
|
||||
/*!
|
||||
* Constructor
|
||||
*/
|
||||
SubdivisionConverter(double factor = 1) : m_factor(factor) {}
|
||||
virtual double toDefault(double factor) const { using BlackMisc::Math::CMath;
|
||||
double ret = CMath::trunc(factor); factor = CMath::fract(factor) * Den;
|
||||
ret += factor / Num;
|
||||
return ret * m_factor; }
|
||||
virtual double fromDefault(double factor) const { using BlackMisc::Math::CMath;
|
||||
factor /= m_factor;
|
||||
double ret = CMath::trunc(factor); factor = CMath::fract(factor) * Num;
|
||||
return ret += factor / Den; }
|
||||
virtual Converter *clone(const CMeasurementPrefix &) const { qFatal("Not implemented"); return 0; }
|
||||
};
|
||||
|
||||
/*!
|
||||
* Concrete strategy pattern for converting unit with subdivision conversion.
|
||||
*/
|
||||
template <int Num1, int Den1, int Num2, int Den2>
|
||||
class SubdivisionConverter2 : public Converter
|
||||
{
|
||||
double m_factor;
|
||||
public:
|
||||
/*!
|
||||
* Constructor
|
||||
*/
|
||||
SubdivisionConverter2(double factor = 1) : m_factor(factor) {}
|
||||
virtual double toDefault(double factor) const { using BlackMisc::Math::CMath;
|
||||
double ret = CMath::trunc(factor); factor = CMath::fract(factor) * Den1;
|
||||
ret += CMath::trunc(factor) / Num1; factor = CMath::fract(factor) * Den2;
|
||||
ret += factor / (Num1 * Num2);
|
||||
return ret * m_factor; }
|
||||
virtual double fromDefault(double factor) const { using BlackMisc::Math::CMath;
|
||||
factor /= m_factor;
|
||||
double ret = CMath::trunc(factor); factor = CMath::fract(factor) * Num1;
|
||||
ret += CMath::trunc(factor) / Den1; factor = CMath::fract(factor) * Num2;
|
||||
return ret += factor / (Den1 * Den2); }
|
||||
virtual Converter *clone(const CMeasurementPrefix &) const { qFatal("Not implemented"); return 0; }
|
||||
};
|
||||
|
||||
private:
|
||||
QString m_name; //!< name, e.g. "meter"
|
||||
QString m_unitName; //!< unit name, e.g. "m"
|
||||
QString m_type; //!< type,such as distance. Somehow redundant, but simplifies unit comparisons
|
||||
bool m_isSiUnit; //!< is this a SI unit?
|
||||
bool m_isSiBaseUnit; //!< SI base unit?
|
||||
double m_conversionFactorToSIConversionUnit; //!< factor to convert to SI, set to 0 if not applicable (rare cases, e.g. temperature)
|
||||
QString m_symbol; //!< unit name, e.g. "m"
|
||||
double m_epsilon; //!< values with differences below epsilon are the equal
|
||||
int m_displayDigits; //!< standard rounding for string conversions
|
||||
CMeasurementPrefix m_multiplier; //!< multiplier (kilo, Mega)
|
||||
UnitConverter m_fromSiConverter; //! allows an arbitrary conversion method as per object (e.g. angle, sexagesimal)
|
||||
UnitConverter m_toSiConverter; //! allows an arbitrary conversion method as per object (e.g. angle, sexagesimal)
|
||||
CMeasurementPrefix m_prefix; //!< multiplier (kilo, Mega)
|
||||
QSharedDataPointer<Converter> m_converter; //!< strategy pattern allows an arbitrary conversion method as per object
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Constructor by parameter
|
||||
* Construct a unit with linear conversion
|
||||
* \param name
|
||||
* \param unitName
|
||||
* \param type
|
||||
* \param isSiUnit
|
||||
* \param isSiBaseUnit
|
||||
* \param conversionFactorToSI
|
||||
* \param multiplier
|
||||
* \param symbol
|
||||
* \param factor
|
||||
* \param displayDigits
|
||||
* \param epsilon
|
||||
* \param toSiConverter
|
||||
* \param fromSiConverter
|
||||
*/
|
||||
CMeasurementUnit(const QString &name, const QString &unitName, const QString &type, bool isSiUnit, bool isSiBaseUnit, double conversionFactorToSI = 1,
|
||||
const CMeasurementPrefix &multiplier = CMeasurementPrefix::None(), qint32 displayDigits = 2,
|
||||
double epsilon = 1E-10, UnitConverter toSiConverter = 0, UnitConverter fromSiConverter = 0);
|
||||
CMeasurementUnit(const QString &name, const QString &symbol, double factor, int displayDigits, double epsilon);
|
||||
|
||||
/*!
|
||||
* Construct a unit with affine conversion
|
||||
* \param name
|
||||
* \param symbol
|
||||
* \param factor
|
||||
* \param offset
|
||||
* \param displayDigits
|
||||
* \param epsilon
|
||||
*/
|
||||
CMeasurementUnit(const QString &name, const QString &symbol, double factor, double offset, int displayDigits, double epsilon);
|
||||
|
||||
/*!
|
||||
* Construct a unit with custom conversion
|
||||
* \param name
|
||||
* \param symbol
|
||||
* \param converter
|
||||
* \param displayDigits
|
||||
* \param epsilon
|
||||
*/
|
||||
CMeasurementUnit(const QString &name, const QString &symbol, Converter *converter, int displayDigits, double epsilon);
|
||||
|
||||
/*!
|
||||
* Construct from base unit and prefix
|
||||
* \param base
|
||||
* \param prefix
|
||||
* \param displayDigits
|
||||
* \param epsilon
|
||||
*/
|
||||
CMeasurementUnit(const CMeasurementUnit &base, const CMeasurementPrefix &prefix, int displayDigits = 2, double epsilon = 1E-10);
|
||||
|
||||
/*!
|
||||
* \brief Copy constructor
|
||||
@@ -357,38 +462,7 @@ protected:
|
||||
*/
|
||||
virtual QString convertToQString(bool i18n = false) const
|
||||
{
|
||||
return this->getUnitName(i18n);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Conversion factor to SI conversion unit
|
||||
* \return
|
||||
*/
|
||||
double getConversionFactorToSI() const
|
||||
{
|
||||
return this->m_conversionFactorToSIConversionUnit;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Given value to conversion SI conversion unit (e.g. meter, hertz).
|
||||
* Standard implementaion is simply factor based.
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double conversionToSiConversionUnit(double value) const
|
||||
{
|
||||
return value * this->m_conversionFactorToSIConversionUnit;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Value from SI conversion unit to this unit.
|
||||
* Standard implementation is simply factor based.
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
virtual double conversionFromSiConversionUnit(double value) const
|
||||
{
|
||||
return value / this->m_conversionFactorToSIConversionUnit;
|
||||
return this->getSymbol(i18n);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -397,7 +471,7 @@ protected:
|
||||
*/
|
||||
virtual void marshallToDbus(QDBusArgument &argument) const
|
||||
{
|
||||
argument << this->m_unitName;
|
||||
argument << this->m_symbol;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -411,6 +485,22 @@ protected:
|
||||
(*this) = CMeasurementUnit::None();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Unit from symbol
|
||||
* \param symbol must be a valid unit symbol (without i18n) or empty string (empty means default unit)
|
||||
* \return
|
||||
*/
|
||||
template <class U> static const U &unitFromSymbol(const QString &symbol)
|
||||
{
|
||||
if (symbol.isEmpty()) return U::defaultUnit();
|
||||
const QList<U> &units = U::allUnits();
|
||||
for (int i = 0; i < units.size(); ++i) {
|
||||
if (units.at(i).getSymbol() == symbol) return units.at(i);
|
||||
}
|
||||
qFatal("Illegal unit name");
|
||||
return U::defaultUnit(); // just suppress "not all control paths return a value"
|
||||
}
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Equal operator ==
|
||||
@@ -426,33 +516,6 @@ public:
|
||||
*/
|
||||
bool operator != (const CMeasurementUnit &other) const;
|
||||
|
||||
/*!
|
||||
* \brief Representing an SI unit? Examples: kilometer, meter, hertz
|
||||
* \return
|
||||
*/
|
||||
bool isSiUnit() const
|
||||
{
|
||||
return this->m_isSiUnit;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Representing an base SI unit? Examples: second, meter
|
||||
* \return
|
||||
*/
|
||||
bool isSiBaseUnit() const
|
||||
{
|
||||
return this->m_isSiUnit;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Representing an SI base unit? Example: meter
|
||||
* \return
|
||||
*/
|
||||
bool isUnprefixedSiUnit() const
|
||||
{
|
||||
return this->m_isSiUnit && this->m_multiplier.getFactor() == 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Name such as "meter"
|
||||
* \param i18n
|
||||
@@ -460,7 +523,8 @@ public:
|
||||
*/
|
||||
QString getName(bool i18n = false) const
|
||||
{
|
||||
return i18n ? QCoreApplication::translate("CMeasurementUnit", this->m_name.toStdString().c_str()) : this->m_name;
|
||||
QString base = i18n ? QCoreApplication::translate("CMeasurementUnit", this->m_name.toStdString().c_str()) : this->m_name;
|
||||
return this->m_prefix.getName(i18n) + base;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -468,41 +532,19 @@ public:
|
||||
* \param i18n
|
||||
* \return
|
||||
*/
|
||||
QString getUnitName(bool i18n = false) const
|
||||
QString getSymbol(bool i18n = false) const
|
||||
{
|
||||
return i18n ? QCoreApplication::translate("CMeasurementUnit", this->m_unitName.toStdString().c_str()) : this->m_unitName;
|
||||
QString base = i18n ? QCoreApplication::translate("CMeasurementUnit", this->m_symbol.toStdString().c_str()) : this->m_symbol;
|
||||
return this->m_prefix.getSymbol(i18n) + base;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Type such as "distance", "frequency"
|
||||
* \return
|
||||
*/
|
||||
QString getType() const
|
||||
{
|
||||
return this->m_type;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Given value to conversion SI conversion unit (e.g. meter, hertz).
|
||||
* Standard implementation is simply factor based.
|
||||
* \brief Rounded value
|
||||
* \param value
|
||||
* \param digits
|
||||
* \return
|
||||
*/
|
||||
double convertToSiConversionUnit(double value) const
|
||||
{
|
||||
return (this->m_toSiConverter) ? this->m_toSiConverter((*this), value) : this->conversionToSiConversionUnit(value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Value from SI conversion unit to this unit.
|
||||
* Standard implementation is simply factor based.
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
double convertFromSiConversionUnit(double value) const
|
||||
{
|
||||
return (this->m_fromSiConverter) ? this->m_fromSiConverter((*this), value) : this->conversionFromSiConversionUnit(value);
|
||||
}
|
||||
double roundValue(double value, int digits = -1) const;
|
||||
|
||||
/*!
|
||||
* Rounded string utility method, virtual so units can have
|
||||
@@ -512,15 +554,7 @@ public:
|
||||
* \param i18n
|
||||
* \return
|
||||
*/
|
||||
virtual QString toQStringRounded(double value, int digits = -1, bool i18n = false) const;
|
||||
|
||||
/*!
|
||||
* \brief Rounded value
|
||||
* \param value
|
||||
* \param digits
|
||||
* \return
|
||||
*/
|
||||
double valueRounded(double value, int digits = -1) const;
|
||||
virtual QString makeRoundedQString(double value, int digits = -1, bool i18n = false) const;
|
||||
|
||||
/*!
|
||||
* \brief Value rounded with unit, e.g. "5.00m", "30kHz"
|
||||
@@ -529,7 +563,7 @@ public:
|
||||
* \param i18n
|
||||
* \return
|
||||
*/
|
||||
virtual QString valueRoundedWithUnit(double value, int digits = -1, bool i18n = false) const;
|
||||
virtual QString makeRoundedQStringWithUnit(double value, int digits = -1, bool i18n = false) const;
|
||||
|
||||
/*!
|
||||
* \brief Threshold for rounding
|
||||
@@ -544,7 +578,7 @@ public:
|
||||
* \brief getDisplayDigits
|
||||
* \return
|
||||
*/
|
||||
qint32 getDisplayDigits() const
|
||||
int getDisplayDigits() const
|
||||
{
|
||||
return this->m_displayDigits;
|
||||
}
|
||||
@@ -553,26 +587,16 @@ public:
|
||||
* \brief Multiplier such as "kilo"
|
||||
* \return
|
||||
*/
|
||||
CMeasurementPrefix getMultiplier() const
|
||||
CMeasurementPrefix getPrefix() const
|
||||
{
|
||||
return this->m_multiplier;
|
||||
return this->m_prefix;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Factor to convert to given unit
|
||||
* \param value
|
||||
* \param to
|
||||
* \return
|
||||
* Convert from other unit to this unit.
|
||||
* \param
|
||||
*/
|
||||
double conversionToUnit(double value, const CMeasurementUnit &to) const;
|
||||
|
||||
/*!
|
||||
* Epsilon rounding. In some conversion rouding is required to avoid
|
||||
* periodical numbers.
|
||||
* \param value
|
||||
* \return
|
||||
*/
|
||||
double epsilonUpRounding(double value) const;
|
||||
double convertFrom(double value, const CMeasurementUnit &unit) const;
|
||||
|
||||
/*!
|
||||
* \brief Is given value <= epsilon?
|
||||
@@ -595,7 +619,7 @@ public:
|
||||
*/
|
||||
static CMeasurementUnit &None()
|
||||
{
|
||||
static CMeasurementUnit none("none", "", "", false, false, 0.0, CMeasurementPrefix::None(), 0, 0);
|
||||
static CMeasurementUnit none("none", "", 0.0, 0, 0);
|
||||
return none;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -69,6 +69,16 @@ public:
|
||||
return p;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Standard pressure datum for flight levels expressed in mmHg, such as in Russia, 760mmHg
|
||||
* \return
|
||||
*/
|
||||
static const CPressure& RuFlightLevelPressure()
|
||||
{
|
||||
static CPressure p(760, CPressureUnit::mmHg());
|
||||
return p;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Unicom frequency
|
||||
* \return
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
*/
|
||||
CFrequency() : CPhysicalQuantity(0, CFrequencyUnit::Hz(), CFrequencyUnit::Hz()) {}
|
||||
CFrequency() : CPhysicalQuantity(0, CFrequencyUnit::defaultUnit()) {}
|
||||
|
||||
/**
|
||||
*\brief Copy constructor from base type
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
* \param value
|
||||
* \param unit
|
||||
*/
|
||||
CFrequency(double value, const CFrequencyUnit &unit) : CPhysicalQuantity(value, unit, CFrequencyUnit::Hz()) {}
|
||||
CFrequency(double value, const CFrequencyUnit &unit) : CPhysicalQuantity(value, unit) {}
|
||||
|
||||
/*!
|
||||
* \brief Virtual destructor
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
*/
|
||||
CLength() : CPhysicalQuantity(0, CLengthUnit::m(), CLengthUnit::m()) {}
|
||||
CLength() : CPhysicalQuantity(0, CLengthUnit::defaultUnit()) {}
|
||||
|
||||
/**
|
||||
*\brief Copy constructor from base type
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
* \param value
|
||||
* \param unit
|
||||
*/
|
||||
CLength(double value, const CLengthUnit &unit) : CPhysicalQuantity(value, unit, CLengthUnit::m()) {}
|
||||
CLength(double value, const CLengthUnit &unit) : CPhysicalQuantity(value, unit) {}
|
||||
|
||||
/*!
|
||||
* \brief Virtual destructor
|
||||
|
||||
@@ -21,14 +21,14 @@ public:
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
*/
|
||||
CMass() : CPhysicalQuantity(0, CMassUnit::kg(), CMassUnit::kg()) {}
|
||||
CMass() : CPhysicalQuantity(0, CMassUnit::defaultUnit()) {}
|
||||
|
||||
/*!
|
||||
* \brief Init by double value
|
||||
* \param value
|
||||
* \param unit
|
||||
*/
|
||||
CMass(double value, const CMassUnit &unit) : CPhysicalQuantity(value, unit, CMassUnit::kg()) {}
|
||||
CMass(double value, const CMassUnit &unit) : CPhysicalQuantity(value, unit) {}
|
||||
|
||||
/*!
|
||||
* \brief Copy constructor from base type
|
||||
|
||||
@@ -13,25 +13,16 @@ namespace PhysicalQuantities
|
||||
/*
|
||||
* Constructor by double
|
||||
*/
|
||||
template <class MU, class PQ> CPhysicalQuantity<MU, PQ>::CPhysicalQuantity(double baseValue, const MU &unit, const MU &siConversionUnit) :
|
||||
m_unit(unit), m_conversionSiUnit(siConversionUnit)
|
||||
template <class MU, class PQ> CPhysicalQuantity<MU, PQ>::CPhysicalQuantity(double value, const MU &unit) :
|
||||
m_value(value), m_unit(unit)
|
||||
{
|
||||
this->setUnitValue(baseValue);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy constructor
|
||||
*/
|
||||
template <class MU, class PQ> CPhysicalQuantity<MU, PQ>::CPhysicalQuantity(const CPhysicalQuantity &other) :
|
||||
m_unitValueD(other.m_unitValueD), m_convertedSiUnitValueD(other.m_convertedSiUnitValueD),
|
||||
m_unit(other.m_unit), m_conversionSiUnit(other.m_conversionSiUnit)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Destructor
|
||||
*/
|
||||
template <class MU, class PQ> CPhysicalQuantity<MU, PQ>::~CPhysicalQuantity()
|
||||
m_value(other.m_value), m_unit(other.m_unit)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -41,25 +32,8 @@ template <class MU, class PQ> CPhysicalQuantity<MU, PQ>::~CPhysicalQuantity()
|
||||
template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::operator ==(const CPhysicalQuantity<MU, PQ> &other) const
|
||||
{
|
||||
if (this == &other) return true;
|
||||
if (this->m_unit.getType() != other.m_unit.getType()) return false;
|
||||
|
||||
// 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 == other.m_unit)
|
||||
{
|
||||
// same unit, comparison based on double
|
||||
diff = qAbs(this->m_unitValueD - other.m_unitValueD);
|
||||
eq = diff <= (lenient * this->m_unit.getEpsilon());
|
||||
}
|
||||
else
|
||||
{
|
||||
// based on SI value
|
||||
diff = qAbs(this->m_convertedSiUnitValueD - other.m_convertedSiUnitValueD);
|
||||
eq = diff <= (lenient * this->m_conversionSiUnit.getEpsilon());
|
||||
}
|
||||
return eq;
|
||||
double diff = abs(this->m_value - other.value(this->m_unit));
|
||||
return diff <= this->m_unit.getEpsilon();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -77,10 +51,8 @@ template <class MU, class PQ> CPhysicalQuantity<MU, PQ>& CPhysicalQuantity<MU, P
|
||||
{
|
||||
if (this == &other) return *this;
|
||||
|
||||
this->m_unitValueD = other.m_unitValueD;
|
||||
this->m_convertedSiUnitValueD = other.m_convertedSiUnitValueD;
|
||||
this->m_value = other.m_value;
|
||||
this->m_unit = other.m_unit;
|
||||
this->m_conversionSiUnit = other.m_conversionSiUnit;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -89,15 +61,7 @@ template <class MU, class PQ> CPhysicalQuantity<MU, PQ>& CPhysicalQuantity<MU, P
|
||||
*/
|
||||
template <class MU, class PQ> CPhysicalQuantity<MU, PQ> &CPhysicalQuantity<MU, PQ>::operator +=(const CPhysicalQuantity<MU, PQ> &other)
|
||||
{
|
||||
if (this->m_unit == other.m_unit)
|
||||
{
|
||||
this->setUnitValue(other.m_unitValueD + this->m_unitValueD);
|
||||
}
|
||||
else
|
||||
{
|
||||
double v = other.value(this->m_unit);
|
||||
this->setUnitValue(v + this->m_unitValueD);
|
||||
}
|
||||
this->m_value += other.value(this->m_unit);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -114,17 +78,17 @@ template <class MU, class PQ> PQ CPhysicalQuantity<MU, PQ>::operator +(const PQ
|
||||
/*
|
||||
* Explicit plus
|
||||
*/
|
||||
template <class MU, class PQ> void CPhysicalQuantity<MU, PQ>::addUnitValue(double value)
|
||||
template <class MU, class PQ> void CPhysicalQuantity<MU, PQ>::addValueSameUnit(double value)
|
||||
{
|
||||
this->setUnitValue(this->m_unitValueD + value);
|
||||
this->m_value += value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Explicit minus
|
||||
*/
|
||||
template <class MU, class PQ> void CPhysicalQuantity<MU, PQ>::substractUnitValue(double value)
|
||||
template <class MU, class PQ> void CPhysicalQuantity<MU, PQ>::substractValueSameUnit(double value)
|
||||
{
|
||||
this->setUnitValue(this->m_unitValueD - value);
|
||||
this->m_value -= value;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -132,15 +96,7 @@ template <class MU, class PQ> void CPhysicalQuantity<MU, PQ>::substractUnitValue
|
||||
*/
|
||||
template <class MU, class PQ> CPhysicalQuantity<MU, PQ> &CPhysicalQuantity<MU, PQ>::operator -=(const CPhysicalQuantity<MU, PQ> &other)
|
||||
{
|
||||
if (this->m_unit == other.m_unit)
|
||||
{
|
||||
this->setUnitValue(other.m_unitValueD - this->m_unitValueD);
|
||||
}
|
||||
else
|
||||
{
|
||||
double v = other.value(this->m_unit);
|
||||
this->setUnitValue(v - this->m_unitValueD);
|
||||
}
|
||||
this->m_value -= other.value(this->m_unit);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -157,38 +113,38 @@ template <class MU, class PQ> PQ CPhysicalQuantity<MU, PQ>::operator -(const PQ
|
||||
/*
|
||||
* Multiply operator
|
||||
*/
|
||||
template <class MU, class PQ> CPhysicalQuantity<MU, PQ> &CPhysicalQuantity<MU, PQ>::operator *=(double multiply)
|
||||
template <class MU, class PQ> CPhysicalQuantity<MU, PQ> &CPhysicalQuantity<MU, PQ>::operator *=(double factor)
|
||||
{
|
||||
this->setUnitValue(this->m_unitValueD * multiply);
|
||||
this->m_value *= factor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiply operator
|
||||
*/
|
||||
template <class MU, class PQ> PQ CPhysicalQuantity<MU, PQ>::operator *(double multiply) const
|
||||
template <class MU, class PQ> PQ CPhysicalQuantity<MU, PQ>::operator *(double factor) const
|
||||
{
|
||||
PQ copy = *derived();
|
||||
copy *= multiply;
|
||||
copy *= factor;
|
||||
return copy;
|
||||
}
|
||||
|
||||
/*
|
||||
* Divide operator /=
|
||||
*/
|
||||
template <class MU, class PQ> CPhysicalQuantity<MU, PQ> &CPhysicalQuantity<MU, PQ>::operator /=(double divide)
|
||||
template <class MU, class PQ> CPhysicalQuantity<MU, PQ> &CPhysicalQuantity<MU, PQ>::operator /=(double divisor)
|
||||
{
|
||||
this->setUnitValue(this->m_unitValueD / divide);
|
||||
this->m_value /= divisor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
* Divide operator /
|
||||
*/
|
||||
template <class MU, class PQ> PQ CPhysicalQuantity<MU, PQ>::operator /(double divide) const
|
||||
template <class MU, class PQ> PQ CPhysicalQuantity<MU, PQ>::operator /(double divisor) const
|
||||
{
|
||||
PQ copy = *derived();
|
||||
copy /= divide;
|
||||
copy /= divisor;
|
||||
return copy;
|
||||
}
|
||||
|
||||
@@ -199,9 +155,7 @@ template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::operator <(const C
|
||||
{
|
||||
if ((*this) == other) return false;
|
||||
|
||||
// == considers epsilon, so we now have a diff > epsilon here
|
||||
double diff = this->m_convertedSiUnitValueD - other.m_convertedSiUnitValueD;
|
||||
return (diff < 0);
|
||||
return (this->m_value < other.value(this->m_unit));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -238,9 +192,8 @@ template <class MU, class PQ> PQ &CPhysicalQuantity<MU, PQ>::switchUnit(const MU
|
||||
{
|
||||
if (this->m_unit != newUnit)
|
||||
{
|
||||
double cf = this->m_unit.conversionToUnit(this->m_unitValueD, newUnit);
|
||||
this->m_value = newUnit.convertFrom(this->m_value, this->m_unit);
|
||||
this->m_unit = newUnit;
|
||||
this->setUnitValue(cf);
|
||||
}
|
||||
return *derived();
|
||||
}
|
||||
@@ -248,60 +201,9 @@ template <class MU, class PQ> PQ &CPhysicalQuantity<MU, PQ>::switchUnit(const MU
|
||||
/*
|
||||
* Init by double
|
||||
*/
|
||||
template <class MU, class PQ> void CPhysicalQuantity<MU, PQ>::setUnitValue(double baseValue)
|
||||
template <class MU, class PQ> void CPhysicalQuantity<MU, PQ>::setValueSameUnit(double baseValue)
|
||||
{
|
||||
this->m_unitValueD = baseValue;
|
||||
this->setConversionSiUnitValue();
|
||||
}
|
||||
|
||||
/*
|
||||
* Set SI value
|
||||
*/
|
||||
template <class MU, class PQ> void CPhysicalQuantity<MU, PQ>::setConversionSiUnitValue()
|
||||
{
|
||||
double si = this->m_unit.convertToSiConversionUnit(this->m_unitValueD);
|
||||
this->m_convertedSiUnitValueD = si;
|
||||
}
|
||||
|
||||
/*
|
||||
* Round
|
||||
*/
|
||||
template <class MU, class PQ> double CPhysicalQuantity<MU, PQ>::unitValueToDoubleRounded(int digits) const
|
||||
{
|
||||
return this->m_unit.valueRounded(this->m_unitValueD, digits);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rounded value to QString
|
||||
*/
|
||||
template <class MU, class PQ> QString CPhysicalQuantity<MU, PQ>::unitValueToQStringRounded(int digits) const
|
||||
{
|
||||
return this->m_unit.toQStringRounded(this->m_unitValueD, digits);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rounded with unit
|
||||
*/
|
||||
template <class MU, class PQ> QString CPhysicalQuantity<MU, PQ>::unitValueRoundedWithUnit(int digits, bool i18n) const
|
||||
{
|
||||
return this->m_unit.valueRoundedWithUnit(this->m_unitValueD, digits, i18n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rounded SI value to QString
|
||||
*/
|
||||
template <class MU, class PQ> QString CPhysicalQuantity<MU, PQ>::convertedSiValueToQStringRounded(int digits) const
|
||||
{
|
||||
if (digits < 1) digits = this->m_conversionSiUnit.getDisplayDigits();
|
||||
return this->m_conversionSiUnit.toQStringRounded(this->m_convertedSiUnitValueD, digits);
|
||||
}
|
||||
|
||||
/*
|
||||
* SI base unit value with unit
|
||||
*/
|
||||
template <class MU, class PQ> QString CPhysicalQuantity<MU, PQ>::convertedSiValueRoundedWithUnit(int digits, bool i18n) const
|
||||
{
|
||||
return this->m_conversionSiUnit.valueRoundedWithUnit(this->m_convertedSiUnitValueD, digits, i18n);
|
||||
this->m_value = baseValue;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -309,9 +211,7 @@ template <class MU, class PQ> QString CPhysicalQuantity<MU, PQ>::convertedSiValu
|
||||
*/
|
||||
template <class MU, class PQ> QString CPhysicalQuantity<MU, PQ>::valueRoundedWithUnit(const MU &unit, int digits, bool i18n) const
|
||||
{
|
||||
if (unit == this->m_unit) return this->unitValueRoundedWithUnit(digits, i18n);
|
||||
if (unit == this->m_conversionSiUnit) return this->convertedSiValueRoundedWithUnit(digits, i18n);
|
||||
return unit.valueRoundedWithUnit(this->value(unit), digits, i18n);
|
||||
return unit.makeRoundedQStringWithUnit(this->value(unit), digits, i18n);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -319,7 +219,7 @@ template <class MU, class PQ> QString CPhysicalQuantity<MU, PQ>::valueRoundedWit
|
||||
*/
|
||||
template <class MU, class PQ> double CPhysicalQuantity<MU, PQ>::valueRounded(const MU &unit, int digits) const
|
||||
{
|
||||
return unit.valueRounded(this->value(unit), digits);
|
||||
return unit.roundValue(this->value(unit), digits);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -327,19 +227,7 @@ template <class MU, class PQ> double CPhysicalQuantity<MU, PQ>::valueRounded(con
|
||||
*/
|
||||
template <class MU, class PQ> double CPhysicalQuantity<MU, PQ>::value(const MU &unit) const
|
||||
{
|
||||
if (unit == this->m_unit) return this->m_unitValueD;
|
||||
if (unit == this->m_conversionSiUnit) return this->m_convertedSiUnitValueD;
|
||||
double v = unit.convertFromSiConversionUnit(this->m_convertedSiUnitValueD);
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
* Round utility method
|
||||
*/
|
||||
template <class MU, class PQ> double CPhysicalQuantity<MU, PQ>::convertedSiValueToDoubleRounded(int digits) const
|
||||
{
|
||||
if (digits < 1) digits = this->m_conversionSiUnit.getDisplayDigits();
|
||||
return this->m_conversionSiUnit.valueRounded(this->m_convertedSiUnitValueD, digits);
|
||||
return unit.convertFrom(this->m_value, this->m_unit);
|
||||
}
|
||||
|
||||
// see here for the reason of thess forward instantiations
|
||||
|
||||
@@ -27,8 +27,13 @@ namespace PhysicalQuantities
|
||||
template <class MU, class PQ> class CPhysicalQuantity : public BlackMisc::CBaseStreamStringifier
|
||||
{
|
||||
private:
|
||||
double m_unitValueD; //!< value backed by double
|
||||
double m_convertedSiUnitValueD; //!< SI unit value
|
||||
double m_value; //!< numeric part
|
||||
MU m_unit; //!< unit part
|
||||
|
||||
/*!
|
||||
* Which subclass of CMeasurementUnit does this quantity use?
|
||||
*/
|
||||
typedef MU UnitClass;
|
||||
|
||||
/*!
|
||||
* \brief Easy access to derived class (CRTP template parameter)
|
||||
@@ -49,16 +54,25 @@ private:
|
||||
}
|
||||
|
||||
protected:
|
||||
MU m_unit; //!< unit
|
||||
MU m_conversionSiUnit; //!< corresponding SI base unit
|
||||
|
||||
/*!
|
||||
* \brief Constructor with double
|
||||
* \param baseValue
|
||||
* \param value
|
||||
* \param unit
|
||||
* \param siConversionUnit
|
||||
*/
|
||||
CPhysicalQuantity(double baseValue, const MU &unit, const MU &siConversionUnit);
|
||||
CPhysicalQuantity(double value, const MU &unit);
|
||||
|
||||
/*!
|
||||
* \brief Copy constructor
|
||||
* \param other
|
||||
*/
|
||||
CPhysicalQuantity(const CPhysicalQuantity &other);
|
||||
|
||||
/*!
|
||||
* \brief Assignment operator =
|
||||
* \param other
|
||||
* \return
|
||||
*/
|
||||
CPhysicalQuantity &operator =(const CPhysicalQuantity &other);
|
||||
|
||||
/*!
|
||||
* \brief Name as string
|
||||
@@ -67,32 +81,20 @@ protected:
|
||||
*/
|
||||
virtual QString convertToQString(bool i18n = false) const
|
||||
{
|
||||
return this->unitValueRoundedWithUnit(-1, i18n);
|
||||
return this->valueRoundedWithUnit(this->getUnit(), -1, i18n);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Init by double
|
||||
* \param baseValue
|
||||
* \brief Change value without changing unit
|
||||
* \param value
|
||||
*/
|
||||
|
||||
void setUnitValue(double baseValue);
|
||||
|
||||
/*!
|
||||
* \brief Set the SI value
|
||||
*/
|
||||
void setConversionSiUnitValue();
|
||||
void setValueSameUnit(double value);
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Copy constructor
|
||||
* \param other
|
||||
*/
|
||||
CPhysicalQuantity(const CPhysicalQuantity &other);
|
||||
|
||||
/*!
|
||||
* \brief Virtual destructor
|
||||
*/
|
||||
virtual ~CPhysicalQuantity();
|
||||
virtual ~CPhysicalQuantity() {}
|
||||
|
||||
/*!
|
||||
* \brief Unit of the distance
|
||||
@@ -104,48 +106,12 @@ public:
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Conversion SI unit
|
||||
* \return
|
||||
*/
|
||||
MU getConversionSiUnit() const
|
||||
{
|
||||
return this->m_conversionSiUnit;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Switch unit, e.g. feet to meter
|
||||
* \brief Change unit, and convert value to maintain the same quantity
|
||||
* \param newUnit
|
||||
* \return
|
||||
*/
|
||||
PQ &switchUnit(const MU &newUnit);
|
||||
|
||||
/*!
|
||||
* \brief Value in SI base unit? Meter is an SI base unit, hertz not!
|
||||
* \return
|
||||
*/
|
||||
bool isSiBaseUnit() const
|
||||
{
|
||||
return this->m_unit.isSiBaseUnit();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Value in SI unit? Hertz is an derived SI unit, NM not!
|
||||
* \return
|
||||
*/
|
||||
bool isSiUnit() const
|
||||
{
|
||||
return this->m_unit.isSiUnit();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Value in unprefixed SI unit? Meter is a unprefixed, kilometer a prefixed SI Unit
|
||||
* \return
|
||||
*/
|
||||
bool isUnprefixedSiUnit() const
|
||||
{
|
||||
return this->m_unit.isUnprefixedSiUnit();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Value in given unit
|
||||
* \param unit
|
||||
@@ -154,7 +120,16 @@ public:
|
||||
double value(const MU &unit) const;
|
||||
|
||||
/*!
|
||||
* \brief Rounded value in unit
|
||||
* \brief Value in current unit
|
||||
* \return
|
||||
*/
|
||||
double value() const
|
||||
{
|
||||
return this->m_value;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Rounded value in given unit
|
||||
* \param unit
|
||||
* \param digits
|
||||
* \return
|
||||
@@ -162,7 +137,17 @@ public:
|
||||
double valueRounded(const MU &unit, int digits = -1) const;
|
||||
|
||||
/*!
|
||||
* \brief Value to QString with unit, e.g. "5.00m"
|
||||
* \brief Rounded value in current unit
|
||||
* \param digits
|
||||
* \return
|
||||
*/
|
||||
double valueRounded(int digits = -1) const
|
||||
{
|
||||
return this->valueRounded(this->m_unit, digits);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Value to QString with the given unit, e.g. "5.00m"
|
||||
* \param unit
|
||||
* \param digits
|
||||
* \param i18n
|
||||
@@ -171,80 +156,27 @@ public:
|
||||
QString valueRoundedWithUnit(const MU &unit, int digits = -1, bool i18n = false) const;
|
||||
|
||||
/*!
|
||||
* \brief Value as double
|
||||
* \return
|
||||
*/
|
||||
double unitValueToDouble() const
|
||||
{
|
||||
return this->m_unitValueD;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Value to QString with unit, e.g. "5.00m"
|
||||
* \brief Value to QString with the current unit, e.g. "5.00m"
|
||||
* \param digits
|
||||
* \param i18n
|
||||
* \return
|
||||
*/
|
||||
QString unitValueRoundedWithUnit(int digits = -1, bool i18n = false) const;
|
||||
|
||||
/*!
|
||||
* \brief Rounded value by n digits
|
||||
* \param digits
|
||||
* \return
|
||||
*/
|
||||
double unitValueToDoubleRounded(int digits = -1) const;
|
||||
|
||||
/*!
|
||||
* \brief Rounded value by n digits
|
||||
* \param digits if no value is provided, unit rounding is taken
|
||||
* \return
|
||||
*/
|
||||
QString unitValueToQStringRounded(int digits = -1) const;
|
||||
|
||||
/*!
|
||||
* \brief Conversion SI value as double
|
||||
* \return
|
||||
*/
|
||||
double convertedSiValueToDouble() const
|
||||
QString valueRoundedWithUnit(int digits = -1, bool i18n = false) const
|
||||
{
|
||||
return this->m_convertedSiUnitValueD;
|
||||
return this->valueRoundedWithUnit(this->m_unit, digits, i18n);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Rounded SI value by n digits
|
||||
* \param digits
|
||||
* \return
|
||||
*/
|
||||
double convertedSiValueToDoubleRounded(int digits = -1) const;
|
||||
|
||||
/*!
|
||||
* \brief Rounded value by n digits
|
||||
* \param digits if no value is provided, unit rounding is taken
|
||||
* \return
|
||||
*/
|
||||
QString convertedSiValueToQStringRounded(int digits = -1) const;
|
||||
|
||||
/*!
|
||||
* \brief SI Base unit value rounded
|
||||
* \param digits
|
||||
* \param i18n
|
||||
* \return
|
||||
*/
|
||||
QString convertedSiValueRoundedWithUnit(int digits = -1, bool i18n = false) const;
|
||||
|
||||
/*!
|
||||
* \brief Add to the unit value.
|
||||
* \remarks Since overloading the + operator with double did lead to unintended conversions, as explicit method
|
||||
* \brief Add to the value in the current unit.
|
||||
* \param value
|
||||
*/
|
||||
void addUnitValue(double value);
|
||||
void addValueSameUnit(double value);
|
||||
|
||||
/*!
|
||||
* \brief Substract to the unit value.
|
||||
* \remarks Since overloading the - operator with double did lead to unintended conversions, as explicit method
|
||||
* \brief Substract from the value in the current unit.
|
||||
* \param value
|
||||
*/
|
||||
void substractUnitValue(double value);
|
||||
void substractValueSameUnit(double value);
|
||||
|
||||
/*!
|
||||
* \brief Multiply operator *=
|
||||
@@ -341,13 +273,6 @@ public:
|
||||
*/
|
||||
bool operator >=(const CPhysicalQuantity &other) const;
|
||||
|
||||
/*!
|
||||
* \brief Assignment operator =
|
||||
* \param other
|
||||
* \return
|
||||
*/
|
||||
CPhysicalQuantity &operator =(const CPhysicalQuantity &other);
|
||||
|
||||
/*!
|
||||
* \brief Plus operator +
|
||||
* \param other
|
||||
@@ -368,25 +293,25 @@ public:
|
||||
*/
|
||||
bool isZeroEpsilon() const
|
||||
{
|
||||
return this->m_unit.isEpsilon(this->m_unitValueD);
|
||||
return this->m_unit.isEpsilon(this->m_value);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Value >= 0 epsilon considered
|
||||
* \return
|
||||
*/
|
||||
bool isGreaterOrEqualZeroEpsilon() const
|
||||
bool isNonNegativeEpsilon() const
|
||||
{
|
||||
return this->isZeroEpsilon() || this->m_unitValueD > 0;
|
||||
return this->isZeroEpsilon() || this->m_value > 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Value <= 0 epsilon considered
|
||||
* \return
|
||||
*/
|
||||
bool isLessOrEqualZeroEpsilon() const
|
||||
bool isNonPositiveEpsilon() const
|
||||
{
|
||||
return this->isZeroEpsilon() || this->m_unitValueD < 0;
|
||||
return this->isZeroEpsilon() || this->m_value < 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -395,10 +320,9 @@ public:
|
||||
*/
|
||||
virtual void marshallToDbus(QDBusArgument &argument) const
|
||||
{
|
||||
argument << this->m_unitValueD;
|
||||
argument << this->m_convertedSiUnitValueD;
|
||||
argument << this->value(UnitClass::defaultUnit());
|
||||
argument << this->m_value;
|
||||
argument << this->m_unit;
|
||||
argument << this->m_conversionSiUnit;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -407,10 +331,10 @@ public:
|
||||
*/
|
||||
virtual void unmarshallFromDbus(const QDBusArgument &argument)
|
||||
{
|
||||
argument >> this->m_unitValueD;
|
||||
argument >> this->m_convertedSiUnitValueD;
|
||||
double ignore;
|
||||
argument >> ignore;
|
||||
argument >> this->m_value;
|
||||
argument >> this->m_unit;
|
||||
argument >> this->m_conversionSiUnit;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
*/
|
||||
CPressure() : CPhysicalQuantity(0, CPressureUnit::Pa(), CPressureUnit::Pa()) {}
|
||||
CPressure() : CPhysicalQuantity(0, CPressureUnit::defaultUnit()) {}
|
||||
|
||||
/**
|
||||
*\brief Copy constructor from base type
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
* \param value
|
||||
* \param unit
|
||||
*/
|
||||
CPressure(double value, const CPressureUnit &unit) : CPhysicalQuantity(value, unit, CPressureUnit::Pa()) {}
|
||||
CPressure(double value, const CPressureUnit &unit) : CPhysicalQuantity(value, unit) {}
|
||||
|
||||
/*!
|
||||
* \brief Virtual destructor
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
*/
|
||||
CSpeed() : CPhysicalQuantity(0, CSpeedUnit::m_s(), CSpeedUnit::m_s()) {}
|
||||
CSpeed() : CPhysicalQuantity(0, CSpeedUnit::defaultUnit()) {}
|
||||
|
||||
/*!
|
||||
*\brief Copy constructor from base type
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
* \param value
|
||||
* \param unit
|
||||
*/
|
||||
CSpeed(double value, const CSpeedUnit &unit) : CPhysicalQuantity(value, unit, CSpeedUnit::m_s()) {}
|
||||
CSpeed(double value, const CSpeedUnit &unit) : CPhysicalQuantity(value, unit) {}
|
||||
|
||||
/*!
|
||||
* \brief Destructor
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
*/
|
||||
CTemperature() : CPhysicalQuantity(0, CTemperatureUnit::K(), CTemperatureUnit::K()) {}
|
||||
CTemperature() : CPhysicalQuantity(0, CTemperatureUnit::defaultUnit()) {}
|
||||
|
||||
/**
|
||||
* \brief Copy constructor from base type
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
* \param value
|
||||
* \param unit
|
||||
*/
|
||||
CTemperature(double value, const CTemperatureUnit &unit): CPhysicalQuantity(value, unit, CTemperatureUnit::K()) {}
|
||||
CTemperature(double value, const CTemperatureUnit &unit): CPhysicalQuantity(value, unit) {}
|
||||
|
||||
/*!
|
||||
* \brief Destructor
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
*/
|
||||
CTime() : CPhysicalQuantity(0, CTimeUnit::s(), CTimeUnit::s()) {}
|
||||
CTime() : CPhysicalQuantity(0, CTimeUnit::defaultUnit()) {}
|
||||
|
||||
/**
|
||||
*\brief Copy constructor from base type
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
* \param value
|
||||
* \param unit
|
||||
*/
|
||||
CTime(double value, const CTimeUnit &unit) : CPhysicalQuantity(value, unit, CTimeUnit::s()) {}
|
||||
CTime(double value, const CTimeUnit &unit) : CPhysicalQuantity(value, unit) {}
|
||||
|
||||
/*!
|
||||
* \brief Destructor
|
||||
|
||||
@@ -10,79 +10,74 @@ namespace BlackMisc
|
||||
namespace PhysicalQuantities
|
||||
{
|
||||
|
||||
/*
|
||||
* Convert to SI
|
||||
*/
|
||||
double CTemperatureUnit::conversionToSiConversionUnit(double value) const
|
||||
{
|
||||
double v = value + this->m_conversionOffsetToSi;
|
||||
v *= this->getConversionFactorToSI();
|
||||
return v;
|
||||
}
|
||||
using BlackMisc::Math::CMath;
|
||||
|
||||
/*
|
||||
* Convert from SI
|
||||
* Rounded to QString
|
||||
*/
|
||||
double CTemperatureUnit::conversionFromSiConversionUnit(double value) const
|
||||
QString CAngleUnit::makeRoundedQString(double value, int digits, bool i18n) const
|
||||
{
|
||||
double v = value / this->getConversionFactorToSI();
|
||||
v -= this->m_conversionOffsetToSi;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert from SI
|
||||
*/
|
||||
double CAngleUnit::conversionSexagesimalFromSi(const CMeasurementUnit &angleUnit, double value)
|
||||
{
|
||||
// using rounding here, since fractions can lead to ugly sexagesimal conversion
|
||||
// e.g. 185.499999 gives 185 29' 59.9999"
|
||||
value = angleUnit.epsilonUpRounding(value * 180 / M_PI); // degree
|
||||
double v = floor(value);
|
||||
double c = value - v;
|
||||
double mr = c * 60.0;
|
||||
double m = floor(mr); // minutes
|
||||
double s = (mr - m) * 60; // seconds + rest fraction
|
||||
v = (v + (m / 100) + (s / 10000));
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert to SI
|
||||
*/
|
||||
double CAngleUnit::conversionSexagesimalToSi(const CMeasurementUnit &, double value)
|
||||
{
|
||||
double v = floor(value); // degrees
|
||||
double c = value - v;
|
||||
c = c * 100.0;
|
||||
double m = floor(c);
|
||||
c = c - m;
|
||||
m /= 60.0; // minutes back to decimals
|
||||
double s = c / 36.0; // seconds back to decimals
|
||||
v = v + m + s;
|
||||
return v / 180.0 * M_PI;
|
||||
if (digits < 0) digits = this->getDisplayDigits();
|
||||
QString s;
|
||||
if ((*this) == CAngleUnit::sexagesimalDeg())
|
||||
{
|
||||
double de = CMath::trunc(value);
|
||||
double mi = CMath::trunc((value - de) * 100.0);
|
||||
double se = CMath::trunc((value - de - mi / 100.0) * 1000000) / 100.0;
|
||||
const char *fmt = value < 0 ? "-%L1 %L2'%L3\"" : "%L1 %L2'%L3\"";
|
||||
s = i18n ? QCoreApplication::translate("CMeasurementUnit", fmt) : fmt;
|
||||
s = s.arg(fabs(de), 0, 'f', 0).arg(fabs(mi), 2, 'f', 0, '0').arg(fabs(se), 2, 'f', digits, '0');
|
||||
}
|
||||
else if ((*this) == CAngleUnit::sexagesimalDegMin())
|
||||
{
|
||||
double de = CMath::trunc(value);
|
||||
double mi = CMath::trunc((value - de) * 100.0);
|
||||
const char *fmt = value < 0 ? "-%L1 %L2'" : "%L1 %L2'";
|
||||
s = i18n ? QCoreApplication::translate("CMeasurementUnit", fmt) : fmt;
|
||||
s = s.arg(fabs(de), 0, 'f', 0).arg(fabs(mi), 2, 'f', digits, '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
s = this->CMeasurementUnit::makeRoundedQString(value, digits, i18n);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rounded to QString
|
||||
*/
|
||||
QString CAngleUnit::toQStringRounded(double value, int digits, bool i18n) const
|
||||
QString CTimeUnit::makeRoundedQString(double value, int digits, bool i18n) const
|
||||
{
|
||||
if (digits < 0) digits = this->getDisplayDigits();
|
||||
QString s;
|
||||
if ((*this) == CAngleUnit::sexagesimalDeg())
|
||||
if ((*this) == CTimeUnit::hms())
|
||||
{
|
||||
// special formatting for sexagesimal degrees
|
||||
double de = floor(value);
|
||||
double mi = floor((value - de) * 100.0);
|
||||
double se = floor((value - de - mi / 100.0) * 1000000) / 100.0;
|
||||
QString ses = QLocale::system().toString(se, 'f', 2);
|
||||
s = QString::number(de);
|
||||
s = s.append(i18n ? CAngleUnit::deg().getUnitName(true) : " ");
|
||||
s = s.append(QString::number(mi)).append("'").append(ses).append("\"");
|
||||
double hr = CMath::trunc(value);
|
||||
double mi = CMath::trunc((value - hr) * 100.0);
|
||||
double se = CMath::trunc((value - hr - mi / 100.0) * 1000000) / 100.0;
|
||||
const char *fmt = value < 0 ? "-%L1h%L2m%L3s" : "%L1h%L2m%L3s";
|
||||
s = i18n ? QCoreApplication::translate("CMeasurementUnit", fmt) : fmt;
|
||||
s = s.arg(fabs(hr), 0, 'f', 0).arg(fabs(mi), 2, 'f', 0, '0').arg(fabs(se), 2, 'f', digits, '0');
|
||||
}
|
||||
else if ((*this) == CTimeUnit::hrmin())
|
||||
{
|
||||
double hr = CMath::trunc(value);
|
||||
double mi = CMath::trunc((value - hr) * 100.0);
|
||||
const char *fmt = value < 0 ? "-%L1h%L2m" : "%L1h%L2m";
|
||||
s = i18n ? QCoreApplication::translate("CMeasurementUnit", fmt) : fmt;
|
||||
s = s.arg(fabs(hr), 0, 'f', 0).arg(fabs(mi), 2, 'f', digits, '0');
|
||||
}
|
||||
else if ((*this) == CTimeUnit::minsec())
|
||||
{
|
||||
double mi = CMath::trunc(value);
|
||||
double se = CMath::trunc((value - mi) * 100.0);
|
||||
const char *fmt = value < 0 ? "-%L2m%L3s" : "%L2m%L3s";
|
||||
s = i18n ? QCoreApplication::translate("CMeasurementUnit", fmt) : fmt;
|
||||
s = s.arg(fabs(mi), 0, 'f', 0).arg(fabs(se), 2, 'f', digits, '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
s = this->CMeasurementUnit::toQStringRounded(value, digits);
|
||||
s = this->CMeasurementUnit::makeRoundedQString(value, digits, i18n);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,11 +37,11 @@ void CTestAviation::headingBasics()
|
||||
QVERIFY2(h4 == h1, "Values shall be equal");
|
||||
|
||||
h1 -= h1;
|
||||
QVERIFY2(h1.unitValueToDouble() == 0, "Value shall be 0");
|
||||
QVERIFY2(h1.value() == 0, "Value shall be 0");
|
||||
|
||||
// h4 = h1 + h2; does not work, because misleading
|
||||
h2 += h2; // add just angle
|
||||
QVERIFY2(h2.unitValueToDouble() == 360, "Value shall be 360");
|
||||
QVERIFY2(h2.value() == 360, "Value shall be 360");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -14,7 +14,7 @@ void CTestGeo::geoBasics()
|
||||
CLatitude lati(10, CAngleUnit::deg());
|
||||
QVERIFY2(lati * 2 == lati + lati, "Latitude addition should be equal");
|
||||
lati += CLatitude(20, CAngleUnit::deg());
|
||||
QVERIFY2(lati.unitValueToDoubleRounded() == 30.0, "Latitude should be 30 degrees");
|
||||
QVERIFY2(lati.valueRounded() == 30.0, "Latitude should be 30 degrees");
|
||||
|
||||
double lat = 27.999999, lon = 86.999999, h = 8820.999999; // Mt Everest
|
||||
CCoordinateGeodetic startGeoVec(lat, lon, h);
|
||||
|
||||
@@ -15,8 +15,6 @@ namespace BlackMiscTest
|
||||
*/
|
||||
void CTestPhysicalQuantities::unitsBasics()
|
||||
{
|
||||
QVERIFY2(CMeasurementPrefix::k() > CMeasurementPrefix::h(), "kilo > hecto");
|
||||
|
||||
// some tests on units
|
||||
CLengthUnit du1 = CLengthUnit::m(); // Copy
|
||||
CLengthUnit du2 = CLengthUnit::m(); // Copy
|
||||
@@ -25,7 +23,6 @@ void CTestPhysicalQuantities::unitsBasics()
|
||||
du2 = CLengthUnit::m(); // Copy
|
||||
QVERIFY2(du1 == du2, "Compare by value 2");
|
||||
QVERIFY2(CLengthUnit::m() == CLengthUnit::m(), "Compare by value");
|
||||
QVERIFY2(CMeasurementPrefix::h() < CMeasurementPrefix::M(), "hecto < mega");
|
||||
|
||||
CFrequencyUnit fu1 = CFrequencyUnit::Hz();
|
||||
QVERIFY2(fu1 != du1, "Hz must not be meter");
|
||||
@@ -54,12 +51,12 @@ void CTestPhysicalQuantities::lengthBasics()
|
||||
|
||||
// epsilon tests
|
||||
d1 = d2; // both in same unit
|
||||
d1.addUnitValue(d1.getUnit().getEpsilon()); // this should be still the same
|
||||
d1.addValueSameUnit(d1.getUnit().getEpsilon() / 2.0); // this should be still the same
|
||||
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
|
||||
d1.addValueSameUnit(d1.getUnit().getEpsilon()); // now over epsilon threshold
|
||||
QVERIFY2(d1 != d2, "Epsilon exceeded: 100 cm + 2 epsilon shall not be 100cm");
|
||||
QVERIFY2(d1 > d2, "d1 shall be greater");
|
||||
}
|
||||
@@ -82,8 +79,8 @@ void CTestPhysicalQuantities::frequencyTests()
|
||||
{
|
||||
CFrequency f1(1, CFrequencyUnit::MHz());
|
||||
QVERIFY2(f1.valueRounded(CFrequencyUnit::kHz(), 2) == 1000, "Mega is 1000kHz");
|
||||
QVERIFY2(f1.unitValueToDouble() == 1 , "1MHz");
|
||||
QVERIFY2(f1.convertedSiValueToDouble() == 1000000 , "1E6 Hz");
|
||||
QVERIFY2(f1.value() == 1 , "1MHz");
|
||||
QVERIFY2(f1.value(CFrequencyUnit::defaultUnit()) == 1000000 , "1E6 Hz");
|
||||
CFrequency f2(CMeasurementPrefix::M().toDouble(), CFrequencyUnit::Hz()) ; // 1 Megahertz
|
||||
QVERIFY2(f1 == f2 , "MHz is 1E6 Hz");
|
||||
}
|
||||
@@ -96,9 +93,13 @@ void CTestPhysicalQuantities::angleTests()
|
||||
CAngle a1(180, CAngleUnit::deg());
|
||||
CAngle a2(1.5 * CAngle::PI(), CAngleUnit::rad());
|
||||
CAngle a3(35.4336, CAngleUnit::sexagesimalDeg()); // 35.72666
|
||||
CAngle a4(35.436, CAngleUnit::sexagesimalDegMin()); // 35.72666
|
||||
CAngle a5(-60.3015, CAngleUnit::sexagesimalDeg()); // negative angles = west longitude or south latitude
|
||||
a2.switchUnit(CAngleUnit::deg());
|
||||
QVERIFY2(a1.piFactor() == 1, qPrintable(QString("Pi should be 1PI, not %1").arg(a1.piFactor())));
|
||||
QVERIFY2(a3.valueRounded(CAngleUnit::deg()) == 35.73, "Expecting 35.73");
|
||||
QVERIFY2(a4.valueRounded(CAngleUnit::deg()) == 35.73, "Expecting 35.73");
|
||||
QVERIFY2(a5.valueRounded(CAngleUnit::deg(), 4) == -60.5042, "Expecting -60.5042");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -107,11 +108,11 @@ void CTestPhysicalQuantities::angleTests()
|
||||
void CTestPhysicalQuantities::massTests()
|
||||
{
|
||||
CMass w1(1000, CMassUnit::kg());
|
||||
CMass w2(w1.unitValueToDouble(), CMassUnit::kg());
|
||||
CMass w2(w1.value(), CMassUnit::kg());
|
||||
w2.switchUnit(CMassUnit::t());
|
||||
QVERIFY2(w2.unitValueToDouble() == 1, "1tonne shall be 1000kg");
|
||||
QVERIFY2(w2.value() == 1, "1tonne shall be 1000kg");
|
||||
w2.switchUnit(CMassUnit::lb());
|
||||
QVERIFY2(w2.unitValueToDoubleRounded(2) == 2204.62, "1tonne shall be 2204pounds");
|
||||
QVERIFY2(w2.valueRounded(2) == 2204.62, "1tonne shall be 2204pounds");
|
||||
QVERIFY2(w1 == w2, "Masses shall be equal");
|
||||
}
|
||||
|
||||
@@ -127,7 +128,7 @@ void CTestPhysicalQuantities::pressureTests()
|
||||
|
||||
// does not match exactly
|
||||
QVERIFY2(p1 != p2, "Standard pressure test little difference");
|
||||
QVERIFY2(p1.unitValueToDouble() == p4.unitValueToDouble(), "mbar/hPa test");
|
||||
QVERIFY2(p1.value() == p4.value(), "mbar/hPa test");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -139,19 +140,25 @@ void CTestPhysicalQuantities::temperatureTests()
|
||||
CTemperature t2(1, CTemperatureUnit::F()); // 1F
|
||||
CTemperature t3(220.15, CTemperatureUnit::F());
|
||||
CTemperature t4(10, CTemperatureUnit::F());
|
||||
QVERIFY2(t1.convertedSiValueToDoubleRounded() == 273.15, qPrintable(QString("0C shall be 273.15K, not %1 K").arg(t1.convertedSiValueToDoubleRounded())));
|
||||
QVERIFY2(t1.valueRounded(CTemperatureUnit::K()) == 273.15, qPrintable(QString("0C shall be 273.15K, not %1 K").arg(t1.valueRounded(CTemperatureUnit::K()))));
|
||||
QVERIFY2(t2.valueRounded(CTemperatureUnit::C()) == -17.22, qPrintable(QString("1F shall be -17.22C, not %1 C").arg(t2.valueRounded(CTemperatureUnit::C()))));
|
||||
QVERIFY2(t3.valueRounded(CTemperatureUnit::C()) == 104.53, qPrintable(QString("220.15F shall be 104.53C, not %1 C").arg(t3.valueRounded(CTemperatureUnit::C()))));
|
||||
QVERIFY2(t4.valueRounded(CTemperatureUnit::K()) == 260.93, qPrintable(QString("10F shall be 260.93K, not %1 K").arg(t4.valueRounded(CTemperatureUnit::K()))));
|
||||
}
|
||||
|
||||
/*
|
||||
* Temperature tests
|
||||
* Time tests
|
||||
*/
|
||||
void CTestPhysicalQuantities::timeTests()
|
||||
{
|
||||
CTime t1(1, CTimeUnit::h());
|
||||
QVERIFY2(t1.convertedSiValueToDouble() == 3600, "1hour shall be 3600s");
|
||||
CTime t2(1.5, CTimeUnit::h());
|
||||
CTime t3(1.25, CTimeUnit::min());
|
||||
CTime t4(1.0101, CTimeUnit::hms());
|
||||
QVERIFY2(t1.value(CTimeUnit::defaultUnit()) == 3600, "1hour shall be 3600s");
|
||||
QVERIFY2(t2.value(CTimeUnit::hrmin()) == 1.30, "1.5hour shall be 1h30m");
|
||||
QVERIFY2(t3.value(CTimeUnit::minsec()) == 1.15, "1.25min shall be 1m15s");
|
||||
QVERIFY2(t4.value(CTimeUnit::s()) == 3661, "1h01m01s shall be 3661s");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -160,13 +167,13 @@ void CTestPhysicalQuantities::timeTests()
|
||||
void CTestPhysicalQuantities::accelerationTests()
|
||||
{
|
||||
CLength oneMeter(1, CLengthUnit::m());
|
||||
double ftFactor = oneMeter.switchUnit(CLengthUnit::ft()).unitValueToDouble();
|
||||
double ftFactor = oneMeter.switchUnit(CLengthUnit::ft()).value();
|
||||
|
||||
CAcceleration a1(10.0, CAccelerationUnit::m_s2());
|
||||
CAcceleration a2(a1);
|
||||
a1.switchUnit(CAccelerationUnit::ft_s2());
|
||||
QVERIFY2(a1 == a2, "Accelerations should be similar");
|
||||
QVERIFY2(BlackMisc::Math::CMath::round(a1.unitValueToDouble() * ftFactor, 6) == a2.unitValueToDoubleRounded(6),
|
||||
QVERIFY2(BlackMisc::Math::CMath::round(a1.value() * ftFactor, 6) == a2.valueRounded(6),
|
||||
"Numerical values should be equal");
|
||||
}
|
||||
|
||||
@@ -177,13 +184,13 @@ void CTestPhysicalQuantities::memoryTests()
|
||||
{
|
||||
CLength *c = new CLength(100, CLengthUnit::m());
|
||||
c->switchUnit(CLengthUnit::NM());
|
||||
QVERIFY2(c->getUnit() == CLengthUnit::NM() && c->getConversionSiUnit() == CLengthUnit::m(),
|
||||
QVERIFY2(c->getUnit() == CLengthUnit::NM() && CLengthUnit::defaultUnit() == CLengthUnit::m(),
|
||||
"Testing distance units failed");
|
||||
delete c;
|
||||
|
||||
CAngle *a = new CAngle(100, CAngleUnit::rad());
|
||||
a->switchUnit(CAngleUnit::deg());
|
||||
QVERIFY2(a->getUnit() == CAngleUnit::deg() && c->getConversionSiUnit() == CAngleUnit::rad(),
|
||||
QVERIFY2(a->getUnit() == CAngleUnit::deg() && CAngleUnit::defaultUnit() == CAngleUnit::deg(),
|
||||
"Testing angle units failed");
|
||||
delete a;
|
||||
}
|
||||
@@ -201,7 +208,7 @@ void CTestPhysicalQuantities::basicArithmetic()
|
||||
p3 /= 2.0;
|
||||
QVERIFY2(p3 == p1, "Pressure needs to be the same (1time)");
|
||||
p3 = p3 - p3;
|
||||
QVERIFY2(p3.unitValueToDouble() == 0, "Value needs to be zero");
|
||||
QVERIFY2(p3.value() == 0, "Value needs to be zero");
|
||||
p3 = CPressure(1013, CPressureUnit::hPa());
|
||||
QVERIFY2(p3 * 1.5 == 1.5 * p3, "Basic commutative test on PQ failed");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user