mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-05-05 01:35:45 +08:00
Initial structure for refactoring, some conversions still missing. Especially required further test cases.
This commit is contained in:
@@ -46,6 +46,10 @@ int CSamplesPhysicalQuantities::samples()
|
|||||||
l3 *= 1.5;// 3km now
|
l3 *= 1.5;// 3km now
|
||||||
qDebug() << l2 << l3;
|
qDebug() << l2 << l3;
|
||||||
|
|
||||||
|
l3 = l3 * 2;
|
||||||
|
qDebug() << "doubled l3:" << l3;
|
||||||
|
|
||||||
|
|
||||||
CFrequency f1(1E6, CFrequencyUnit::Hz()); // 1MHz
|
CFrequency f1(1E6, CFrequencyUnit::Hz()); // 1MHz
|
||||||
qDebug() << f1 << f1.valueRoundedWithUnit(CFrequencyUnit::MHz()) << f1.valueRoundedWithUnit(CFrequencyUnit::GHz(), 3);
|
qDebug() << f1 << f1.valueRoundedWithUnit(CFrequencyUnit::MHz()) << f1.valueRoundedWithUnit(CFrequencyUnit::GHz(), 3);
|
||||||
|
|
||||||
|
|||||||
@@ -11,15 +11,15 @@ namespace BlackMiscTest
|
|||||||
*/
|
*/
|
||||||
int CSamplesGeo::samples()
|
int CSamplesGeo::samples()
|
||||||
{
|
{
|
||||||
CGeoLatitude lat1(20.0, CAngleUnit::deg());
|
CLatitude lat1(20.0, CAngleUnit::deg());
|
||||||
CGeoLatitude lat2 = lat1;
|
CLatitude lat2 = lat1;
|
||||||
CGeoLatitude lat3 = lat1 - lat2;
|
CLatitude lat3 = lat1 - lat2;
|
||||||
|
|
||||||
qDebug() << lat1 << lat2 << lat3;
|
qDebug() << lat1 << lat2 << lat3;
|
||||||
qDebug() << (lat1 + lat2) << (lat1 - lat2);
|
qDebug() << (lat1 + lat2) << (lat1 - lat2);
|
||||||
|
|
||||||
lat3 += lat1;
|
lat3 += lat1;
|
||||||
CGeoLongitude lon1(33.0, CAngleUnit::deg());
|
CLongitude lon1(33.0, CAngleUnit::deg());
|
||||||
qDebug() << lon1 << lat3;
|
qDebug() << lon1 << lat3;
|
||||||
|
|
||||||
// lat3 += lon1; // must not work
|
// lat3 += lon1; // must not work
|
||||||
|
|||||||
@@ -72,7 +72,9 @@ HEADERS += \
|
|||||||
coordinategeodetic.h \
|
coordinategeodetic.h \
|
||||||
coordinateecef.h \
|
coordinateecef.h \
|
||||||
coordinatened.h \
|
coordinatened.h \
|
||||||
geoearthangle.h
|
geoearthangle.h \
|
||||||
|
coordinatetransformation.h \
|
||||||
|
mathmatrix1x3.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
logmessage.cpp \
|
logmessage.cpp \
|
||||||
@@ -104,6 +106,7 @@ SOURCES += \
|
|||||||
mathvector3dbase.cpp \
|
mathvector3dbase.cpp \
|
||||||
mathmatrixbase.cpp \
|
mathmatrixbase.cpp \
|
||||||
mathmatrix3x3.cpp \
|
mathmatrix3x3.cpp \
|
||||||
mathematics.cpp
|
mathematics.cpp \
|
||||||
|
coordinatetransformation.cpp
|
||||||
|
|
||||||
DESTDIR = ../../lib
|
DESTDIR = ../../lib
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ class CCoordinateGeodetic : public CBaseStreamStringifier<CCoordinateGeodetic>
|
|||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CGeoLatitude m_latitude; //!< Latitude
|
CLatitude m_latitude; //!< Latitude
|
||||||
CGeoLongitude m_longitude; //!< Longitude
|
CLongitude m_longitude; //!< Longitude
|
||||||
BlackMisc::PhysicalQuantities::CLength m_height; //!< height
|
BlackMisc::PhysicalQuantities::CLength m_height; //!< height
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
* \param longitude
|
* \param longitude
|
||||||
* \param height
|
* \param height
|
||||||
*/
|
*/
|
||||||
CCoordinateGeodetic(CGeoLatitude latitude, CGeoLongitude longitude, BlackMisc::PhysicalQuantities::CLength height) :
|
CCoordinateGeodetic(CLatitude latitude, CLongitude longitude, BlackMisc::PhysicalQuantities::CLength height) :
|
||||||
m_latitude(latitude), m_longitude(longitude), m_height(height) {}
|
m_latitude(latitude), m_longitude(longitude), m_height(height) {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -72,7 +72,7 @@ public:
|
|||||||
* \brief Latitude
|
* \brief Latitude
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
CGeoLatitude latitude() const
|
CLatitude latitude() const
|
||||||
{
|
{
|
||||||
return this->m_latitude;
|
return this->m_latitude;
|
||||||
}
|
}
|
||||||
@@ -81,7 +81,7 @@ public:
|
|||||||
* \brief Longitude
|
* \brief Longitude
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
CGeoLongitude longitude() const
|
CLongitude longitude() const
|
||||||
{
|
{
|
||||||
return this->m_longitude;
|
return this->m_longitude;
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ public:
|
|||||||
* \brief Set latitude
|
* \brief Set latitude
|
||||||
* \param latitude
|
* \param latitude
|
||||||
*/
|
*/
|
||||||
void setLatitude(CGeoLatitude latitude)
|
void setLatitude(CLatitude latitude)
|
||||||
{
|
{
|
||||||
this->m_latitude = latitude;
|
this->m_latitude = latitude;
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ public:
|
|||||||
* \brief Set longitude
|
* \brief Set longitude
|
||||||
* \param latitude
|
* \param latitude
|
||||||
*/
|
*/
|
||||||
void setLongitude(CGeoLongitude longitude)
|
void setLongitude(CLongitude longitude)
|
||||||
{
|
{
|
||||||
this->m_longitude = longitude;
|
this->m_longitude = longitude;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
#ifndef BLACKMISC_COORDINATENED_H
|
#ifndef BLACKMISC_COORDINATENED_H
|
||||||
#define BLACKMISC_COORDINATENED_H
|
#define BLACKMISC_COORDINATENED_H
|
||||||
#include "blackmisc/mathvector3dbase.h"
|
#include "blackmisc/mathvector3dbase.h"
|
||||||
|
#include "blackmisc/mathmatrix3x3.h"
|
||||||
|
#include "blackmisc/coordinategeodetic.h"
|
||||||
|
|
||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
{
|
{
|
||||||
@@ -16,19 +18,94 @@ namespace Geo
|
|||||||
*/
|
*/
|
||||||
class CCoordinateNed : public BlackMisc::Math::CVector3DBase<CCoordinateNed>
|
class CCoordinateNed : public BlackMisc::Math::CVector3DBase<CCoordinateNed>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
CCoordinateGeodetic m_referencePosition; //!< geodetic reference position
|
||||||
|
bool m_hasReferencePosition; //!< valid reference position?
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
* \brief Default constructor
|
* \brief Default constructor
|
||||||
*/
|
*/
|
||||||
CCoordinateNed() : CVector3DBase() {}
|
CCoordinateNed() : CVector3DBase(), m_hasReferencePosition(false) {}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructor with reference position
|
||||||
|
* \param referencePosition
|
||||||
|
*/
|
||||||
|
CCoordinateNed(const CCoordinateGeodetic &referencePosition) : CVector3DBase(), m_referencePosition(referencePosition), m_hasReferencePosition(true) {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Constructor by values
|
* \brief Constructor by values
|
||||||
|
* \param referencePosition
|
||||||
* \param north
|
* \param north
|
||||||
* \param east
|
* \param east
|
||||||
* \param down
|
* \param down
|
||||||
*/
|
*/
|
||||||
CCoordinateNed(qreal north, qreal east, qreal down) : CVector3DBase(north, east, down) {}
|
CCoordinateNed(const CCoordinateGeodetic &referencePosition, qreal north, qreal east, qreal down) : CVector3DBase(north, east, down), m_referencePosition(referencePosition), m_hasReferencePosition(true) {}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Copy constructor
|
||||||
|
* \param otherNed
|
||||||
|
*/
|
||||||
|
CCoordinateNed(const CCoordinateNed &otherNed) :
|
||||||
|
CVector3DBase(otherNed) , m_hasReferencePosition(otherNed.m_hasReferencePosition), m_referencePosition(otherNed.m_referencePosition) {}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Equal operator ==
|
||||||
|
* \param otherNed
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
bool operator ==(const CCoordinateNed &otherNed) const
|
||||||
|
{
|
||||||
|
if (this == &otherNed) return true;
|
||||||
|
return this->m_hasReferencePosition == otherNed.m_hasReferencePosition &&
|
||||||
|
this->m_referencePosition == otherNed.m_referencePosition &&
|
||||||
|
CVector3DBase::operator== (otherNed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Unequal operator !=
|
||||||
|
* \param otherNed
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
bool operator !=(const CCoordinateNed &otherNed) const
|
||||||
|
{
|
||||||
|
if (this == &otherNed) return false;
|
||||||
|
return !((*this) == otherNed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Assigment operator =
|
||||||
|
* \param otherNed
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
CCoordinateNed &operator =(const CCoordinateNed &otherNed)
|
||||||
|
{
|
||||||
|
if (this == &otherNed) return *this; // Same object?
|
||||||
|
CVector3DBase::operator = (otherNed);
|
||||||
|
this->m_hasReferencePosition = otherNed.m_hasReferencePosition;
|
||||||
|
this->m_referencePosition = otherNed.m_referencePosition;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Corresponding reference position
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
CCoordinateGeodetic referencePosition() const
|
||||||
|
{
|
||||||
|
return this->m_referencePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Corresponding reference position
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
bool hasReferencePosition() const
|
||||||
|
{
|
||||||
|
return this->m_hasReferencePosition;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief North
|
* \brief North
|
||||||
@@ -83,6 +160,17 @@ public:
|
|||||||
{
|
{
|
||||||
this->m_vector.setZ(down);
|
this->m_vector.setZ(down);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Corresponding reference position
|
||||||
|
* \param referencePosition
|
||||||
|
*/
|
||||||
|
void setReferencePosition(const CCoordinateGeodetic &referencePosition)
|
||||||
|
{
|
||||||
|
this->m_referencePosition = referencePosition;
|
||||||
|
this->m_hasReferencePosition = true;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
63
src/blackmisc/coordinatetransformation.cpp
Normal file
63
src/blackmisc/coordinatetransformation.cpp
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/* Copyright (C) 2013 VATSIM Community / authors
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "coordinatetransformation.h"
|
||||||
|
using namespace BlackMisc::PhysicalQuantities;
|
||||||
|
using namespace BlackMisc::Math;
|
||||||
|
|
||||||
|
namespace BlackMisc
|
||||||
|
{
|
||||||
|
namespace Geo
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NED to ECEF
|
||||||
|
*/
|
||||||
|
CCoordinateEcef CCoordinateTransformation::toEcef(const CCoordinateNed &ned)
|
||||||
|
{
|
||||||
|
CLatitude lat = ned.referencePosition().latitude();
|
||||||
|
lat.switchUnit(CAngleUnit::rad());
|
||||||
|
CLongitude lon = ned.referencePosition().longitude();
|
||||||
|
lon.switchUnit(CAngleUnit::rad());
|
||||||
|
|
||||||
|
double angleRad = - (lat.unitValueToDouble()) - BlackMisc::Math::PI / 2;
|
||||||
|
CMatrix3x3 dcm1;
|
||||||
|
CMatrix3x3 dcm2;
|
||||||
|
CMatrix3x3 dcm3;
|
||||||
|
CMatrix3x3 dcm;
|
||||||
|
CMatrix3x3 invDcm;
|
||||||
|
dcm1.setToIdentity();
|
||||||
|
dcm2.setZero();
|
||||||
|
dcm3.setZero();
|
||||||
|
|
||||||
|
dcm2(0, 0) = cos(angleRad);
|
||||||
|
dcm2(0, 2) = -sin(angleRad);
|
||||||
|
dcm2(1, 1) = 1;
|
||||||
|
dcm2(2, 0) = sin(angleRad);
|
||||||
|
dcm2(2, 2) = cos(angleRad);
|
||||||
|
|
||||||
|
angleRad = lon.unitValueToDouble();
|
||||||
|
|
||||||
|
dcm3(0, 0) = cos(angleRad);
|
||||||
|
dcm3(0, 1) = sin(angleRad);
|
||||||
|
dcm3(1, 0) = -sin(angleRad);
|
||||||
|
dcm3(1, 1) = cos(angleRad);
|
||||||
|
dcm3(2, 2) = 1;
|
||||||
|
|
||||||
|
dcm = dcm1 * dcm2 * dcm3;
|
||||||
|
|
||||||
|
invDcm.setZero();
|
||||||
|
invDcm = dcm.inverse();
|
||||||
|
|
||||||
|
CCoordinateNed tempResult(ned);
|
||||||
|
tempResult.matrixMultiplication(invDcm);
|
||||||
|
CCoordinateEcef result(tempResult.north(), tempResult.east(), tempResult.down());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace
|
||||||
44
src/blackmisc/coordinatetransformation.h
Normal file
44
src/blackmisc/coordinatetransformation.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/* Copyright (C) 2013 VATSIM Community / authors
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef BLACKMISC_COORDINATETRANSFORMATION_H
|
||||||
|
#define BLACKMISC_COORDINATETRANSFORMATION_H
|
||||||
|
|
||||||
|
#include "blackmisc/coordinateecef.h"
|
||||||
|
#include "blackmisc/coordinatened.h"
|
||||||
|
#include "blackmisc/coordinategeodetic.h"
|
||||||
|
#include "blackmisc/mathmatrix3x3.h"
|
||||||
|
#include "blackmisc/mathematics.h"
|
||||||
|
|
||||||
|
namespace BlackMisc
|
||||||
|
{
|
||||||
|
namespace Geo
|
||||||
|
{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Coordinate transformation class between different systems
|
||||||
|
*/
|
||||||
|
class CCoordinateTransformation
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/*!
|
||||||
|
* \brief Default constructor, avoid object instantiation
|
||||||
|
*/
|
||||||
|
CCoordinateTransformation() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* \brief NED to ECEF
|
||||||
|
* \param ned
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
static CCoordinateEcef toEcef(const CCoordinateNed &ned);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif // guard
|
||||||
@@ -14,33 +14,33 @@ namespace Geo
|
|||||||
/*!
|
/*!
|
||||||
* \brief Base class for latitude / longitude
|
* \brief Base class for latitude / longitude
|
||||||
*/
|
*/
|
||||||
template <class LATorLON> class CGeoEarthAngle : public BlackMisc::PhysicalQuantities::CAngle
|
template <class LATorLON> class CEarthAngle : public BlackMisc::PhysicalQuantities::CAngle
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/*!
|
/*!
|
||||||
* \brief Default constructor
|
* \brief Default constructor
|
||||||
*/
|
*/
|
||||||
CGeoEarthAngle() : CAngle() {}
|
CEarthAngle() : CAngle() {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Copy constructor
|
* \brief Copy constructor
|
||||||
* \param latOrLon
|
* \param latOrLon
|
||||||
*/
|
*/
|
||||||
CGeoEarthAngle(const LATorLON &latOrLon) : CAngle(latOrLon) { }
|
CEarthAngle(const LATorLON &latOrLon) : CAngle(latOrLon) { }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Init by double value
|
* \brief Init by double value
|
||||||
* \param value
|
* \param value
|
||||||
* \param unit
|
* \param unit
|
||||||
*/
|
*/
|
||||||
CGeoEarthAngle(double value, const BlackMisc::PhysicalQuantities::CAngleUnit &unit): CAngle(value, unit) {}
|
CEarthAngle(double value, const BlackMisc::PhysicalQuantities::CAngleUnit &unit): CAngle(value, unit) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Virtual destructor
|
* \brief Virtual destructor
|
||||||
*/
|
*/
|
||||||
virtual ~CGeoEarthAngle() {}
|
virtual ~CEarthAngle() {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Equal operator ==
|
* \brief Equal operator ==
|
||||||
@@ -67,7 +67,7 @@ public:
|
|||||||
* \param latOrLon
|
* \param latOrLon
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
CGeoEarthAngle &operator +=(const CGeoEarthAngle &latOrLon)
|
CEarthAngle &operator +=(const CEarthAngle &latOrLon)
|
||||||
{
|
{
|
||||||
CAngle::operator +=(latOrLon);
|
CAngle::operator +=(latOrLon);
|
||||||
return (*this);
|
return (*this);
|
||||||
@@ -78,7 +78,7 @@ public:
|
|||||||
* \param latOrLon
|
* \param latOrLon
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
CGeoEarthAngle &operator -=(const CGeoEarthAngle &latOrLon)
|
CEarthAngle &operator -=(const CEarthAngle &latOrLon)
|
||||||
{
|
{
|
||||||
CAngle::operator -=(latOrLon);
|
CAngle::operator -=(latOrLon);
|
||||||
return (*this);
|
return (*this);
|
||||||
@@ -129,7 +129,7 @@ public:
|
|||||||
* \param latOrLon
|
* \param latOrLon
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
CGeoEarthAngle &operator =(const LATorLON &latOrLon)
|
CEarthAngle &operator =(const LATorLON &latOrLon)
|
||||||
{
|
{
|
||||||
CAngle::operator =(latOrLon);
|
CAngle::operator =(latOrLon);
|
||||||
return (*this);
|
return (*this);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Geo
|
|||||||
/*!
|
/*!
|
||||||
* \brief Latitude
|
* \brief Latitude
|
||||||
*/
|
*/
|
||||||
class CGeoLatitude : public CGeoEarthAngle<CGeoLatitude>
|
class CLatitude : public CEarthAngle<CLatitude>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/*!
|
/*!
|
||||||
@@ -19,32 +19,32 @@ protected:
|
|||||||
virtual QString stringForConverter() const
|
virtual QString stringForConverter() const
|
||||||
{
|
{
|
||||||
QString s = "latitude ";
|
QString s = "latitude ";
|
||||||
return s.append(CGeoEarthAngle::stringForConverter());
|
return s.append(CEarthAngle::stringForConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
* \brief Default constructor
|
* \brief Default constructor
|
||||||
*/
|
*/
|
||||||
CGeoLatitude() : CGeoEarthAngle() {}
|
CLatitude() : CEarthAngle() {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Copy constructor
|
* \brief Copy constructor
|
||||||
* \param latitude
|
* \param latitude
|
||||||
*/
|
*/
|
||||||
CGeoLatitude(const CGeoLatitude &latitude) : CGeoEarthAngle(latitude) {}
|
CLatitude(const CLatitude &latitude) : CEarthAngle(latitude) {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Init by double value
|
* \brief Init by double value
|
||||||
* \param value
|
* \param value
|
||||||
* \param unit
|
* \param unit
|
||||||
*/
|
*/
|
||||||
CGeoLatitude(double value, const BlackMisc::PhysicalQuantities::CAngleUnit &unit): CGeoEarthAngle(value, unit) {}
|
CLatitude(double value, const BlackMisc::PhysicalQuantities::CAngleUnit &unit): CEarthAngle(value, unit) {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Virtual destructor
|
* \brief Virtual destructor
|
||||||
*/
|
*/
|
||||||
virtual ~CGeoLatitude() {}
|
virtual ~CLatitude() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace Geo
|
|||||||
/*!
|
/*!
|
||||||
* \brief Longitude
|
* \brief Longitude
|
||||||
*/
|
*/
|
||||||
class CGeoLongitude : public CGeoEarthAngle<CGeoLongitude>
|
class CLongitude : public CEarthAngle<CLongitude>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/*!
|
/*!
|
||||||
@@ -19,32 +19,32 @@ protected:
|
|||||||
virtual QString stringForConverter() const
|
virtual QString stringForConverter() const
|
||||||
{
|
{
|
||||||
QString s = "longitude ";
|
QString s = "longitude ";
|
||||||
return s.append(CGeoEarthAngle::stringForConverter());
|
return s.append(CEarthAngle::stringForConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
* \brief Default constructor
|
* \brief Default constructor
|
||||||
*/
|
*/
|
||||||
CGeoLongitude() : CGeoEarthAngle() {}
|
CLongitude() : CEarthAngle() {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Copy constructor
|
* \brief Copy constructor
|
||||||
* \param Longitude
|
* \param Longitude
|
||||||
*/
|
*/
|
||||||
CGeoLongitude(const CGeoLongitude &Longitude) : CGeoEarthAngle(Longitude) {}
|
CLongitude(const CLongitude &Longitude) : CEarthAngle(Longitude) {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Init by double value
|
* \brief Init by double value
|
||||||
* \param value
|
* \param value
|
||||||
* \param unit
|
* \param unit
|
||||||
*/
|
*/
|
||||||
CGeoLongitude(double value, const BlackMisc::PhysicalQuantities::CAngleUnit &unit): CGeoEarthAngle(value, unit) {}
|
CLongitude(double value, const BlackMisc::PhysicalQuantities::CAngleUnit &unit): CEarthAngle(value, unit) {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Virtual destructor
|
* \brief Virtual destructor
|
||||||
*/
|
*/
|
||||||
virtual ~CGeoLongitude() {}
|
virtual ~CLongitude() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Math
|
|||||||
/*
|
/*
|
||||||
* Hypotenuse
|
* Hypotenuse
|
||||||
*/
|
*/
|
||||||
double CMath::hypot(double x, double y)
|
qreal CMath::hypot(qreal x, qreal y)
|
||||||
{
|
{
|
||||||
x = abs(x);
|
x = abs(x);
|
||||||
y = abs(y);
|
y = abs(y);
|
||||||
@@ -27,7 +27,7 @@ double CMath::hypot(double x, double y)
|
|||||||
/*
|
/*
|
||||||
* Real part of cubic root
|
* Real part of cubic root
|
||||||
*/
|
*/
|
||||||
double CMath::cubicRootReal(const double x)
|
qreal CMath::cubicRootReal(qreal x)
|
||||||
{
|
{
|
||||||
double result;
|
double result;
|
||||||
result = std::pow(std::abs(x), (double)1 / 3);
|
result = std::pow(std::abs(x), (double)1 / 3);
|
||||||
|
|||||||
@@ -5,32 +5,42 @@
|
|||||||
|
|
||||||
#ifndef BLACKMISC_MATHEMATICS_H
|
#ifndef BLACKMISC_MATHEMATICS_H
|
||||||
#define BLACKMISC_MATHEMATICS_H
|
#define BLACKMISC_MATHEMATICS_H
|
||||||
|
#include <QtCore/qmath.h>
|
||||||
|
|
||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
{
|
{
|
||||||
namespace Math
|
namespace Math
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Some namespace wide constant values
|
||||||
|
|
||||||
|
//! Mathematical constant Pi
|
||||||
|
const qreal PI = 4.0 * qAtan(1.0);
|
||||||
|
|
||||||
|
//! 2 * Pi
|
||||||
|
const qreal TwoPI = 2.0 * PI;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Math utils
|
* \brief Math utils
|
||||||
*/
|
*/
|
||||||
class CMath
|
class CMath
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Calculates the hypotenuse of x and y without overflow
|
* \brief Calculates the hypotenuse of x and y without overflow
|
||||||
* \param x
|
* \param x
|
||||||
* \param y
|
* \param y
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
static double hypot(double x, double y);
|
static qreal hypot(qreal x, qreal y);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Calculates the square of x
|
* \brief Calculates the square of x
|
||||||
* \param x
|
* \param x
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
static inline double square(const double x)
|
static inline qreal square(qreal x)
|
||||||
{
|
{
|
||||||
return x * x;
|
return x * x;
|
||||||
}
|
}
|
||||||
@@ -40,7 +50,7 @@ public:
|
|||||||
* \param x
|
* \param x
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
static inline double cubic(const double x)
|
static inline qreal cubic(const qreal x)
|
||||||
{
|
{
|
||||||
return x * x * x;
|
return x * x * x;
|
||||||
}
|
}
|
||||||
@@ -50,7 +60,7 @@ public:
|
|||||||
* \param x
|
* \param x
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
static double cubicRootReal(const double x);
|
static qreal cubicRootReal(qreal x);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*!
|
/*!
|
||||||
|
|||||||
58
src/blackmisc/mathmatrix1x3.h
Normal file
58
src/blackmisc/mathmatrix1x3.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/* Copyright (C) 2013 VATSIM Community / authors
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef BLACKMISC_POSMATRIX1x3_H
|
||||||
|
#define BLACKMISC_POSMATRIX1x3_H
|
||||||
|
|
||||||
|
#include "blackmisc/mathmatrixbase.h"
|
||||||
|
#include "blackmisc/mathvector3d.h"
|
||||||
|
|
||||||
|
namespace BlackMisc
|
||||||
|
{
|
||||||
|
namespace Math
|
||||||
|
{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief 3D matrix
|
||||||
|
*/
|
||||||
|
class CMatrix1x3 : public CMatrixBase<CMatrix1x3, 1, 3>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* \brief Matrix 1x3
|
||||||
|
*/
|
||||||
|
CMatrix1x3() : CMatrixBase() {}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief init with value
|
||||||
|
* \param fillValue
|
||||||
|
*/
|
||||||
|
CMatrix1x3(qreal fillValue) : CMatrixBase(fillValue) {}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Copy constructor
|
||||||
|
* \param other
|
||||||
|
*/
|
||||||
|
CMatrix1x3(const CMatrix1x3 &otherMatrix) : CMatrixBase(otherMatrix) {}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief CMatrix 3x1
|
||||||
|
* \param c1
|
||||||
|
* \param c2
|
||||||
|
* \param c3
|
||||||
|
*/
|
||||||
|
CMatrix1x3(qreal c1, qreal c2, qreal c3) : CMatrixBase()
|
||||||
|
{
|
||||||
|
this->m_matrix(0, 0) = c1;
|
||||||
|
this->m_matrix(0, 1) = c2;
|
||||||
|
this->m_matrix(0, 2) = c3;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
#endif // guard
|
||||||
@@ -15,16 +15,31 @@ namespace Math
|
|||||||
{
|
{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief 3D matrix
|
* \brief Matrix 3x1
|
||||||
*/
|
*/
|
||||||
class CMatrix3x1 : public CMatrixBase<CMatrix3x1, 3, 1>
|
class CMatrix3x1 : public CMatrixBase<CMatrix3x1, 3, 1>
|
||||||
{
|
{
|
||||||
|
friend class CMatrix3x3; // for matrix multiplicaion to access m_matrix
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*!
|
/*!
|
||||||
* \brief CMatrix3D
|
* \brief CMatrix 3x1
|
||||||
*/
|
*/
|
||||||
CMatrix3x1() : CMatrixBase() {}
|
CMatrix3x1() : CMatrixBase() {}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief CMatrix 3x1
|
||||||
|
* \param r1
|
||||||
|
* \param r2
|
||||||
|
* \param r3
|
||||||
|
*/
|
||||||
|
CMatrix3x1(qreal r1, qreal r2, qreal r3) : CMatrixBase()
|
||||||
|
{
|
||||||
|
this->m_matrix(0, 0) = r1;
|
||||||
|
this->m_matrix(1, 0) = r2;
|
||||||
|
this->m_matrix(2, 0) = r3;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief init with value
|
* \brief init with value
|
||||||
* \param fillValue
|
* \param fillValue
|
||||||
@@ -52,9 +67,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void fromVector3D(const CVector3D &vector)
|
void fromVector3D(const CVector3D &vector)
|
||||||
{
|
{
|
||||||
this->m_matrix[0][0] = vector.x();
|
this->m_matrix(0, 0) = vector.i();
|
||||||
this->m_matrix[1][0] = vector.y();
|
this->m_matrix(1, 0) = vector.j();
|
||||||
this->m_matrix[2][0] = vector.z();
|
this->m_matrix(2, 0) = vector.k();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,30 @@ CMatrix3x3 CMatrix3x3::inverse() const
|
|||||||
return inverse;
|
return inverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a row
|
||||||
|
*/
|
||||||
|
CMatrix1x3 CMatrix3x3::getRow(int row) const
|
||||||
|
{
|
||||||
|
bool valid = row >= 0 && row <= 3;
|
||||||
|
Q_ASSERT_X(valid, "getRow", "invalid row");
|
||||||
|
if (!valid) throw new std::range_error("invalid row");
|
||||||
|
return CMatrix1x3(this->getElement(row, 0), this->getElement(row, 1), this->getElement(row, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a column
|
||||||
|
*/
|
||||||
|
CMatrix3x1 CMatrix3x3::getColumn(int column) const
|
||||||
|
{
|
||||||
|
bool valid = column >= 0 && column <= 3;
|
||||||
|
Q_ASSERT_X(valid, "getColumn", "invalid column");
|
||||||
|
if (!valid) throw new std::range_error("invalid column");
|
||||||
|
return CMatrix3x1(this->getElement(0, column), this->getElement(1, column), this->getElement(2, column));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
#ifndef BLACKMISC_POSMATRIX3X3_H
|
#ifndef BLACKMISC_POSMATRIX3X3_H
|
||||||
#define BLACKMISC_POSMATRIX3X3_H
|
#define BLACKMISC_POSMATRIX3X3_H
|
||||||
|
#include "blackmisc/mathmatrix1x3.h"
|
||||||
#include "blackmisc/mathmatrixbase.h"
|
#include "blackmisc/mathmatrix3x1.h"
|
||||||
|
|
||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
{
|
{
|
||||||
@@ -14,7 +14,7 @@ namespace Math
|
|||||||
{
|
{
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief 3x1 matrix
|
* \brief 3x3 matrix
|
||||||
*/
|
*/
|
||||||
class CMatrix3x3 : public CMatrixBase<CMatrix3x3, 3, 3>
|
class CMatrix3x3 : public CMatrixBase<CMatrix3x3, 3, 3>
|
||||||
{
|
{
|
||||||
@@ -48,6 +48,66 @@ public:
|
|||||||
*/
|
*/
|
||||||
CMatrix3x3 inverse() const;
|
CMatrix3x3 inverse() const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Operator *=
|
||||||
|
* \param otherMatrix
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
CMatrix3x3 &operator *=(const CMatrix3x3 &otherMatrix)
|
||||||
|
{
|
||||||
|
this->m_matrix = this->m_matrix * otherMatrix.m_matrix;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Operator *
|
||||||
|
* \param otherMatrix
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
CMatrix3x1 operator *(const CMatrix3x1 &otherMatrix) const
|
||||||
|
{
|
||||||
|
CMatrix3x1 m;
|
||||||
|
m.m_matrix = this->m_matrix * otherMatrix.m_matrix;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Operator *
|
||||||
|
* \param multiply
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
CMatrix3x3 operator *(const CMatrix3x3 &otherMatrix) const
|
||||||
|
{
|
||||||
|
CMatrix3x3 m(otherMatrix);
|
||||||
|
m *= otherMatrix;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Transposed matrix
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
CMatrix3x3 transposed() const
|
||||||
|
{
|
||||||
|
CMatrix3x3 m(0.0);
|
||||||
|
m.m_matrix = this->m_matrix.transposed();
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get column
|
||||||
|
* \param column
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
CMatrix3x1 getColumn(int column) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get row
|
||||||
|
* \param column
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
CMatrix1x3 getRow(int column) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -14,12 +14,29 @@ namespace Math
|
|||||||
/*
|
/*
|
||||||
* Get element by column / row
|
* Get element by column / row
|
||||||
*/
|
*/
|
||||||
template<class ImplMatrix, int Rows, int Columns> double CMatrixBase<ImplMatrix, Rows, Columns>::getElement(size_t row, size_t column) const
|
template<class ImplMatrix, int Rows, int Columns> qreal CMatrixBase<ImplMatrix, Rows, Columns>::getElement(size_t row, size_t column) const
|
||||||
|
{
|
||||||
|
this->checkRange(row, column);
|
||||||
|
return this->m_matrix(row, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set element by column / row
|
||||||
|
*/
|
||||||
|
template<class ImplMatrix, int Rows, int Columns> void CMatrixBase<ImplMatrix, Rows, Columns>::setElement(size_t row, size_t column, qreal value)
|
||||||
|
{
|
||||||
|
this->checkRange(row, column);
|
||||||
|
this->m_matrix(row, column) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check range
|
||||||
|
*/
|
||||||
|
template<class ImplMatrix, int Rows, int Columns> void CMatrixBase<ImplMatrix, Rows, Columns>::checkRange(size_t row, size_t column) const
|
||||||
{
|
{
|
||||||
bool valid = (row >= 0 && column >= 0 && row < Rows && column < Columns);
|
bool valid = (row >= 0 && column >= 0 && row < Rows && column < Columns);
|
||||||
Q_ASSERT_X(valid, "getElement()", "Row or column invalid");
|
Q_ASSERT_X(valid, "getElement()", "Row or column invalid");
|
||||||
std::range_error("Row or column invalid");
|
if (!valid) throw std::range_error("Row or column invalid");
|
||||||
return this->m_matrix(row, column);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -57,11 +74,11 @@ template <class ImplMatrix, int Rows, int Columns> QString CMatrixBase<ImplMatri
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// see here for the reason of thess forward instantiations
|
// see here for the reason of thess forward instantiations
|
||||||
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
||||||
template class CMatrixBase<CMatrix3x3, 3, 3>;
|
template class CMatrixBase<CMatrix3x3, 3, 3>;
|
||||||
template class CMatrixBase<CMatrix3x1, 3, 1>;
|
template class CMatrixBase<CMatrix3x1, 3, 1>;
|
||||||
|
template class CMatrixBase<CMatrix1x3, 1, 3>;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#define BLACKMISC_MATHMATRIXBASE_H
|
#define BLACKMISC_MATHMATRIXBASE_H
|
||||||
|
|
||||||
#include "blackmisc/basestreamstringifier.h"
|
#include "blackmisc/basestreamstringifier.h"
|
||||||
|
#include "blackmisc/mathvector3dbase.h"
|
||||||
#include <QGenericMatrix>
|
#include <QGenericMatrix>
|
||||||
|
|
||||||
namespace BlackMisc
|
namespace BlackMisc
|
||||||
@@ -17,11 +18,12 @@ namespace Math
|
|||||||
/*!
|
/*!
|
||||||
* \brief Base functionality of a matrix
|
* \brief Base functionality of a matrix
|
||||||
*/
|
*/
|
||||||
template<class ImplMatrix, int Rows, int Columns> class CMatrixBase :
|
template<class ImplMatrix, int Rows, int Columns> class CMatrixBase : public BlackMisc::CBaseStreamStringifier<ImplMatrix>
|
||||||
public BlackMisc::CBaseStreamStringifier<ImplMatrix>
|
|
||||||
{
|
{
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QGenericMatrix<Rows, Columns, qreal> m_matrix; //!< backing data
|
// no bug, Qt expects columns rows
|
||||||
|
QGenericMatrix<Columns, Rows, qreal> m_matrix; //!< backing data
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Conversion to string
|
* \brief Conversion to string
|
||||||
@@ -72,7 +74,6 @@ public:
|
|||||||
{
|
{
|
||||||
if (this == &otherMatrix) return false;
|
if (this == &otherMatrix) return false;
|
||||||
return !((*this) == otherMatrix);
|
return !((*this) == otherMatrix);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -87,30 +88,6 @@ public:
|
|||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Operator *=
|
|
||||||
* \param multiply
|
|
||||||
* \return
|
|
||||||
*/
|
|
||||||
CMatrixBase &operator *=(const CMatrixBase &otherMatrix)
|
|
||||||
{
|
|
||||||
this->m_matrix = this->m_matrix * otherMatrix.m_matrix;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Operator *
|
|
||||||
* \param multiply
|
|
||||||
* \return
|
|
||||||
*/
|
|
||||||
ImplMatrix operator *(const ImplMatrix &otherMatrix) const
|
|
||||||
{
|
|
||||||
ImplMatrix m(0.0);
|
|
||||||
m += (*this);
|
|
||||||
m *= otherMatrix;
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Operator *=
|
* \brief Operator *=
|
||||||
* \param factor
|
* \param factor
|
||||||
@@ -135,6 +112,13 @@ public:
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Multiply with 3D vector operator *
|
||||||
|
* \param vector
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
template<class ImplVector> ImplVector operator*(const ImplVector vector) const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Operator /=
|
* \brief Operator /=
|
||||||
* \param factor
|
* \param factor
|
||||||
@@ -207,17 +191,6 @@ public:
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Transposed matrix
|
|
||||||
* \return
|
|
||||||
*/
|
|
||||||
ImplMatrix transposed() const
|
|
||||||
{
|
|
||||||
ImplMatrix m(0.0);
|
|
||||||
m.m_matrix = this->m_matrix.transposed();
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Is identity matrix?
|
* \brief Is identity matrix?
|
||||||
* \return
|
* \return
|
||||||
@@ -255,9 +228,49 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
* \brief Get element
|
* \brief Get element
|
||||||
* \param row
|
* \param row
|
||||||
|
* \param column
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
double getElement(size_t row, size_t column) const;
|
qreal getElement(size_t row, size_t column) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get element
|
||||||
|
* \param row
|
||||||
|
* \param column
|
||||||
|
* \param value
|
||||||
|
*/
|
||||||
|
void setElement(size_t row, size_t column, qreal value);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get element by ()
|
||||||
|
* \param column
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
qreal &operator()(size_t row, size_t column)
|
||||||
|
{
|
||||||
|
this->checkRange(row, column);
|
||||||
|
return this->m_matrix(row, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get element by ()
|
||||||
|
* \param column
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
qreal operator()(size_t row, size_t column) const
|
||||||
|
{
|
||||||
|
return this->getElement(row, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*!
|
||||||
|
* \brief Check range of row / column
|
||||||
|
* \param row
|
||||||
|
* \param column
|
||||||
|
* \throws std::range_error if index out of bounds
|
||||||
|
*/
|
||||||
|
void checkRange(size_t row, size_t column) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
* 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/mathvector3dbase.h"
|
|
||||||
#include "blackmisc/mathvector3d.h"
|
#include "blackmisc/mathvector3d.h"
|
||||||
|
#include "blackmisc/mathmatrix3x3.h"
|
||||||
#include "blackmisc/coordinateecef.h"
|
#include "blackmisc/coordinateecef.h"
|
||||||
#include "blackmisc/coordinatened.h"
|
#include "blackmisc/coordinatened.h"
|
||||||
|
|
||||||
@@ -46,10 +46,7 @@ template <class ImplClass> void CVector3DBase<ImplClass>::fill(qreal value)
|
|||||||
*/
|
*/
|
||||||
template <class ImplClass> qreal CVector3DBase<ImplClass>::getElement(size_t row) const
|
template <class ImplClass> qreal CVector3DBase<ImplClass>::getElement(size_t row) const
|
||||||
{
|
{
|
||||||
bool validIndex = (row < 3 && row >= 0);
|
qreal d;
|
||||||
Q_ASSERT_X(validIndex, "getElement", "Wrong index");
|
|
||||||
if (!validIndex) throw std::range_error("Invalid index vor 3D vector");
|
|
||||||
double d;
|
|
||||||
switch (row)
|
switch (row)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@@ -69,6 +66,48 @@ template <class ImplClass> qreal CVector3DBase<ImplClass>::getElement(size_t row
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set given element
|
||||||
|
*/
|
||||||
|
template <class ImplClass> void CVector3DBase<ImplClass>::setElement(size_t row, qreal value)
|
||||||
|
{
|
||||||
|
switch (row)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
this->m_vector.setX(value);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
this->m_vector.setY(value);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this->m_vector.setZ(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Q_ASSERT_X(true, "setElement", "Detected invalid index in 3D vector");
|
||||||
|
throw std::range_error("Detected invalid index in 3D vector");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Multiply with matrix
|
||||||
|
*/
|
||||||
|
template <class ImplClass> void CVector3DBase<ImplClass>::matrixMultiplication(const CMatrix3x3 &matrix)
|
||||||
|
{
|
||||||
|
CMatrix3x1 m = matrix * (this->toMatrix3x1());
|
||||||
|
this->m_vector.setX(m(0,0));
|
||||||
|
this->m_vector.setY(m(1,0));
|
||||||
|
this->m_vector.setZ(m(2,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert to matrix
|
||||||
|
*/
|
||||||
|
template <class ImplClass> CMatrix3x1 CVector3DBase<ImplClass>::toMatrix3x1() const
|
||||||
|
{
|
||||||
|
return CMatrix3x1(this->m_vector.x(), this->m_vector.y(), this->m_vector.z());
|
||||||
|
}
|
||||||
|
|
||||||
// see here for the reason of thess forward instantiations
|
// see here for the reason of thess forward instantiations
|
||||||
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
// http://www.parashift.com/c++-faq/separate-template-class-defn-from-decl.html
|
||||||
template class CVector3DBase<CVector3D>;
|
template class CVector3DBase<CVector3D>;
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ namespace BlackMisc
|
|||||||
namespace Math
|
namespace Math
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class CMatrix3x3; // forward declaration
|
||||||
|
class CMatrix3x1; // forward declaration
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief 3D vector base (x, y, z)
|
* \brief 3D vector base (x, y, z)
|
||||||
*/
|
*/
|
||||||
@@ -75,6 +79,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
qreal getElement(size_t row) const;
|
qreal getElement(size_t row) const;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Set element
|
||||||
|
* \param row
|
||||||
|
* \param value
|
||||||
|
*/
|
||||||
|
void setElement(size_t row, qreal value);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Operator []
|
* \brief Operator []
|
||||||
* \param row
|
* \param row
|
||||||
@@ -82,6 +93,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
qreal operator[](size_t row) const { return this->getElement(row); }
|
qreal operator[](size_t row) const { return this->getElement(row); }
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get element by ()
|
||||||
|
* \param column
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
qreal operator()(size_t row) const { return this->getElement(row); }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Equal operator ==
|
* \brief Equal operator ==
|
||||||
* \param otherVector
|
* \param otherVector
|
||||||
@@ -106,7 +125,7 @@ public:
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Assigment operator =
|
* \brief Assigment operator =
|
||||||
* \param multiply
|
* \param otherVector
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
CVector3DBase &operator =(const CVector3DBase &otherVector)
|
CVector3DBase &operator =(const CVector3DBase &otherVector)
|
||||||
@@ -165,7 +184,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Operator *=, just x*x, y*y, z*z neither vector nor dot product
|
* \brief Operator *=, just x*x, y*y, z*z neither vector nor dot product (like a matrix produc)
|
||||||
* \param otherVector
|
* \param otherVector
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
@@ -176,7 +195,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Operator, just x*x, y*y, z*z neither vector nor dot product
|
* \brief Operator, just x*x, y*y, z*z neither vector nor dot product, (like a matrix produc)
|
||||||
* \param otherVector
|
* \param otherVector
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
@@ -223,7 +242,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Dot product
|
* \brief Cross product
|
||||||
* \param otherVector
|
* \param otherVector
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
@@ -235,7 +254,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Dot product
|
* \brief Matrix * this vector
|
||||||
|
* \param matrix
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
void matrixMultiplication(const CMatrix3x3 &matrix);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Reciporcal value
|
||||||
* \param otherVector
|
* \param otherVector
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
@@ -266,6 +292,12 @@ public:
|
|||||||
return this->m_vector.lengthSquared();
|
return this->m_vector.lengthSquared();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Converted to matrix
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
CMatrix3x1 toMatrix3x1() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Magnitude
|
* \brief Magnitude
|
||||||
* \return
|
* \return
|
||||||
|
|||||||
@@ -57,16 +57,22 @@ template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::operator ==(const
|
|||||||
// some special cases for best quality
|
// some special cases for best quality
|
||||||
double diff;
|
double diff;
|
||||||
const double lenient = 1.001; // even diff already has a rounding issue to be avoided
|
const double lenient = 1.001; // even diff already has a rounding issue to be avoided
|
||||||
if (this->m_unit == otherQuantity.m_unit) {
|
if (this->m_unit == otherQuantity.m_unit)
|
||||||
|
{
|
||||||
// same unit
|
// same unit
|
||||||
if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue) {
|
if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue)
|
||||||
|
{
|
||||||
// pure integer comparison, no rounding issues
|
// pure integer comparison, no rounding issues
|
||||||
return this->m_unitValueI == otherQuantity.m_unitValueI;
|
return this->m_unitValueI == otherQuantity.m_unitValueI;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
diff = abs(this->m_unitValueD - otherQuantity.m_unitValueD);
|
diff = abs(this->m_unitValueD - otherQuantity.m_unitValueD);
|
||||||
return diff <= (lenient * this->m_unit.getEpsilon());
|
return diff <= (lenient * this->m_unit.getEpsilon());
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// based on SI value
|
// based on SI value
|
||||||
diff = abs(this->m_convertedSiUnitValueD - otherQuantity.m_convertedSiUnitValueD);
|
diff = abs(this->m_convertedSiUnitValueD - otherQuantity.m_convertedSiUnitValueD);
|
||||||
return diff <= (lenient * this->m_unit.getEpsilon());
|
return diff <= (lenient * this->m_unit.getEpsilon());
|
||||||
@@ -105,15 +111,21 @@ 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> &otherQuantity)
|
template <class MU, class PQ> CPhysicalQuantity<MU, PQ> &CPhysicalQuantity<MU, PQ>::operator +=(const CPhysicalQuantity<MU, PQ> &otherQuantity)
|
||||||
{
|
{
|
||||||
if (this->m_unit == otherQuantity.m_unit) {
|
if (this->m_unit == otherQuantity.m_unit)
|
||||||
|
{
|
||||||
// same unit
|
// same unit
|
||||||
if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue) {
|
if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue)
|
||||||
|
{
|
||||||
// pure integer, no rounding issues
|
// pure integer, no rounding issues
|
||||||
this->setUnitValue(otherQuantity.m_unitValueI + this->m_unitValueI);
|
this->setUnitValue(otherQuantity.m_unitValueI + this->m_unitValueI);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
this->setUnitValue(otherQuantity.m_unitValueD + this->m_unitValueD);
|
this->setUnitValue(otherQuantity.m_unitValueD + this->m_unitValueD);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
double v = otherQuantity.value(this->m_unit);
|
double v = otherQuantity.value(this->m_unit);
|
||||||
this->setUnitValue(v + this->m_unitValueD);
|
this->setUnitValue(v + this->m_unitValueD);
|
||||||
}
|
}
|
||||||
@@ -152,15 +164,21 @@ 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> &otherQuantity)
|
template <class MU, class PQ> CPhysicalQuantity<MU, PQ> &CPhysicalQuantity<MU, PQ>::operator -=(const CPhysicalQuantity<MU, PQ> &otherQuantity)
|
||||||
{
|
{
|
||||||
if (this->m_unit == otherQuantity.m_unit) {
|
if (this->m_unit == otherQuantity.m_unit)
|
||||||
|
{
|
||||||
// same unit
|
// same unit
|
||||||
if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue) {
|
if (this->m_isIntegerBaseValue && otherQuantity.m_isIntegerBaseValue)
|
||||||
|
{
|
||||||
// pure integer, no rounding issues
|
// pure integer, no rounding issues
|
||||||
this->setUnitValue(otherQuantity.m_unitValueI - this->m_unitValueI);
|
this->setUnitValue(otherQuantity.m_unitValueI - this->m_unitValueI);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
this->setUnitValue(otherQuantity.m_unitValueD - this->m_unitValueD);
|
this->setUnitValue(otherQuantity.m_unitValueD - this->m_unitValueD);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
double v = otherQuantity.value(this->m_unit);
|
double v = otherQuantity.value(this->m_unit);
|
||||||
this->setUnitValue(v - this->m_unitValueD);
|
this->setUnitValue(v - this->m_unitValueD);
|
||||||
}
|
}
|
||||||
@@ -258,14 +276,13 @@ template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::operator <=(const
|
|||||||
/*
|
/*
|
||||||
* Switch to another unit
|
* Switch to another unit
|
||||||
*/
|
*/
|
||||||
template <class MU, class PQ> bool CPhysicalQuantity<MU, PQ>::switchUnit(const MU &newUnit)
|
template <class MU, class PQ> CPhysicalQuantity<MU, PQ> &CPhysicalQuantity<MU, PQ>::switchUnit(const MU &newUnit)
|
||||||
{
|
{
|
||||||
if (this->m_unit == newUnit) return true;
|
if (this->m_unit == newUnit) return *this;
|
||||||
if (this->m_unit.getType() != newUnit.getType()) return false; // not possible
|
|
||||||
double cf = this->m_unit.conversionToUnit(this->m_unitValueD, newUnit);
|
double cf = this->m_unit.conversionToUnit(this->m_unitValueD, newUnit);
|
||||||
this->m_unit = newUnit;
|
this->m_unit = newUnit;
|
||||||
this->setUnitValue(cf);
|
this->setUnitValue(cf);
|
||||||
return true;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public:
|
|||||||
* \param newUnit
|
* \param newUnit
|
||||||
* \return
|
* \return
|
||||||
*/
|
*/
|
||||||
bool switchUnit(const MU &newUnit);
|
CPhysicalQuantity &switchUnit(const MU &newUnit);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Value in SI base unit? Meter is an SI base unit, hertz not!
|
* \brief Value in SI base unit? Meter is an SI base unit, hertz not!
|
||||||
|
|||||||
Reference in New Issue
Block a user