mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-31 21:15:33 +08:00
258 lines
7.9 KiB
C++
258 lines
7.9 KiB
C++
/* Copyright (C) 2013
|
|
* swift project Community / Contributors
|
|
*
|
|
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
|
|
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
|
|
* including this file, may be copied, modified, propagated, or distributed except according to the terms
|
|
* contained in the LICENSE file.
|
|
*/
|
|
|
|
//! \file
|
|
|
|
#ifndef BLACKMISC_MATHVECTOR3DBASE_H
|
|
#define BLACKMISC_MATHVECTOR3DBASE_H
|
|
|
|
#include "blackmisc/valueobject.h"
|
|
#include "blackmisc/mathematics.h"
|
|
#include "blackmisc/blackmiscfreefunctions.h"
|
|
|
|
namespace BlackMisc
|
|
{
|
|
namespace Math { template <class> class CVector3DBase; }
|
|
|
|
//! \private
|
|
template <class ImplVector> struct CValueObjectPolicy<Math::CVector3DBase<ImplVector>> : public CValueObjectPolicy<>
|
|
{
|
|
using Equals = Policy::Equals::None;
|
|
using LessThan = Policy::LessThan::None;
|
|
using Hash = Policy::Hash::Own;
|
|
using Json = Policy::Json::Own;
|
|
};
|
|
|
|
namespace Math
|
|
{
|
|
class CMatrix3x1;
|
|
|
|
//! 3D vector base (x, y, z)
|
|
template <class ImplVector> class CVector3DBase : public CValueObject<CVector3DBase<ImplVector>>
|
|
{
|
|
public:
|
|
// getter and setters are implemented in the derived classes
|
|
// as they have different names (x, i, north)
|
|
|
|
//! Set zeros
|
|
void setZero();
|
|
|
|
//! Is zero?
|
|
bool isZero() const
|
|
{
|
|
return this->m_i == 0 && this->m_j == 0 && this->m_k == 0;
|
|
}
|
|
|
|
//! Is zero, epsilon considered.
|
|
bool isZeroEpsilon() const
|
|
{
|
|
ImplVector v;
|
|
v += *this;
|
|
v.round();
|
|
return v.isZero();
|
|
}
|
|
|
|
//! Set all elements the same
|
|
void fill(double value);
|
|
|
|
//! Get element
|
|
double getElement(int row) const;
|
|
|
|
//! Set element
|
|
void setElement(int row, double value);
|
|
|
|
//! Operator []
|
|
double operator[](int row) const { return this->getElement(row); }
|
|
|
|
//! Operator [], mutable reference
|
|
double &operator[](int row) { return this->getElement(row); }
|
|
|
|
//! Equal operator ==
|
|
bool operator ==(const CVector3DBase &other) const
|
|
{
|
|
if (this == &other) return true;
|
|
return
|
|
CMath::epsilonEqual(this->m_i, other.m_i, 1E-9) &&
|
|
CMath::epsilonEqual(this->m_j, other.m_j, 1E-9) &&
|
|
CMath::epsilonEqual(this->m_k, other.m_k, 1E-9);
|
|
}
|
|
|
|
//! Unequal operator !=
|
|
bool operator !=(const CVector3DBase &other) const
|
|
{
|
|
return !((*this) == other);
|
|
}
|
|
|
|
//! Operator +=
|
|
CVector3DBase &operator +=(const CVector3DBase &other)
|
|
{
|
|
this->m_i += other.m_i;
|
|
this->m_j += other.m_j;
|
|
this->m_k += other.m_k;
|
|
return *this;
|
|
}
|
|
|
|
//! Operator +
|
|
ImplVector operator +(const ImplVector &other) const
|
|
{
|
|
ImplVector v = *derived();
|
|
v += other;
|
|
return v;
|
|
}
|
|
|
|
//! Operator -=
|
|
CVector3DBase &operator -=(const CVector3DBase &other)
|
|
{
|
|
this->m_i -= other.m_i;
|
|
this->m_j -= other.m_j;
|
|
this->m_k -= other.m_k;
|
|
return *this;
|
|
}
|
|
|
|
//! Operator -
|
|
ImplVector operator -(const ImplVector &other) const
|
|
{
|
|
ImplVector v = *derived();
|
|
v -= other;
|
|
return v;
|
|
}
|
|
|
|
//! Multiply with scalar
|
|
CVector3DBase &operator *=(double factor)
|
|
{
|
|
this->m_i *= factor;
|
|
this->m_j *= factor;
|
|
this->m_k *= factor;
|
|
return *this;
|
|
}
|
|
|
|
//! Multiply with scalar
|
|
ImplVector operator *(double factor) const
|
|
{
|
|
ImplVector v = *derived();
|
|
v *= factor;
|
|
return v;
|
|
}
|
|
|
|
//! Operator to support commutative multiplication
|
|
friend ImplVector operator *(double factor, const ImplVector &other)
|
|
{
|
|
return other * factor;
|
|
}
|
|
|
|
//! Divide by scalar
|
|
CVector3DBase &operator /=(double divisor)
|
|
{
|
|
this->m_i /= divisor;
|
|
this->m_j /= divisor;
|
|
this->m_k /= divisor;
|
|
return *this;
|
|
}
|
|
|
|
//! Divide by scalar
|
|
ImplVector operator /(double divisor) const
|
|
{
|
|
ImplVector v = *derived();
|
|
v /= divisor;
|
|
return v;
|
|
}
|
|
|
|
//! Dot product
|
|
double dotProduct(const ImplVector &other) const;
|
|
|
|
//! Cross product
|
|
ImplVector crossProduct(const ImplVector &other) const;
|
|
|
|
//! Reciprocal value
|
|
ImplVector reciprocalValues() const
|
|
{
|
|
ImplVector v(1 / this->m_i, 1 / this->m_j, 1 / this->m_j);
|
|
return v;
|
|
}
|
|
|
|
//! Converted to matrix
|
|
CMatrix3x1 toMatrix3x1() const;
|
|
|
|
//! \copydoc CValueObject::getValueHash
|
|
virtual uint getValueHash() const override;
|
|
|
|
//! length / magnitude
|
|
double length() const
|
|
{
|
|
return sqrt(this->m_i * this->m_i + this->m_j * this->m_j + this->m_k * this->m_k);
|
|
}
|
|
|
|
//! Round this vector
|
|
void round()
|
|
{
|
|
const double epsilon = 1E-10;
|
|
this->m_i = BlackMisc::Math::CMath::roundEpsilon(this->m_i, epsilon);
|
|
this->m_j = BlackMisc::Math::CMath::roundEpsilon(this->m_j, epsilon);
|
|
this->m_k = BlackMisc::Math::CMath::roundEpsilon(this->m_k, epsilon);
|
|
}
|
|
|
|
//! Rounded vector
|
|
ImplVector rounded() const
|
|
{
|
|
ImplVector v = *derived();
|
|
v.round();
|
|
return v;
|
|
}
|
|
|
|
//! \copydoc CValueObject::toJson
|
|
virtual QJsonObject toJson() const override;
|
|
|
|
//! \copydoc CValueObject::convertFromJson
|
|
virtual void convertFromJson(const QJsonObject &json) override;
|
|
|
|
protected:
|
|
// using own value since Qt QVector3D stores internally as float
|
|
double m_i; //!< Vector data i
|
|
double m_j; //!< Vector data j
|
|
double m_k; //!< Vector data k
|
|
|
|
//! Default constructor
|
|
CVector3DBase() : m_i(0.0), m_j(0.0), m_k(0.0) {}
|
|
|
|
//! Constructor by values
|
|
CVector3DBase(double i, double j, double k) : m_i(i), m_j(j), m_k(k) {}
|
|
|
|
//! Constructor by value
|
|
explicit CVector3DBase(double value) : m_i(value), m_j(value), m_k(value) {}
|
|
|
|
//! Get mutable element
|
|
double &getElement(int row);
|
|
|
|
//! \copydoc CValueObject::convertToQString
|
|
virtual QString convertToQString(bool i18n = false) const override;
|
|
|
|
private:
|
|
BLACK_ENABLE_TUPLE_CONVERSION(CVector3DBase)
|
|
|
|
//! Easy access to derived class (CRTP template parameter)
|
|
ImplVector const *derived() const
|
|
{
|
|
return static_cast<ImplVector const *>(this);
|
|
}
|
|
|
|
//! Easy access to derived class (CRTP template parameter)
|
|
ImplVector *derived()
|
|
{
|
|
return static_cast<ImplVector *>(this);
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
BLACK_DECLARE_TUPLE_CONVERSION_TEMPLATE(BlackMisc::Math::CVector3DBase, (o.m_i, o.m_j, o.m_k))
|
|
|
|
#endif // guard
|