From 7b5555f63d2f6e23ce540ae3108d653873c3fce2 Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 21 Oct 2020 17:58:42 +0300 Subject: [PATCH 01/11] refactor pimathvector.h --- libs/main/math/pimathmatrix.h | 2 +- libs/main/math/pimathvector.h | 373 +++++++++++++++++++++++--------- libs/main/math/piquaternion.cpp | 4 +- 3 files changed, 272 insertions(+), 107 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 9dd8ee7c..645c9e22 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -1227,7 +1227,7 @@ public: ++crow; smat.swapRows(i, crow); mtmp.swapRows(i, crow); - if (sv != 0) sv->swap(i, crow); + if (sv != 0) sv->swapElements(i, crow); } for (uint j = i + 1; j < _V2D::rows_; ++j) { mul = smat.element(i, j) / smat.element(i, i); diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 09b8d07b..010b74e3 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -28,85 +28,151 @@ template class PIMathMatrixT; +#define PIMATHVECTOR_ZERO_CMP Type(1E-100) + /// Vector templated -#define PIMV_FOR(v, s) for (uint v = s; v < Size; ++v) +#define PIMV_FOR for (uint i = 0; i < Size; ++i) template class PIP_EXPORT PIMathVectorT { typedef PIMathVectorT _CVector; static_assert(std::is_arithmetic::value, "Type must be arithmetic"); - static_assert(Size > 0, "Size count must be > 0"); + static_assert(Size > 0, "Size must be > 0"); public: - PIMathVectorT() {resize();} - PIMathVectorT(const PIVector & val) {resize(); PIMV_FOR(i, 0) c[i] = val[i];} - PIMathVectorT(const _CVector & st, const _CVector & fn) {resize(); set(st, fn);} + PIMathVectorT(const Type & v = Type()) {PIMV_FOR c[i] = v;} + PIMathVectorT(const PIVector & val) { + assert(Size == val.size()); + PIMV_FOR c[i] = val[i]; + } + static _CVector fromTwoPoints(const _CVector & st, const _CVector & fn) { + _CVector tv; + PIMV_FOR tv[i] = fn[i] - st[i]; + return tv; + } uint size() const {return Size;} - _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} - _CVector & set(const _CVector & st, const _CVector & fn) {PIMV_FOR(i, 0) c[i] = fn[i] - st[i]; return *this;} - _CVector & move(const Type & v) {PIMV_FOR(i, 0) c[i] += v; return *this;} - _CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;} - Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += (c[i] * c[i]); return tv;} + _CVector & fill(const Type & v) {PIMV_FOR c[i] = v; return *this;} + _CVector & move(const Type & v) {PIMV_FOR c[i] += v; return *this;} + _CVector & move(const _CVector & v) {PIMV_FOR c[i] += v[i]; return *this;} + Type lengthSqr() const { + Type tv(0); + PIMV_FOR tv += c[i] * c[i]; + return tv; + } Type length() const {return sqrt(lengthSqr());} - Type manhattanLength() const {Type tv(0); PIMV_FOR(i, 0) tv += fabs(c[i]); return tv;} - Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);} - Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);} + Type manhattanLength() const { + Type tv(0); + PIMV_FOR tv += piAbs(c[i]); + return tv; + } + Type angleCos(const _CVector & v) const { + Type tv = v.length() * length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + return dot(v) / tv; + } + Type angleSin(const _CVector & v) const { + Type tv = angleCos(v); + return sqrt(Type(1) - tv * tv); + } Type angleRad(const _CVector & v) const {return acos(angleCos(v));} - Type angleDeg(const _CVector & v) const {return toDeg(acos(angleCos(v)));} - Type angleElevation(const _CVector & v) const {_CVector z = v - *this; double c = z.angleCos(*this); return 90.0 - acos(c) * rad2deg;} - _CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));} - _CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; if (piAbs(tv) <= Type(1E-100)) {fill(Type(0)); return *this;} PIMV_FOR(i, 0) c[i] /= tv; return *this;} + Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} + Type angleElevation(const _CVector & v) const {return 90.0 - angleDeg(v - *this);} + _CVector projection(const _CVector & v) { + Type tv = v.length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + return v * (dot(v) / tv); + } + _CVector & normalize() { + Type tv = length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + if (tv == Type(1)) return *this; + PIMV_FOR c[i] /= tv; + return *this; + } _CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;} - _CVector cross(const _CVector & v) {return (*this) * v;} - Type dot(const _CVector & v) const {return (*this) ^ v;} - bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;} + bool isNull() const {PIMV_FOR if (c[i] != Type(0)) return false; return true;} bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} Type & at(uint index) {return c[index];} Type at(uint index) const {return c[index];} Type & operator [](uint index) {return c[index];} Type operator [](uint index) const {return c[index];} - _CVector & operator =(const _CVector & v) {memcpy(c, v.c, sizeof(Type) * Size); return *this;} - _CVector & operator =(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} - bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;} + _CVector & operator =(const Type & v) {PIMV_FOR c[i] = v; return *this;} + bool operator ==(const _CVector & v) const {PIMV_FOR if (c[i] != v[i]) return false; return true;} bool operator !=(const _CVector & v) const {return !(*this == c);} - void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];} - void operator -=(const _CVector & v) {PIMV_FOR(i, 0) c[i] -= v[i];} - void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;} - void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];} - void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;} - void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];} - _CVector operator -() const {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;} - _CVector operator +(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;} - _CVector operator -(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;} - _CVector operator *(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;} - _CVector operator /(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;} - _CVector operator /(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v[i]; return tv;} - _CVector operator *(const _CVector & v) const {if (Size != 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;} - _CVector operator &(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v[i]; return tv;} - Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;} + void operator +=(const _CVector & v) {PIMV_FOR c[i] += v[i];} + void operator -=(const _CVector & v) {PIMV_FOR c[i] -= v[i];} + void operator *=(const Type & v) {PIMV_FOR c[i] *= v;} + void operator /=(const Type & v) { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + PIMV_FOR c[i] /= v; + } + _CVector operator -() const { + _CVector tv; + PIMV_FOR tv[i] = -c[i]; + return tv; + } + _CVector operator +(const _CVector & v) const { + _CVector tv(*this); + PIMV_FOR tv[i] += v[i]; + return tv; + } + _CVector operator -(const _CVector & v) const { + _CVector tv(*this); + PIMV_FOR tv[i] -= v[i]; + return tv; + } + _CVector operator *(const Type & v) const { + _CVector tv(*this); + PIMV_FOR tv[i] *= v; + return tv; + } + _CVector operator /(const Type & v) const { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + _CVector tv = _CVector(*this); + PIMV_FOR tv[i] /= v; + return tv; + } + + _CVector cross(const _CVector & v) const { + static_assert(Size == 3, "cross product avalible only for 3D vectors"); + _CVector tv; + tv[0] = c[1]*v[2] - v[1]*c[2]; + tv[1] = v[0]*c[2] - c[0]*v[2]; + tv[2] = c[0]*v[1] - v[0]*c[1]; + return tv; + } + Type dot(const _CVector & v) const { + Type tv(0); + PIMV_FOR tv += c[i] * v[i]; + return tv; + } PIMathMatrixT<1, Size, Type> transposed() const { PIMathMatrixT<1, Size, Type> ret; - PIMV_FOR(i, 0) ret[0][i] = c[i]; + PIMV_FOR ret[0][i] = c[i]; return ret; } Type distToLine(const _CVector & lp0, const _CVector & lp1) { - _CVector a(lp0, lp1), b(lp0, *this), c(lp1, *this); - Type f = fabs(a[0]*b[1] - a[1]*b[0]) / a.length(); - return f;} + _CVector a(lp0, lp1); + Type tv = a.length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + _CVector b(lp0, *this); + return piAbs(a[0]*b[1] - a[1]*b[0]) / tv; + } template /// vector {Size, Type} to vector {Size1, Type1} - PIMathVectorT turnTo() const {PIMathVectorT tv; uint sz = piMin(Size, Size1); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;} - - static _CVector filled(const Type & v) {_CVector vv; PIMV_FOR(i, 0) vv[i] = v; return vv;} + PIMathVectorT turnTo() const { + PIMathVectorT tv; + uint sz = piMin(Size, Size1); + for (uint i = 0; i < sz; ++i) tv[i] = c[i]; + return tv; + } private: - void resize(const Type & new_value = Type()) {for (uint i = 0; i < Size; ++i) c[i] = new_value;} - Type c[Size]; }; @@ -117,18 +183,8 @@ inline PIMathVectorT operator *(const Type & x, const PIMathVectorT< } template -inline PICout operator <<(PICout s, const PIMathVectorT & v) {s << "{"; PIMV_FOR(i, 0) {s << v[i]; if (i < Size - 1) s << ", ";} s << "}"; return s;} -template -inline bool operator ||(const PIMathVectorT & f, const PIMathVectorT & s) {return (f * s).isNull();} -template -inline PIMathVectorT sqrt(const PIMathVectorT & v) {PIMathVectorT ret; PIMV_FOR(i, 0) {ret[i] = sqrt(v[i]);} return ret;} -template -inline PIMathVectorT sqr(const PIMathVectorT & v) {PIMathVectorT ret; PIMV_FOR(i, 0) {ret[i] = sqr(v[i]);} return ret;} +inline PICout operator <<(PICout s, const PIMathVectorT & v) {s << "{"; PIMV_FOR {s << v[i]; if (i < Size - 1) s << ", ";} s << "}"; return s;} -template -inline PIByteArray & operator <<(PIByteArray & s, const PIMathVectorT & v) {for (uint i = 0; i < Size; ++i) s << v[i]; return s;} -template -inline PIByteArray & operator >>(PIByteArray & s, PIMathVectorT & v) {for (uint i = 0; i < Size; ++i) s >> v[i]; return s;} template @@ -158,7 +214,7 @@ typedef PIMathVectorT<4u, double> PIMathVectorT4d; /// Vector -#define PIMV_FOR(v, s) for (uint v = s; v < c.size(); ++v) +#define PIMV_FOR for (uint i = 0; i < c.size(); ++i) template class PIP_EXPORT PIMathVector { @@ -166,63 +222,167 @@ class PIP_EXPORT PIMathVector { template friend PIByteArray & operator <<(PIByteArray & s, const PIMathVector & v); template friend PIByteArray & operator >>(PIByteArray & s, PIMathVector & v); public: - PIMathVector(const uint size = 0) {c.resize(size);} - PIMathVector(const PIVector & val) {c.resize(val.size()); PIMV_FOR(i, 0) c[i] = val[i];} - PIMathVector(const _CVector & st, const _CVector & fn) {c.resize(st.size()); PIMV_FOR(i, 0) c[i] = fn[i] - st[i];} + PIMathVector(const uint size = 0, const Type & new_value = Type()) {c.resize(size, new_value);} + PIMathVector(const PIVector & val) {c = val;} + + template + PIMathVector(const PIMathVectorT & val) {c.resize(Size); PIMV_FOR c[i] = val[i];} + + static PIMathVector fromTwoPoints(const _CVector & st, const _CVector & fn) { + assert(st.size() == fn.size()); + _CVector v(st.size()); + for (uint i = 0; i < v.size(); ++i) v.c[i] = fn[i] - st[i]; + } uint size() const {return c.size();} - _CVector & resize(uint size, const Type & new_value = Type()) {c.resize(size, new_value); return *this;} - _CVector resized(uint size, const Type & new_value = Type()) {_CVector tv = _CVector(*this); tv.resize(size, new_value); return tv;} - _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} - _CVector & move(const Type & v) {PIMV_FOR(i, 0) c[i] += v; return *this;} - _CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;} - _CVector & swap(uint fe, uint se) {piSwap(c[fe], c[se]); return *this;} - Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += (c[i] * c[i]); return tv;} + _CVector & resize(uint size, const Type & new_value = Type()) { + c.resize(size, new_value); + return *this; + } + _CVector resized(uint size, const Type & new_value = Type()) { + _CVector tv = _CVector(*this); + tv.resize(size, new_value); + return tv; + } + _CVector & fill(const Type & v) { + c.fill(v); + return *this; + } + _CVector & move(const Type & v) { + PIMV_FOR c[i] += v; + return *this; + } + _CVector & move(const _CVector & v) { + assert(c.size() == v.size()); + PIMV_FOR c[i] += v[i]; + return *this; + } + _CVector & swapElements(uint fe, uint se) { + piSwap(c[fe], c[se]); + return *this; + } + Type lengthSqr() const { + Type tv(0); + PIMV_FOR tv += c[i] * c[i]; + return tv; + } Type length() const {return sqrt(lengthSqr());} - Type manhattanLength() const {Type tv(0); PIMV_FOR(i, 0) tv += fabs(c[i]); return tv;} - Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);} - Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);} + Type manhattanLength() const { + Type tv(0); + PIMV_FOR tv += piAbs(c[i]); + return tv; + } + Type angleCos(const _CVector & v) const { + assert(c.size() == v.size()); + Type tv = v.length() * length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + return dot(v) / tv; + } + Type angleSin(const _CVector & v) const { + assert(c.size() == v.size()); + Type tv = angleCos(v); + return sqrt(Type(1) - tv * tv); + } Type angleRad(const _CVector & v) const {return acos(angleCos(v));} - Type angleDeg(const _CVector & v) const {return toDeg(acos(angleCos(v)));} - _CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));} - _CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; if (piAbs(tv) <= Type(1E-100)) {fill(Type(0)); return *this;} PIMV_FOR(i, 0) c[i] /= tv; return *this;} - _CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;} - bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;} + Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} + _CVector projection(const _CVector & v) { + assert(c.size() == v.size()); + Type tv = v.length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + return v * (dot(v) / tv); + } + _CVector & normalize() { + Type tv = length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + if (tv == Type(1)) return *this; + PIMV_FOR c[i] /= tv; + return *this; + } + _CVector normalized() { + _CVector tv(*this); + tv.normalize(); + return tv; + } + bool isNull() const { + PIMV_FOR if (c[i] != Type(0)) return false; + return true; + } bool isValid() const {return !c.isEmpty();} - - bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} + bool isOrtho(const _CVector & v) const {return dot(v) == Type(0);} Type & at(uint index) {return c[index];} Type at(uint index) const {return c[index];} Type & operator [](uint index) {return c[index];} Type operator [](uint index) const {return c[index];} - _CVector & operator =(const _CVector & v) {c = v.c; return *this;} - _CVector & operator =(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} - bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;} - bool operator !=(const _CVector & v) const {return !(*this == c);} - void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];} - void operator -=(const _CVector & v) {PIMV_FOR(i, 0) c[i] -= v[i];} - void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;} - void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];} - void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;} - void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];} - _CVector operator -() const {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;} - _CVector operator +(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;} - _CVector operator -(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;} - _CVector operator *(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;} - _CVector operator /(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;} - _CVector operator *(const _CVector & v) const {if (c.size() < 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;} - _CVector operator &(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v[i]; return tv;} - Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;} - - Type distToLine(const _CVector & lp0, const _CVector & lp1) { - _CVector a(lp0, lp1), b(lp0, *this), c(lp1, *this); - Type f = fabs(a[0]*b[1] - a[1]*b[0]) / a.length(); - return f; + bool operator ==(const _CVector & v) const {return c == v.c;} + bool operator !=(const _CVector & v) const {return c != v.c;} + void operator +=(const _CVector & v) { + assert(c.size() == v.size()); + PIMV_FOR c[i] += v[i]; + } + void operator -=(const _CVector & v) { + assert(c.size() == v.size()); + PIMV_FOR c[i] -= v[i]; + } + void operator *=(const Type & v) {PIMV_FOR c[i] *= v;} + void operator /=(const Type & v) { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + PIMV_FOR c[i] /= v; + } + _CVector operator -() const { + _CVector tv(c.size()); + PIMV_FOR tv[i] = -c[i]; + return tv; + } + _CVector operator +(const _CVector & v) const { + assert(c.size() == v.size()); + _CVector tv(*this); + PIMV_FOR tv[i] += v[i]; + return tv; + } + _CVector operator -(const _CVector & v) const { + assert(c.size() == v.size()); + _CVector tv(*this); + PIMV_FOR tv[i] -= v[i]; + return tv; + } + _CVector operator *(const Type & v) const { + _CVector tv(*this); + PIMV_FOR tv[i] *= v; + return tv; + } + _CVector operator /(const Type & v) const { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + _CVector tv(*this); + PIMV_FOR tv[i] /= v; + return tv; + } + _CVector cross(const _CVector & v) const { + assert(c.size() == 3); + assert(v.size() == 3); + _CVector tv(3); + tv[0] = c[1]*v[2] - v[1]*c[2]; + tv[1] = c[2]*v[0] - v[2]*c[0]; + tv[2] = c[0]*v[1] - v[0]*c[1]; + return tv; + } + Type dot(const _CVector & v) const { + assert(c.size() == v.size()); + Type tv(0); + PIMV_FOR tv += c[i] * v[i]; + return tv; + } + + Type distToLine(const _CVector & lp0, const _CVector & lp1) { + assert(c.size() == lp0.size()); + assert(c.size() == lp1.size()); + _CVector a = _CVector::fromTwoPoints(lp0, lp1); + Type tv = a.length(); + assert(piAbs(tv) > PIMATHVECTOR_ZERO_CMP); + _CVector b = _CVector::fromTwoPoints(lp0, *this); + return piAbs(a[0]*b[1] - a[1]*b[0]) / tv; } - template - PIMathVector turnTo(uint size) const {PIMathVector tv; uint sz = piMin(c.size(), size); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;} PIVector toVector() const {return c;} inline Type * data() {return c.data();} @@ -233,6 +393,11 @@ private: }; +template +inline PIMathVector operator *(const Type & x, const PIMathVector & v) { + return v * x; +} + #undef PIMV_FOR #ifdef PIP_STD_IOSTREAM diff --git a/libs/main/math/piquaternion.cpp b/libs/main/math/piquaternion.cpp index 5ea23fe9..fa95ad7c 100644 --- a/libs/main/math/piquaternion.cpp +++ b/libs/main/math/piquaternion.cpp @@ -199,8 +199,8 @@ PIQuaternion PIQuaternion::fromRotationMatrix(const PIMathMatrixT33d & m) { PIQuaternion operator*(const PIQuaternion & q0, const PIQuaternion & q1) { PIMathVectorT3d v0(q0.vector()), v1(q1.vector()); - double r0 = q0.q[0] * q1.q[0] - (v0^v1); - PIMathVectorT3d qv = v1*q0.q[0] + v0*q1.q[0] + v0*v1; + double r0 = q0.q[0] * q1.q[0] - v0.dot(v1); + PIMathVectorT3d qv = v1*q0.q[0] + v0*q1.q[0] + v0.cross(v1); PIQuaternion ret; ret.q[0] = r0; ret.q[1] = qv[0]; From 6f3fdf4d4945bb24e807050147a3766c49611dff Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 21 Oct 2020 18:36:57 +0300 Subject: [PATCH 02/11] pimathvector.h mul --- libs/main/math/pimathvector.h | 50 ++++++++++++++++++++++++++++++++++- main.cpp | 9 +++---- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 010b74e3..8983fd37 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -149,6 +149,14 @@ public: PIMV_FOR tv += c[i] * v[i]; return tv; } + _CVector mul(const _CVector & v) const { + _CVector tv(*this); + PIMV_FOR tv[i] *= v[i]; + return tv; + } + _CVector mul(const Type & v) const { + return (*this) * v; + } PIMathMatrixT<1, Size, Type> transposed() const { PIMathMatrixT<1, Size, Type> ret; @@ -172,6 +180,22 @@ public: return tv; } + static _CVector cross(const _CVector & v1, const _CVector & v2) { + return v1.cross(v2); + } + static _CVector dot(const _CVector & v1, const _CVector & v2) { + return v1.dot(v2); + } + static _CVector mul(const _CVector & v1, const _CVector & v2) { + return v1.mul(v2); + } + static _CVector mul(const Type & v1, const _CVector & v2) { + return v2 * v1; + } + static _CVector mul(const _CVector & v1, const Type & v2) { + return v1 * v2; + } + private: Type c[Size]; @@ -372,6 +396,15 @@ public: PIMV_FOR tv += c[i] * v[i]; return tv; } + _CVector mul(const _CVector & v) const { + assert(c.size() == v.size()); + _CVector tv(*this); + PIMV_FOR tv[i] *= v[i]; + return tv; + } + _CVector mul(const Type & v) const { + return (*this) * v; + } Type distToLine(const _CVector & lp0, const _CVector & lp1) { assert(c.size() == lp0.size()); @@ -388,9 +421,24 @@ public: inline Type * data() {return c.data();} inline const Type * data() const {return c.data();} + + static _CVector cross(const _CVector & v1, const _CVector & v2) { + return v1.cross(v2); + } + static _CVector dot(const _CVector & v1, const _CVector & v2) { + return v1.dot(v2); + } + static _CVector mul(const _CVector & v1, const _CVector & v2) { + return v1.mul(v2); + } + static _CVector mul(const Type & v1, const _CVector & v2) { + return v2 * v1; + } + static _CVector mul(const _CVector & v1, const Type & v2) { + return v1 * v2; + } private: PIVector c; - }; template diff --git a/main.cpp b/main.cpp index e4194112..072c42ab 100644 --- a/main.cpp +++ b/main.cpp @@ -40,11 +40,8 @@ inline PIByteArray & operator >>(PIByteArray & ba, MM & v) {piCout << ">>" int main() { - PIMathMatrixd m = PIMathMatrixd::identity(5,5); -// m.fill(9); - //PIMathMatrixd m2 = PIMathMatrixd::identity(3,4); - piCout << m; - m.resize(3,3); - piCout << m; + PIMathVectorT3d v3 = createVectorT3d(1,2,3); + PIMathVectord v(v3); + piCout << v; return 0; } From a7408922dfac67dc297c9d512434d69aeb665266 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 21 Oct 2020 18:49:04 +0300 Subject: [PATCH 03/11] add constexpr to pibase methods --- libs/main/core/pibase.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libs/main/core/pibase.h b/libs/main/core/pibase.h index 82b95935..593a0dfa 100644 --- a/libs/main/core/pibase.h +++ b/libs/main/core/pibase.h @@ -358,7 +358,7 @@ inline bool piCompareBinary(const void * f, const void * s, size_t size) { * * Example: * \snippet piincludes.cpp round */ -template inline int piRound(const T & v) {return int(v >= T(0.) ? v + T(0.5) : v - T(0.5));} +template inline constexpr int piRound(const T & v) {return int(v >= T(0.) ? v + T(0.5) : v - T(0.5));} /*! \brief Templated function return floor of float falue * \details Floor is the largest integer that is not greater than value \n @@ -368,7 +368,7 @@ template inline int piRound(const T & v) {return int(v >= T(0.) ? v * * Example: * \snippet piincludes.cpp floor */ -template inline int piFloor(const T & v) {return v < T(0) ? int(v) - 1 : int(v);} +template inline constexpr int piFloor(const T & v) {return v < T(0) ? int(v) - 1 : int(v);} /*! \brief Templated function return ceil of float falue * \details Ceil is the smallest integer that is not less than value \n @@ -378,7 +378,7 @@ template inline int piFloor(const T & v) {return v < T(0) ? int(v) - * * Example: * \snippet piincludes.cpp ceil */ -template inline int piCeil(const T & v) {return v < T(0) ? int(v) : int(v) + 1;} +template inline constexpr int piCeil(const T & v) {return v < T(0) ? int(v) : int(v) + 1;} /*! \brief Templated function return absolute of numeric falue * \details Absolute is the positive or equal 0 value \n @@ -392,7 +392,7 @@ template inline int piCeil(const T & v) {return v < T(0) ? int(v) : * * Example: * \snippet piincludes.cpp abs */ -template inline T piAbs(const T & v) {return (v >= T(0) ? v : -v);} +template inline constexpr T piAbs(const T & v) {return (v >= T(0) ? v : -v);} /*! \brief Templated function return minimum of two values * \details There are some macros: @@ -405,7 +405,7 @@ template inline T piAbs(const T & v) {return (v >= T(0) ? v : -v);} * * Example: * \snippet piincludes.cpp min2 */ -template inline T piMin(const T & f, const T & s) {return ((f > s) ? s : f);} +template inline constexpr T piMin(const T & f, const T & s) {return ((f > s) ? s : f);} /*! \brief Templated function return minimum of tree values * \details There are some macros: @@ -418,7 +418,7 @@ template inline T piMin(const T & f, const T & s) {return ((f > s) ? * * Example: * \snippet piincludes.cpp min3 */ -template inline T piMin(const T & f, const T & s, const T & t) {return ((f < s && f < t) ? f : ((s < t) ? s : t));} +template inline constexpr T piMin(const T & f, const T & s, const T & t) {return ((f < s && f < t) ? f : ((s < t) ? s : t));} /*! \brief Templated function return maximum of two values * \details There are some macros: @@ -431,7 +431,7 @@ template inline T piMin(const T & f, const T & s, const T & t) {retu * * Example: * \snippet piincludes.cpp max2 */ -template inline T piMax(const T & f, const T & s) {return ((f < s) ? s : f);} +template inline constexpr T piMax(const T & f, const T & s) {return ((f < s) ? s : f);} /*! \brief Templated function return maximum of tree values * \details There are some macros: @@ -444,7 +444,7 @@ template inline T piMax(const T & f, const T & s) {return ((f < s) ? * * Example: * \snippet piincludes.cpp max3 */ -template inline T piMax(const T & f, const T & s, const T & t) {return ((f > s && f > t) ? f : ((s > t) ? s : t));} +template inline constexpr T piMax(const T & f, const T & s, const T & t) {return ((f > s && f > t) ? f : ((s > t) ? s : t));} /*! \brief Templated function return clamped value * \details Clamped is the not greater than "max" and not lesser than "min" value \n @@ -458,7 +458,7 @@ template inline T piMax(const T & f, const T & s, const T & t) {retu * * Example: * \snippet piincludes.cpp clamp */ -template inline T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));} +template inline constexpr T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));} /// Function inverse byte order in memory block inline void piLetobe(void * data, int size) { From 47be2d3d6297838a9eb22617e7a724824fb59d9d Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 21 Oct 2020 18:54:41 +0300 Subject: [PATCH 04/11] pimathvector.h div and std::initializer_list --- libs/main/math/pimathvector.h | 60 +++++++++++++++++++++++---------- libs/main/math/piquaternion.cpp | 4 +-- libs/main/math/piquaternion.h | 2 +- main.cpp | 4 ++- 4 files changed, 48 insertions(+), 22 deletions(-) diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 8983fd37..4f89a7b9 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -46,6 +46,10 @@ public: assert(Size == val.size()); PIMV_FOR c[i] = val[i]; } + PIMathVectorT(std::initializer_list init_list) { + assert(Size == init_list.size()); + PIMV_FOR c[i] = init_list.begin()[i]; + } static _CVector fromTwoPoints(const _CVector & st, const _CVector & fn) { _CVector tv; PIMV_FOR tv[i] = fn[i] - st[i]; @@ -157,7 +161,18 @@ public: _CVector mul(const Type & v) const { return (*this) * v; } - + _CVector div(const _CVector & v) const { + _CVector tv(*this); + PIMV_FOR { + assert(piAbs(v[i]) > PIMATHVECTOR_ZERO_CMP); + tv[i] /= v[i]; + } + return tv; + } + _CVector div(const Type & v) const { + return (*this) / v; + } + PIMathMatrixT<1, Size, Type> transposed() const { PIMathMatrixT<1, Size, Type> ret; PIMV_FOR ret[0][i] = c[i]; @@ -195,6 +210,12 @@ public: static _CVector mul(const _CVector & v1, const Type & v2) { return v1 * v2; } + static _CVector div(const _CVector & v1, const _CVector & v2) { + return v1.div(v2); + } + static _CVector div(const _CVector & v1, const Type & v2) { + return v1 / v2; + } private: Type c[Size]; @@ -210,29 +231,13 @@ template inline PICout operator <<(PICout s, const PIMathVectorT & v) {s << "{"; PIMV_FOR {s << v[i]; if (i < Size - 1) s << ", ";} s << "}"; return s;} - -template -inline PIMathVectorT<2u, T> createVectorT2(T x, T y) {return PIMathVectorT<2u, T>(PIVector() << x << y);} -template -inline PIMathVectorT<3u, T> createVectorT3(T x, T y, T z) {return PIMathVectorT<3u, T>(PIVector() << x << y << z);} -template -inline PIMathVectorT<4u, T> createVectorT4(T x, T y, T z, T w) {return PIMathVectorT<4u, T>(PIVector() << x << y << z << w);} - typedef PIMathVectorT<2u, int> PIMathVectorT2i; typedef PIMathVectorT<3u, int> PIMathVectorT3i; typedef PIMathVectorT<4u, int> PIMathVectorT4i; typedef PIMathVectorT<2u, double> PIMathVectorT2d; typedef PIMathVectorT<3u, double> PIMathVectorT3d; typedef PIMathVectorT<4u, double> PIMathVectorT4d; -#define createVectorT2i createVectorT2 -#define createVectorT3i createVectorT3 -#define createVectorT4i createVectorT4 -#define createVectorT2f createVectorT2 -#define createVectorT3f createVectorT3 -#define createVectorT4f createVectorT4 -#define createVectorT2d createVectorT2 -#define createVectorT3d createVectorT3 -#define createVectorT4d createVectorT4 + #undef PIMV_FOR @@ -248,6 +253,7 @@ class PIP_EXPORT PIMathVector { public: PIMathVector(const uint size = 0, const Type & new_value = Type()) {c.resize(size, new_value);} PIMathVector(const PIVector & val) {c = val;} + PIMathVector(std::initializer_list init_list) {c = PIVector(init_list);} template PIMathVector(const PIMathVectorT & val) {c.resize(Size); PIMV_FOR c[i] = val[i];} @@ -405,6 +411,18 @@ public: _CVector mul(const Type & v) const { return (*this) * v; } + _CVector div(const _CVector & v) const { + assert(c.size() == v.size()); + _CVector tv(*this); + PIMV_FOR { + assert(piAbs(v[i]) > PIMATHVECTOR_ZERO_CMP); + tv[i] /= v[i]; + } + return tv; + } + _CVector div(const Type & v) const { + return (*this) / v; + } Type distToLine(const _CVector & lp0, const _CVector & lp1) { assert(c.size() == lp0.size()); @@ -437,6 +455,12 @@ public: static _CVector mul(const _CVector & v1, const Type & v2) { return v1 * v2; } + static _CVector div(const _CVector & v1, const _CVector & v2) { + return v1.div(v2); + } + static _CVector div(const _CVector & v1, const Type & v2) { + return v1 / v2; + } private: PIVector c; }; diff --git a/libs/main/math/piquaternion.cpp b/libs/main/math/piquaternion.cpp index fa95ad7c..9dc570a2 100644 --- a/libs/main/math/piquaternion.cpp +++ b/libs/main/math/piquaternion.cpp @@ -40,7 +40,7 @@ PIMathVectorT3d PIQuaternion::eyler() const { angle_z = atan2(-rmat[0][1] / c, rmat[0][0] / c); } if (angle_z < 0) angle_z = 2*M_PI + angle_z; - return createVectorT3d(angle_x,angle_y,angle_z); + return PIMathVectorT3d({angle_x,angle_y,angle_z}); } @@ -153,7 +153,7 @@ PIQuaternion PIQuaternion::fromAngles(double ax, double ay, double az) { } PIQuaternion PIQuaternion::fromAngles2(double ax, double ay, double az) { - double om = createVectorT3d(ax,ay,az).length(); + double om = PIMathVectorT3d({ax,ay,az}).length(); if (om == 0.) return PIQuaternion(PIMathVectorT3d(), 1.); PIQuaternion res; res.q[0] = cos(om/2); diff --git a/libs/main/math/piquaternion.h b/libs/main/math/piquaternion.h index e9b79e92..c54dbf89 100644 --- a/libs/main/math/piquaternion.h +++ b/libs/main/math/piquaternion.h @@ -39,7 +39,7 @@ public: double & scalar() {return q[0];} double scalar() const {return q[0];} - PIMathVectorT3d vector() const {return createVectorT3(q[1], q[2], q[3]);} + PIMathVectorT3d vector() const {return PIMathVectorT3d({q[1], q[2], q[3]});} PIMathVectorT3d eyler() const; PIMathMatrixT33d rotationMatrix() const; diff --git a/main.cpp b/main.cpp index 072c42ab..10dfb678 100644 --- a/main.cpp +++ b/main.cpp @@ -40,8 +40,10 @@ inline PIByteArray & operator >>(PIByteArray & ba, MM & v) {piCout << ">>" int main() { - PIMathVectorT3d v3 = createVectorT3d(1,2,3); + PIMathVectorT3d v3({1,2,3}); PIMathVectord v(v3); + PIMathVectord v2({3,2,1}); piCout << v; + piCout << v2; return 0; } From 13a0c1097afd19f0f2b41369c8ba4b9efff1edf0 Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 21 Oct 2020 18:55:31 +0300 Subject: [PATCH 05/11] version --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a9237f2a..8f00c155 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(pip_MAJOR 2) -set(pip_MINOR 13) +set(pip_MINOR 14) set(pip_REVISION 0) -set(pip_SUFFIX beta) +set(pip_SUFFIX alpha) set(pip_COMPANY SHS) set(pip_DOMAIN org.SHS) From b46825a5a07e688161432f091b815827c81bb248 Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 22 Oct 2020 12:44:30 +0300 Subject: [PATCH 06/11] PIMathMatrixT remove scale and rotate funcs --- libs/main/math/pimathmatrix.h | 241 ++++++++------------------------ libs/main/math/piquaternion.cpp | 10 -- libs/main/math/piquaternion.h | 3 - 3 files changed, 56 insertions(+), 198 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 645c9e22..1e263e15 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -31,12 +31,9 @@ /// Matrix templated -#define PIMM_FOR(r, c) for (uint c = 0; c < Cols; ++c) { for (uint r = 0; r < Rows; ++r) { -#define PIMM_FOR_WB(r, c) for (uint c = 0; c < Cols; ++c) for (uint r = 0; r < Rows; ++r) // without brakes -#define PIMM_FOR_I(r, c) for (uint r = 0; r < Rows; ++r) { for (uint c = 0; c < Cols; ++c) { -#define PIMM_FOR_I_WB(r, c) for (uint r = 0; r < Rows; ++r) for (uint c = 0; c < Cols; ++c) // without brakes -#define PIMM_FOR_C(v) for (uint v = 0; v < Cols; ++v) -#define PIMM_FOR_R(v) for (uint v = 0; v < Rows; ++v) +#define PIMM_FOR for (uint r = 0; r < Rows; ++r) for (uint c = 0; c < Cols; ++c) +#define PIMM_FOR_C for (uint i = 0; i < Cols; ++i) +#define PIMM_FOR_R for (uint i = 0; i < Rows; ++i) #pragma pack(push, 1) @@ -71,7 +68,16 @@ public: PIMathMatrixT(const PIVector &val) { resize(Rows, Cols); int i = 0; - PIMM_FOR_I_WB(r, c) m[r][c] = val[i++]; + PIMM_FOR m[r][c] = val[i++]; + } + + /** + * @brief Contructs PIMathMatrixT from C++11 initializer list + */ + PIMathMatrixT(std::initializer_list init_list) { + assert(Rows*Cols == init_list.size()); + int i = 0; + PIMM_FOR m[r][c] = init_list.begin()[i++]; } /** @@ -81,7 +87,7 @@ public: */ static _CMatrix identity() { _CMatrix tm = _CMatrix(); - PIMM_FOR_WB(r, c) tm.m[r][c] = (c == r ? Type(1) : Type(0)); + PIMM_FOR tm.m[r][c] = (c == r ? Type(1) : Type(0)); return tm; } @@ -93,73 +99,10 @@ public: */ static _CMatrix filled(const Type &v) { _CMatrix tm; - PIMM_FOR_WB(r, c) tm.m[r][c] = v; + PIMM_FOR tm.m[r][c] = v; return tm; } - /** - * @brief Rotation the matrix by an "angle". Works only with 2x2 matrix, - * else return default construction of PIMathMatrixT - * - * @param angle is the angle of rotation of the matrix - * @return rotated matrix - */ - static _CMatrix rotation(double angle) { return _CMatrix(); } - - /** - * @brief Rotation of the matrix by an "angle" along the X axis. Works only with 3x3 matrix, - * else return default construction of PIMathMatrixT - * - * @param angle is the angle of rotation of the matrix along the X axis - * @return rotated matrix - */ - static _CMatrix rotationX(double angle) { return _CMatrix(); } - - /** - * @brief Rotation of the matrix by an "angle" along the Y axis. Works only with 3x3 matrix, - * else return default construction of PIMathMatrixT - * - * @param angle is the angle of rotation of the matrix along the Y axis - * @return rotated matrix - */ - static _CMatrix rotationY(double angle) { return _CMatrix(); } - - /** - * @brief Rotation of the matrix by an "angle" along the Z axis. Works only with 3x3 matrix, - * else return default construction of PIMathMatrixT - * - * @param angle is the angle of rotation of the matrix along the Z axis - * @return rotated matrix - */ - static _CMatrix rotationZ(double angle) { return _CMatrix(); } - - /** - * @brief Scaling the matrix along the X axis by the value "factor". Works only with 3x3 and 2x2 matrix, - * else return default construction of PIMathMatrixT - * - * @param factor is the value of scaling by X axis - * @return rotated matrix - */ - static _CMatrix scaleX(double factor) { return _CMatrix(); } - - /** - * @brief Scaling the matrix along the Y axis by the value "factor". Works only with 3x3 and 2x2 matrix, - * else return default construction of PIMathMatrixT - * - * @param factor is the value of scaling by Y axis - * @return rotated matrix - */ - static _CMatrix scaleY(double factor) { return _CMatrix(); } - - /** - * @brief Scaling the matrix along the Z axis by the value "factor". Works only with 3x3 matrix, - * else return default construction of PIMathMatrixT - * - * @param factor is the value of scaling by Z axis - * @return rotated matrix - */ - static _CMatrix scaleZ(double factor) { return _CMatrix(); } - /** * @brief Method which returns number of columns in matrix * @@ -183,7 +126,7 @@ public: */ _CMCol col(uint index) { _CMCol tv; - PIMM_FOR_R(i) tv[i] = m[i][index]; + PIMM_FOR_R tv[i] = m[i][index]; return tv; } @@ -196,7 +139,7 @@ public: */ _CMRow row(uint index) { _CMRow tv; - PIMM_FOR_C(i) tv[i] = m[index][i]; + PIMM_FOR_C tv[i] = m[index][i]; return tv; } @@ -209,7 +152,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &setCol(uint index, const _CMCol &v) { - PIMM_FOR_R(i) m[i][index] = v[i]; + PIMM_FOR_R m[i][index] = v[i]; return *this; } @@ -222,7 +165,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &setRow(uint index, const _CMRow &v) { - PIMM_FOR_C(i) m[index][i] = v[i]; + PIMM_FOR_C m[index][i] = v[i]; return *this; } @@ -236,7 +179,7 @@ public: */ _CMatrix &swapRows(uint r0, uint r1) { Type t; - PIMM_FOR_C(i) { + PIMM_FOR_C { t = m[r0][i]; m[r0][i] = m[r1][i]; m[r1][i] = t; @@ -254,7 +197,7 @@ public: */ _CMatrix &swapCols(uint c0, uint c1) { Type t; - PIMM_FOR_R(i) { + PIMM_FOR_R { t = m[i][c0]; m[i][c0] = m[i][c1]; m[i][c1] = t; @@ -269,7 +212,7 @@ public: * @return filled matrix type _CMatrix */ _CMatrix &fill(const Type &v) { - PIMM_FOR_WB(r, c) m[r][c] = v; + PIMM_FOR m[r][c] = v; return *this; } @@ -286,7 +229,7 @@ public: * @return true if matrix is identitied, else false */ bool isIdentity() const { - PIMM_FOR_WB(r, c) if ((c == r) ? m[r][c] != Type(1) : m[r][c] != Type(0)) return false; + PIMM_FOR if ((c == r) ? m[r][c] != Type(1) : m[r][c] != Type(0)) return false; return true; } @@ -296,7 +239,7 @@ public: * @return true if matrix is null, else false */ bool isNull() const { - PIMM_FOR_WB(r, c) if (m[r][c] != Type(0)) return false; + PIMM_FOR if (m[r][c] != Type(0)) return false; return true; } @@ -354,7 +297,7 @@ public: * @return if matrices are equal true, else false */ bool operator==(const _CMatrix &sm) const { - PIMM_FOR_WB(r, c) if (m[r][c] != sm.m[r][c]) return false; + PIMM_FOR if (m[r][c] != sm.m[r][c]) return false; return true; } @@ -371,28 +314,28 @@ public: * * @param sm matrix for the addition assigment */ - void operator+=(const _CMatrix &sm) { PIMM_FOR_WB(r, c) m[r][c] += sm.m[r][c]; } + void operator+=(const _CMatrix &sm) { PIMM_FOR m[r][c] += sm.m[r][c]; } /** * @brief Subtraction assignment with matrix "sm" * * @param sm matrix for the subtraction assigment */ - void operator-=(const _CMatrix &sm) { PIMM_FOR_WB(r, c) m[r][c] -= sm.m[r][c]; } + void operator-=(const _CMatrix &sm) { PIMM_FOR m[r][c] -= sm.m[r][c]; } /** * @brief Multiplication assignment with value "v" * * @param v value for the multiplication assigment */ - void operator*=(const Type &v) { PIMM_FOR_WB(r, c) m[r][c] *= v; } + void operator*=(const Type &v) { PIMM_FOR m[r][c] *= v; } /** * @brief Division assignment with value "v" * * @param v value for the division assigment */ - void operator/=(const Type &v) { PIMM_FOR_WB(r, c) m[r][c] /= v; } + void operator/=(const Type &v) { PIMM_FOR m[r][c] /= v; } /** * @brief Matrix substraction @@ -401,7 +344,7 @@ public: */ _CMatrix operator-() const { _CMatrix tm; - PIMM_FOR_WB(r, c) tm.m[r][c] = -m[r][c]; + PIMM_FOR tm.m[r][c] = -m[r][c]; return tm; } @@ -413,7 +356,7 @@ public: */ _CMatrix operator+(const _CMatrix &sm) const { _CMatrix tm = _CMatrix(*this); - PIMM_FOR_WB(r, c) tm.m[r][c] += sm.m[r][c]; + PIMM_FOR tm.m[r][c] += sm.m[r][c]; return tm; } @@ -425,7 +368,7 @@ public: */ _CMatrix operator-(const _CMatrix &sm) const { _CMatrix tm = _CMatrix(*this); - PIMM_FOR_WB(r, c) tm.m[r][c] -= sm.m[r][c]; + PIMM_FOR tm.m[r][c] -= sm.m[r][c]; return tm; } @@ -437,7 +380,7 @@ public: */ _CMatrix operator*(const Type &v) const { _CMatrix tm = _CMatrix(*this); - PIMM_FOR_WB(r, c) tm.m[r][c] *= v; + PIMM_FOR tm.m[r][c] *= v; return tm; } @@ -449,7 +392,7 @@ public: */ _CMatrix operator/(const Type &v) const { _CMatrix tm = _CMatrix(*this); - PIMM_FOR_WB(r, c) tm.m[r][c] /= v; + PIMM_FOR tm.m[r][c] /= v; return tm; } @@ -467,10 +410,7 @@ public: if (ok) *ok = k; if (!k) return ret; ret = Type(1); - for (uint c = 0; c < Cols; ++c) - for (uint r = 0; r < Rows; ++r) - if (r == c) - ret *= m[r][c]; + PIMM_FOR if (r == c) ret *= m[r][c]; return ret; } @@ -590,7 +530,7 @@ public: */ _CMatrixI transposed() const { _CMatrixI tm; - PIMM_FOR_WB(r, c) tm[c][r] = m[r][c]; + PIMM_FOR tm[c][r] = m[r][c]; return tm; } @@ -598,7 +538,7 @@ private: void resize(uint rows_, uint cols_, const Type &new_value = Type()) { r_ = rows_; c_ = cols_; - PIMM_FOR_WB(r, c) m[r][c] = new_value; + PIMM_FOR m[r][c] = new_value; } int c_, r_; @@ -609,92 +549,22 @@ private: #pragma pack(pop) -template<> -inline PIMathMatrixT<2u, 2u> PIMathMatrixT<2u, 2u>::rotation(double angle) { - double c = cos(angle), s = sin(angle); - PIMathMatrixT<2u, 2u> tm; - tm[0][0] = tm[1][1] = c; - tm[0][1] = -s; - tm[1][0] = s; - return tm; -} -template<> -inline PIMathMatrixT<2u, 2u> PIMathMatrixT<2u, 2u>::scaleX(double factor) { - PIMathMatrixT<2u, 2u> tm; - tm[0][0] = factor; - tm[1][1] = 1.; - return tm; -} - -template<> -inline PIMathMatrixT<2u, 2u> PIMathMatrixT<2u, 2u>::scaleY(double factor) { - PIMathMatrixT<2u, 2u> tm; - tm[0][0] = 1.; - tm[1][1] = factor; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::rotationX(double angle) { - double c = cos(angle), s = sin(angle); - PIMathMatrixT<3u, 3u> tm; - tm[0][0] = 1.; - tm[1][1] = tm[2][2] = c; - tm[2][1] = s; - tm[1][2] = -s; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::rotationY(double angle) { - double c = cos(angle), s = sin(angle); - PIMathMatrixT<3u, 3u> tm; - tm[1][1] = 1.; - tm[0][0] = tm[2][2] = c; - tm[2][0] = -s; - tm[0][2] = s; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::rotationZ(double angle) { - double c = cos(angle), s = sin(angle); - PIMathMatrixT<3u, 3u> tm; - tm[2][2] = 1.; - tm[0][0] = tm[1][1] = c; - tm[1][0] = s; - tm[0][1] = -s; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::scaleX(double factor) { - PIMathMatrixT<3u, 3u> tm; - tm[1][1] = tm[2][2] = 1.; - tm[0][0] = factor; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::scaleY(double factor) { - PIMathMatrixT<3u, 3u> tm; - tm[0][0] = tm[2][2] = 1.; - tm[1][1] = factor; - return tm; -} - -template<> -inline PIMathMatrixT<3u, 3u> PIMathMatrixT<3u, 3u>::scaleZ(double factor) { - PIMathMatrixT<3u, 3u> tm; - tm[0][0] = tm[1][1] = 1.; - tm[2][2] = factor; - return tm; -} #ifdef PIP_STD_IOSTREAM template -inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT & m) {s << "{"; PIMM_FOR_I(r, c) s << m[r][c]; if (c < Cols - 1 || r < Rows - 1) s << ", ";} if (r < Rows - 1) s << std::endl << " ";} s << "}"; return s;} +inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT & m) { + s << "{"; + for (uint r = 0; r < Rows; ++r) { + for (uint c = 0; c < Cols; ++c) { + s << m[r][c]; + if (c < Cols - 1 || r < Rows - 1) s << ", "; + } + if (r < Rows - 1) s << std::endl << " "; + } + s << "}"; + return s; +} #endif /** @@ -707,9 +577,13 @@ inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT inline PICout operator<<(PICout s, const PIMathMatrixT &m) { s << "{"; - PIMM_FOR_I(r, c) s << m[r][c]; - if (c < Cols - 1 || r < Rows - 1) s << ", "; } - if (r < Rows - 1) s << PICoutManipulators::NewLine << " "; } + for (uint r = 0; r < Rows; ++r) { + for (uint c = 0; c < Cols; ++c) { + s << m[r][c]; + if (c < Cols - 1 || r < Rows - 1) s << ", "; + } + if (r < Rows - 1) s << PICoutManipulators::NewLine << " "; + } s << "}"; return s; } @@ -804,9 +678,6 @@ template class PIMathMatrix; #undef PIMM_FOR -#undef PIMM_FOR_WB -#undef PIMM_FOR_I -#undef PIMM_FOR_I_WB #undef PIMM_FOR_C #undef PIMM_FOR_R diff --git a/libs/main/math/piquaternion.cpp b/libs/main/math/piquaternion.cpp index 9dc570a2..d71c5389 100644 --- a/libs/main/math/piquaternion.cpp +++ b/libs/main/math/piquaternion.cpp @@ -96,16 +96,6 @@ void PIQuaternion::normalize() { } -PIMathMatrixT44d PIQuaternion::makeMatrix() const { - PIMathMatrixT44d ret; - ret[0][0] = q[0]; ret[0][1] = -q[1]; ret[0][2] = -q[2]; ret[0][3] = -q[3]; - ret[1][0] = q[1]; ret[1][1] = q[0]; ret[1][2] = -q[3]; ret[1][3] = q[2]; - ret[2][0] = q[2]; ret[2][1] = q[3]; ret[2][2] = q[0]; ret[2][3] = -q[1]; - ret[3][0] = q[3]; ret[3][1] = -q[2]; ret[3][2] = q[1]; ret[3][3] = q[0]; - return ret; -} - - PIQuaternion PIQuaternion::fromEyler(double ax, double ay, double az) { PIQuaternion q_heading; PIQuaternion q_pinch; diff --git a/libs/main/math/piquaternion.h b/libs/main/math/piquaternion.h index c54dbf89..4cfb6f1f 100644 --- a/libs/main/math/piquaternion.h +++ b/libs/main/math/piquaternion.h @@ -52,9 +52,6 @@ public: protected: double q[4]; - PIMathMatrixT44d makeMatrix() const; - - }; PIP_EXPORT PIQuaternion operator *(const double & a, const PIQuaternion & q); From 7413c7252b38018459139a3488757f0123b8ff51 Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 22 Oct 2020 16:13:39 +0300 Subject: [PATCH 07/11] refactor PIMathMatrixT and fix pimathvector.h --- libs/main/math/pimathmatrix.h | 133 +++++++++++++--------------------- libs/main/math/pimathvector.h | 27 ++++--- 2 files changed, 68 insertions(+), 92 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 1e263e15..05f7a551 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -53,20 +53,15 @@ class PIP_EXPORT PIMathMatrixT { static_assert(Cols > 0, "Column count must be > 0"); public: /** - * @brief Constructor that calls the private resize method - * - * @return identitied matrix of type PIMathMatrixT + * @brief Constructs PIMathMatrixT that is filled by \a new_value */ - PIMathMatrixT() { resize(Rows, Cols); } + PIMathMatrixT(const Type &new_value = Type()) {PIMM_FOR m[r][c] = new_value;} /** - * @brief Constructor that calls the private resize method - * - * @param val is the PIVector with which the matrix is ​​filled - * @return identitied matrix of type PIMathMatrixT + * @brief Contructs PIMathMatrixT from PIVector */ PIMathMatrixT(const PIVector &val) { - resize(Rows, Cols); + assert(Rows*Cols == val.size()); int i = 0; PIMM_FOR m[r][c] = val[i++]; } @@ -91,31 +86,19 @@ public: return tm; } - /** - * @brief Creates a matrix that is filled with elements - * - * @param v is a parameter the type and value of which is selected and later filled into the matrix - * @return filled matrix of type PIMathMatrixT - */ - static _CMatrix filled(const Type &v) { - _CMatrix tm; - PIMM_FOR tm.m[r][c] = v; - return tm; - } - /** * @brief Method which returns number of columns in matrix * * @return type uint shows number of columns */ - uint cols() const { return Cols; } + constexpr uint cols() const {return Cols;} /** * @brief Method which returns number of rows in matrix * * @return type uint shows number of rows */ - uint rows() const { return Rows; } + constexpr uint rows() const {return Rows;} /** * @brief Method which returns the selected column in PIMathVectorT format. @@ -177,13 +160,8 @@ public: * @param r1 is the number of the second selected row * @return matrix type _CMatrix */ - _CMatrix &swapRows(uint r0, uint r1) { - Type t; - PIMM_FOR_C { - t = m[r0][i]; - m[r0][i] = m[r1][i]; - m[r1][i] = t; - } + _CMatrix &swapRows(uint rf, uint rs) { + PIMM_FOR_C piSwap(m[rf][i], m[rs][i]); return *this; } @@ -195,13 +173,8 @@ public: * @param c1 is the number of the second selected column * @return matrix type _CMatrix */ - _CMatrix &swapCols(uint c0, uint c1) { - Type t; - PIMM_FOR_R { - t = m[i][c0]; - m[i][c0] = m[i][c1]; - m[i][c1] = t; - } + _CMatrix &swapCols(uint cf, uint cs) { + PIMM_FOR_R piSwap(m[i][cf], m[i][cs]); return *this; } @@ -221,7 +194,7 @@ public: * * @return true if matrix is square, else false */ - bool isSquare() const { return cols() == rows(); } + constexpr bool isSquare() const { return Rows == Cols; } /** * @brief Method which checks if main diagonal of matrix consists of ones and another elements are zeros @@ -243,30 +216,41 @@ public: return true; } - /** - * @brief Full access to elements reference by row "row" and col "col". - * If you enter an index out of the border of the matrix there will be "undefined behavior" - * - * @param row is a parameter that shows the row number of the matrix of the selected element - * @param col is a parameter that shows the column number of the matrix of the selected element - * @return reference to element of matrix by row "row" and col "col" - */ - Type &at(uint row, uint col) { return m[row][col]; } /** - * @brief Full access to element by row "row" and col "col". + * @brief Read-only access to element by \a row and \a col. * If you enter an index out of the border of the matrix there will be "undefined behavior" * - * @param row is a parameter that shows the row number of the matrix of the selected element - * @param col is a parameter that shows the column number of the matrix of the selected element - * @return element of matrix by row "row" and col "col" + * @param row of matrix + * @param col of matrix + * @return copy of element of matrix */ Type at(uint row, uint col) const { return m[row][col]; } + /** + * @brief Full access to element by \a row and \a col. + * If you enter an index out of the border of the matrix there will be "undefined behavior" + * + * @param row of matrix + * @param col of matrix + * @return element of matrix + */ + inline Type & element(uint row, uint col) {return m[row][col];} + + /** + * @brief Read-only access to element by \a row and \a col. + * If you enter an index out of the border of the matrix there will be "undefined behavior" + * + * @param row of matrix + * @param col of matrix + * @return element of matrix + */ + inline const Type & element(uint row, uint col) const {return m[row][col];} + /** * @brief Full access to the matrix row pointer. If you enter an index out of the border of the matrix there will be "undefined behavior" * - * @param row is a row of necessary matrix + * @param row of matrix * @return matrix row pointer */ Type *operator[](uint row) { return m[row]; } @@ -274,26 +258,15 @@ public: /** * @brief Read-only access to the matrix row pointer. If you enter an index out of the border of the matrix there will be "undefined behavior" * - * @param row is a row of necessary matrix + * @param row of matrix * @return matrix row pointer */ - const Type *operator[](uint row) const { return m[row]; } + const Type *operator[](uint row) const {return m[row];} /** - * @brief Matrix assignment to matrix "sm" + * @brief Matrix compare * - * @param sm matrix for the assigment - * @return matrix equal with sm - */ - _CMatrix &operator=(const _CMatrix &sm) { - memcpy(m, sm.m, sizeof(Type) * Cols * Rows); - return *this; - } - - /** - * @brief Compare with matrix "sm" - * - * @param sm matrix for the compare + * @param sm matrix for compare * @return if matrices are equal true, else false */ bool operator==(const _CMatrix &sm) const { @@ -302,9 +275,9 @@ public: } /** - * @brief Compare with matrix "sm" + * @brief Matrix negative compare * - * @param sm matrix for the compare + * @param sm matrix for compare * @return if matrices are not equal true, else false */ bool operator!=(const _CMatrix &sm) const { return !(*this == sm); } @@ -314,28 +287,31 @@ public: * * @param sm matrix for the addition assigment */ - void operator+=(const _CMatrix &sm) { PIMM_FOR m[r][c] += sm.m[r][c]; } + void operator+=(const _CMatrix &sm) {PIMM_FOR m[r][c] += sm.m[r][c];} /** * @brief Subtraction assignment with matrix "sm" * * @param sm matrix for the subtraction assigment */ - void operator-=(const _CMatrix &sm) { PIMM_FOR m[r][c] -= sm.m[r][c]; } + void operator-=(const _CMatrix &sm) {PIMM_FOR m[r][c] -= sm.m[r][c];} /** * @brief Multiplication assignment with value "v" * * @param v value for the multiplication assigment */ - void operator*=(const Type &v) { PIMM_FOR m[r][c] *= v; } + void operator*=(const Type &v) {PIMM_FOR m[r][c] *= v;} /** * @brief Division assignment with value "v" * * @param v value for the division assigment */ - void operator/=(const Type &v) { PIMM_FOR m[r][c] /= v; } + void operator/=(const Type &v) { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + PIMM_FOR m[r][c] /= v; + } /** * @brief Matrix substraction @@ -391,6 +367,7 @@ public: * @return the result of matrix division */ _CMatrix operator/(const Type &v) const { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); _CMatrix tm = _CMatrix(*this); PIMM_FOR tm.m[r][c] /= v; return tm; @@ -535,22 +512,12 @@ public: } private: - void resize(uint rows_, uint cols_, const Type &new_value = Type()) { - r_ = rows_; - c_ = cols_; - PIMM_FOR m[r][c] = new_value; - } - - int c_, r_; Type m[Rows][Cols]; - }; #pragma pack(pop) - - #ifdef PIP_STD_IOSTREAM template inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT & m) { diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 4f89a7b9..a19ae5e3 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -56,10 +56,14 @@ public: return tv; } - uint size() const {return Size;} + constexpr uint size() const {return Size;} _CVector & fill(const Type & v) {PIMV_FOR c[i] = v; return *this;} _CVector & move(const Type & v) {PIMV_FOR c[i] += v; return *this;} _CVector & move(const _CVector & v) {PIMV_FOR c[i] += v[i]; return *this;} + _CVector & swapElements(uint f, uint s) { + piSwap(c[f], c[s]); + return *this; + } Type lengthSqr() const { Type tv(0); PIMV_FOR tv += c[i] * c[i]; @@ -99,13 +103,15 @@ public: bool isNull() const {PIMV_FOR if (c[i] != Type(0)) return false; return true;} bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} - Type & at(uint index) {return c[index];} - Type at(uint index) const {return c[index];} Type & operator [](uint index) {return c[index];} - Type operator [](uint index) const {return c[index];} + const Type & operator [](uint index) const {return c[index];} + Type at(uint index) const {return c[index];} + _CVector & operator =(const Type & v) {PIMV_FOR c[i] = v; return *this;} + bool operator ==(const _CVector & v) const {PIMV_FOR if (c[i] != v[i]) return false; return true;} bool operator !=(const _CVector & v) const {return !(*this == c);} + void operator +=(const _CVector & v) {PIMV_FOR c[i] += v[i];} void operator -=(const _CVector & v) {PIMV_FOR c[i] -= v[i];} void operator *=(const Type & v) {PIMV_FOR c[i] *= v;} @@ -287,8 +293,8 @@ public: PIMV_FOR c[i] += v[i]; return *this; } - _CVector & swapElements(uint fe, uint se) { - piSwap(c[fe], c[se]); + _CVector & swapElements(uint f, uint s) { + piSwap(c[f], c[s]); return *this; } Type lengthSqr() const { @@ -340,12 +346,15 @@ public: bool isValid() const {return !c.isEmpty();} bool isOrtho(const _CVector & v) const {return dot(v) == Type(0);} - Type & at(uint index) {return c[index];} - Type at(uint index) const {return c[index];} Type & operator [](uint index) {return c[index];} - Type operator [](uint index) const {return c[index];} + const Type & operator [](uint index) const {return c[index];} + Type at(uint index) const {return c[index];} + + _CVector & operator =(const Type & v) {PIMV_FOR c[i] = v; return *this;} + bool operator ==(const _CVector & v) const {return c == v.c;} bool operator !=(const _CVector & v) const {return c != v.c;} + void operator +=(const _CVector & v) { assert(c.size() == v.size()); PIMV_FOR c[i] += v[i]; From f5652efc32315eae8f8324f0d8246b3e1f8910d0 Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 22 Oct 2020 16:48:46 +0300 Subject: [PATCH 08/11] refactoring PIMathMatrix --- libs/main/math/pimathmatrix.h | 92 +++++++++++++++++------------------ 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 05f7a551..b495d90d 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -301,7 +301,9 @@ public: * * @param v value for the multiplication assigment */ - void operator*=(const Type &v) {PIMM_FOR m[r][c] *= v;} + void operator*=(const Type &v) { + PIMM_FOR m[r][c] *= v; + } /** * @brief Division assignment with value "v" @@ -654,11 +656,10 @@ class PIMathMatrix; /// Matrix -#define PIMM_FOR(c, r) for (uint c = 0; c < _V2D::cols_; ++c) for (uint r = 0; r < _V2D::rows_; ++r) -#define PIMM_FOR_I(c, r) for (uint r = 0; r < _V2D::rows_; ++r) for (uint c = 0; c < _V2D::cols_; ++c) -#define PIMM_FOR_A(v) for (uint v = 0; v < _V2D::mat.size(); ++v) -#define PIMM_FOR_C(v) for (uint v = 0; v < _V2D::cols_; ++v) -#define PIMM_FOR_R(v) for (uint v = 0; v < _V2D::rows_; ++v) +#define PIMM_FOR for (uint r = 0; r < _V2D::rows_; ++r) for (uint c = 0; c < _V2D::cols_; ++c) +#define PIMM_FOR_A for (uint i = 0; i < _V2D::mat.size(); ++i) +#define PIMM_FOR_C for (uint i = 0; i < _V2D::cols_; ++i) +#define PIMM_FOR_R for (uint i = 0; i < _V2D::rows_; ++i) //! \brief A class that works with matrix operations, the input data of which is the data type of the matrix //! @tparam There are can be basic C++ language data and different classes where the arithmetic operators(=, +=, -=, *=, /=, ==, !=, +, -, *, /) @@ -667,7 +668,6 @@ template class PIP_EXPORT PIMathMatrix : public PIVector2D { typedef PIVector2D _V2D; typedef PIMathMatrix _CMatrix; - typedef PIMathVector _CMCol; public: /** * @brief Constructor of class PIMathMatrix, which creates a matrix @@ -688,7 +688,7 @@ public: PIMathMatrix(const uint cols, const uint rows, const PIVector &val) { _V2D::resize(rows, cols); int i = 0; - PIMM_FOR_I(c, r) _V2D::element(r, c) = val[i++]; + PIMM_FOR _V2D::element(r, c) = val[i++]; } /** @@ -699,7 +699,11 @@ public: PIMathMatrix(const PIVector > &val) { if (!val.isEmpty()) { _V2D::resize(val.size(), val[0].size()); - PIMM_FOR_I(c, r) _V2D::element(r, c) = val[r][c]; + for (uint r = 0; r < _V2D::rows_; ++r) { + assert(val[r].size() == _V2D::cols_); + for (uint c = 0; c < _V2D::cols_; ++c) + _V2D::element(r, c) = val[r][c]; + } } } @@ -711,7 +715,7 @@ public: PIMathMatrix(const PIVector2D &val) { if (!val.isEmpty()) { _V2D::resize(val.rows(), val.cols()); - PIMM_FOR_I(c, r) _V2D::element(r, c) = val.element(r, c); + PIMM_FOR _V2D::element(r, c) = val.element(r, c); } } @@ -728,26 +732,13 @@ public: return tm; } - /** - * @brief Creates a matrix filled by zeros - * - * @param cols is number of matrix column uint type - * @param rows is number of matrix row uint type - * @return zero matrix(cols,rows) - */ - static _CMatrix zero(const uint cols, const uint rows) { - _CMatrix tm(cols, rows); - tm.fill(Type(0)); - return tm; - } - /** * @brief Creates a row matrix of every element that is equal to every element of the vector * * @param val is the vector type PIMathVector * @return row matrix of every element that is equal to every element of the vector */ - static _CMatrix matrixRow(const PIMathVector &val) { return _CMatrix(val.size(), 1, val.toVector()); } + static _CMatrix matrixRow(const PIMathVector &val) {return _CMatrix(val.size(), 1, val.toVector());} /** * @brief Creates a column matrix of every element that is equal to every element of the vector @@ -755,18 +746,19 @@ public: * @param val is the vector type PIMathVector * @return column matrix of every element that is equal to every element of the vector */ - static _CMatrix matrixCol(const PIMathVector &val) { return _CMatrix(1, val.size(), val.toVector()); } + static _CMatrix matrixCol(const PIMathVector &val) {return _CMatrix(1, val.size(), val.toVector());} /** * @brief Set the selected column in matrix. If there are more elements of the vector than elements in the column of the matrix - * or index larger than the number of columns otherwise there will be "undefined behavior" + * or index larger than the number of columns otherwise there will be "undefined behavior" * * @param index is the number of the selected column * @param v is a vector of the type _CMCol that needs to fill the column * @return matrix type _CMatrix */ - _CMatrix &setCol(uint index, const _CMCol &v) { - PIMM_FOR_R(i) _V2D::element(i, index) = v[i]; + _CMatrix &setCol(uint index, const PIMathVector &v) { + assert(_V2D::rows == v.size()); + PIMM_FOR_R _V2D::element(i, index) = v[i]; return *this; } @@ -777,8 +769,9 @@ public: * @param v is a vector of the type _CMCol that needs to fill the row * @return matrix type _CMatrix */ - _CMatrix &setRow(uint index, const _CMCol &v) { - PIMM_FOR_C(i) _V2D::element(index, i) = v[i]; + _CMatrix &setRow(uint index, const PIMathVector &v) { + assert(_V2D::cols == v.size()); + PIMM_FOR_C _V2D::element(index, i) = v[i]; return *this; } @@ -791,7 +784,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &swapCols(uint r0, uint r1) { - PIMM_FOR_C(i) { piSwap(_V2D::element(i, r0), _V2D::element(i, r1)); } + PIMM_FOR_C piSwap(_V2D::element(i, r0), _V2D::element(i, r1)); return *this; } @@ -804,7 +797,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &swapRows(uint c0, uint c1) { - PIMM_FOR_R(i) { piSwap(_V2D::element(c0, i), _V2D::element(c1, i)); } + PIMM_FOR_R piSwap(_V2D::element(c0, i), _V2D::element(c1, i)); return *this; } @@ -815,7 +808,7 @@ public: * @return filled matrix type _CMatrix */ _CMatrix &fill(const Type &v) { - PIMM_FOR_A(i) _V2D::mat[i] = v; + PIMM_FOR_A _V2D::mat[i] = v; return *this; } @@ -832,7 +825,7 @@ public: * @return true if matrix is identity, else false */ bool isIdentity() const { - PIMM_FOR(c, r) if ((c == r) ? _V2D::element(r, c) != Type(1) : _V2D::element(r, c) != Type(0))return false; + PIMM_FOR if ((c == r) ? _V2D::element(r, c) != Type(1) : _V2D::element(r, c) != Type(0))return false; return true; } @@ -842,7 +835,7 @@ public: * @return true if matrix elements equal to zero, else false */ bool isNull() const { - PIMM_FOR_A(i) if (_V2D::mat[i] != Type(0)) return false; + PIMM_FOR_A if (_V2D::mat[i] != Type(0)) return false; return true; } @@ -861,7 +854,7 @@ public: void operator+=(const _CMatrix &sm) { assert(_V2D::rows() == sm.rows()); assert(_V2D::cols() == sm.cols()); - PIMM_FOR_A(i) _V2D::mat[i] += sm.mat[i]; + PIMM_FOR_A _V2D::mat[i] += sm.mat[i]; } /** @@ -872,7 +865,7 @@ public: void operator-=(const _CMatrix &sm) { assert(_V2D::rows() == sm.rows()); assert(_V2D::cols() == sm.cols()); - PIMM_FOR_A(i) _V2D::mat[i] -= sm.mat[i]; + PIMM_FOR_A _V2D::mat[i] -= sm.mat[i]; } /** @@ -880,14 +873,19 @@ public: * * @param v value for the multiplication assigment */ - void operator*=(const Type &v) { PIMM_FOR_A(i) _V2D::mat[i] *= v; } + void operator*=(const Type &v) { + PIMM_FOR_A _V2D::mat[i] *= v; + } /** * @brief Division assignment with value "v" * * @param v value for the division assigment */ - void operator/=(const Type &v) { PIMM_FOR_A(i) _V2D::mat[i] /= v; } + void operator/=(const Type &v) { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); + PIMM_FOR_A _V2D::mat[i] /= v; + } /** * @brief Matrix substraction @@ -896,7 +894,7 @@ public: */ _CMatrix operator-() const { _CMatrix tm(*this); - PIMM_FOR_A(i) tm.mat[i] = -_V2D::mat[i]; + PIMM_FOR_A tm.mat[i] = -_V2D::mat[i]; return tm; } @@ -910,7 +908,7 @@ public: _CMatrix tm(*this); assert(tm.rows() == sm.rows()); assert(tm.cols() == sm.cols()); - PIMM_FOR_A(i) tm.mat[i] += sm.mat[i]; + PIMM_FOR_A tm.mat[i] += sm.mat[i]; return tm; } @@ -924,7 +922,7 @@ public: _CMatrix tm(*this); assert(tm.rows() == sm.rows()); assert(tm.cols() == sm.cols()); - PIMM_FOR_A(i) tm.mat[i] -= sm.mat[i]; + PIMM_FOR_A tm.mat[i] -= sm.mat[i]; return tm; } @@ -936,7 +934,7 @@ public: */ _CMatrix operator*(const Type &v) const { _CMatrix tm(*this); - PIMM_FOR_A(i) tm.mat[i] *= v; + PIMM_FOR_A tm.mat[i] *= v; return tm; } @@ -947,8 +945,9 @@ public: * @return the result of matrix division */ _CMatrix operator/(const Type &v) const { + assert(piAbs(v) > PIMATHVECTOR_ZERO_CMP); _CMatrix tm(*this); - PIMM_FOR_A(i) tm.mat[i] /= v; + PIMM_FOR_A tm.mat[i] /= v; return tm; } @@ -1042,7 +1041,7 @@ public: * @param sv is a vector multiplier * @return copy of inverted matrix */ - _CMatrix &invert(bool *ok = 0, _CMCol *sv = 0) { + _CMatrix &invert(bool *ok = 0, PIMathVector *sv = 0) { if (!isSquare()) { if (ok != 0) *ok = false; return *this; @@ -1116,7 +1115,7 @@ public: */ _CMatrix transposed() const { _CMatrix tm(_V2D::rows_, _V2D::cols_); - PIMM_FOR(c, r) tm.element(c, r) = _V2D::element(r, c); + PIMM_FOR tm.element(c, r) = _V2D::element(r, c); return tm; } }; @@ -1276,7 +1275,6 @@ PIMathMatrix > hermitian(const PIMathMatrix > &m) { } #undef PIMM_FOR -#undef PIMM_FOR_I #undef PIMM_FOR_A #undef PIMM_FOR_C #undef PIMM_FOR_R From fbe850abf0732ca7f423afb46eb429f0a1fd7cab Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 22 Oct 2020 17:29:58 +0300 Subject: [PATCH 09/11] template math functions in pimathmatrix.h and pimathvector.h and pimathbase.h add PIMathMatrixT::rotate for matrix 2x2 --- libs/main/math/pimathbase.h | 20 +++++++++----------- libs/main/math/pimathmatrix.h | 16 ++++++++++++++-- libs/main/math/pimathvector.h | 14 +++++++------- main.cpp | 4 ++++ 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/libs/main/math/pimathbase.h b/libs/main/math/pimathbase.h index 0841ac4c..553437f5 100644 --- a/libs/main/math/pimathbase.h +++ b/libs/main/math/pimathbase.h @@ -98,9 +98,6 @@ const double rad2deg = M_180_PI; inline int sign(const float & x) {return (x < 0.) ? -1 : (x > 0. ? 1 : 0);} inline int sign(const double & x) {return (x < 0.) ? -1 : (x > 0. ? 1 : 0);} inline int pow2(const int p) {return 1 << p;} -inline int sqr(const int v) {return v * v;} -inline float sqr(const float & v) {return v * v;} -inline double sqr(const double & v) {return v * v;} inline double sinc(const double & v) {if (v == 0.) return 1.; double t = M_PI * v; return sin(t) / t;} PIP_EXPORT double piJ0(const double & v); @@ -109,22 +106,23 @@ PIP_EXPORT double piJn(int n, const double & v); PIP_EXPORT double piY0(const double & v); PIP_EXPORT double piY1(const double & v); PIP_EXPORT double piYn(int n, const double & v); -inline double toDb(double val) {return 10. * log10(val);} -inline double fromDb(double val) {return pow(10., val / 10.);} -inline double toRad(double deg) {return deg * M_PI_180;} -inline double toDeg(double rad) {return rad * M_180_PI;} + +template inline constexpr T toDb(T val) {return T(10.) * std::log10(val);} +template inline constexpr T fromDb(T val) {return std::pow(T(10.), val / T(10.));} +template inline constexpr T toRad(T deg) {return deg * T(M_PI_180);} +template inline constexpr T toDeg(T rad) {return rad * T(M_180_PI);} +template inline constexpr T sqr(const T & v) {return v * v;} // [-1 ; 1] PIP_EXPORT double randomd(); // [-1 ; 1] normal PIP_EXPORT double randomn(double dv = 0., double sv = 1.); - -inline PIVector abs(const PIVector & v) { - PIVector result; +template inline PIVector piAbs(const PIVector & v) { + PIVector result; result.resize(v.size()); for (uint i = 0; i < v.size(); i++) - result[i] = fabs(v[i]); + result[i] = piAbs(v[i]); return result; } diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index b495d90d..2d9dffd1 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -425,7 +425,7 @@ public: for (uint k = i; k < Cols; ++k) smat.m[k][j] -= mul * smat.m[k][i]; } if (i < Cols - 1) { - if (fabs(smat.m[i + 1][i + 1]) < Type(1E-200)) { + if (piAbs(smat.m[i + 1][i + 1]) < Type(1E-200)) { if (ok != 0) *ok = false; return *this; } @@ -469,7 +469,7 @@ public: for (uint k = 0; k < Cols; ++k) mtmp.m[k][j] -= mul * mtmp.m[k][i]; } if (i < Cols - 1) { - if (fabs(smat.m[i + 1][i + 1]) < Type(1E-200)) { + if (piAbs(smat.m[i + 1][i + 1]) < Type(1E-200)) { if (ok != 0) *ok = false; return *this; } @@ -513,6 +513,18 @@ public: return tm; } + _CMatrix rotate(Type angle) { + static_assert(Rows == 2 && Cols == 2, "Works only with 2x2 matrix"); + Type c = std::cos(angle); + Type s = std::sin(angle); + PIMathMatrixT<2u, 2u> tm; + tm[0][0] = tm[1][1] = c; + tm[0][1] = -s; + tm[1][0] = s; + *this = *this * tm; + return *this; + } + private: Type m[Rows][Cols]; }; diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index a19ae5e3..547b03bb 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -69,7 +69,7 @@ public: PIMV_FOR tv += c[i] * c[i]; return tv; } - Type length() const {return sqrt(lengthSqr());} + Type length() const {return std::sqrt(lengthSqr());} Type manhattanLength() const { Type tv(0); PIMV_FOR tv += piAbs(c[i]); @@ -82,10 +82,10 @@ public: } Type angleSin(const _CVector & v) const { Type tv = angleCos(v); - return sqrt(Type(1) - tv * tv); + return std::sqrt(Type(1) - tv * tv); } - Type angleRad(const _CVector & v) const {return acos(angleCos(v));} - Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} + Type angleRad(const _CVector & v) const {return std::acos(angleCos(v));} + Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} Type angleElevation(const _CVector & v) const {return 90.0 - angleDeg(v - *this);} _CVector projection(const _CVector & v) { Type tv = v.length(); @@ -302,7 +302,7 @@ public: PIMV_FOR tv += c[i] * c[i]; return tv; } - Type length() const {return sqrt(lengthSqr());} + Type length() const {return std::sqrt(lengthSqr());} Type manhattanLength() const { Type tv(0); PIMV_FOR tv += piAbs(c[i]); @@ -317,9 +317,9 @@ public: Type angleSin(const _CVector & v) const { assert(c.size() == v.size()); Type tv = angleCos(v); - return sqrt(Type(1) - tv * tv); + return std::sqrt(Type(1) - tv * tv); } - Type angleRad(const _CVector & v) const {return acos(angleCos(v));} + Type angleRad(const _CVector & v) const {return std::acos(angleCos(v));} Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} _CVector projection(const _CVector & v) { assert(c.size() == v.size()); diff --git a/main.cpp b/main.cpp index 10dfb678..0f49cc37 100644 --- a/main.cpp +++ b/main.cpp @@ -45,5 +45,9 @@ int main() { PIMathVectord v2({3,2,1}); piCout << v; piCout << v2; + PIMathMatrixT22d m = PIMathMatrixT22d::identity(); + piCout << m; + m.rotate(toRad(90.)); + piCout << m; return 0; } From 91c1487a7e73186beab3df61ecfe180a855697c7 Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 22 Oct 2020 17:45:42 +0300 Subject: [PATCH 10/11] toDeg and toRad --- libs/main/math/pimathbase.h | 8 ++++++-- libs/main/math/pimathvector.h | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libs/main/math/pimathbase.h b/libs/main/math/pimathbase.h index 553437f5..d270c619 100644 --- a/libs/main/math/pimathbase.h +++ b/libs/main/math/pimathbase.h @@ -109,8 +109,12 @@ PIP_EXPORT double piYn(int n, const double & v); template inline constexpr T toDb(T val) {return T(10.) * std::log10(val);} template inline constexpr T fromDb(T val) {return std::pow(T(10.), val / T(10.));} -template inline constexpr T toRad(T deg) {return deg * T(M_PI_180);} -template inline constexpr T toDeg(T rad) {return rad * T(M_180_PI);} +inline constexpr float toRad(float deg) {return deg * M_PI_180;} +inline constexpr double toRad(double deg) {return deg * M_PI_180;} +inline constexpr long double toRad(long double deg) {return deg * M_PI_180;} +inline constexpr float toDeg(float rad) {return rad * M_180_PI;} +inline constexpr double toDeg(double rad) {return rad * M_180_PI;} +inline constexpr long double toDeg(long double rad) {return rad * M_180_PI;} template inline constexpr T sqr(const T & v) {return v * v;} // [-1 ; 1] diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index 547b03bb..a98cef49 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -85,7 +85,7 @@ public: return std::sqrt(Type(1) - tv * tv); } Type angleRad(const _CVector & v) const {return std::acos(angleCos(v));} - Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} + Type angleDeg(const _CVector & v) const {return toDeg(angleRad(v));} Type angleElevation(const _CVector & v) const {return 90.0 - angleDeg(v - *this);} _CVector projection(const _CVector & v) { Type tv = v.length(); From c79f39ad2a2d37c297681a55e7063d5e6bc4cb17 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 22 Oct 2020 18:03:22 +0300 Subject: [PATCH 11/11] cosmetic --- libs/main/core/piobject.h | 2 +- libs/main/core/piobject_macros.h | 136 +++++++++++++++++++++++-------- libs/main/core/pistring_std.h | 8 +- libs/main/math/pimathbase.h | 21 ++--- libs/main/math/pimathmatrix.h | 2 +- 5 files changed, 118 insertions(+), 51 deletions(-) diff --git a/libs/main/core/piobject.h b/libs/main/core/piobject.h index e85b30c0..939ebb0e 100644 --- a/libs/main/core/piobject.h +++ b/libs/main/core/piobject.h @@ -1,7 +1,7 @@ /*! \file piobject.h * \brief Base object * - * This file declare PIObject class and associated macros + * This file declare PIObject class */ /* PIP - Platform Independent Primitives diff --git a/libs/main/core/piobject_macros.h b/libs/main/core/piobject_macros.h index 261c4531..1f0d27a5 100644 --- a/libs/main/core/piobject_macros.h +++ b/libs/main/core/piobject_macros.h @@ -1,7 +1,7 @@ -/*! \file piobject.h +/*! \file piobject_macros.h * \brief Base object * - * This file declare PIObject class and associated macros + * This file declare macros for PIObject */ /* PIP - Platform Independent Primitives @@ -25,8 +25,6 @@ #ifndef PIOBJECT_MACROS_H #define PIOBJECT_MACROS_H -//#include "piobject_macros.h" - #ifdef DOXYGEN @@ -385,43 +383,63 @@ #define EVENT_VHANDLER0(ret, name) \ EH_INIT0(ret, name) \ - static ret __stat_eh_##name##__(void * __o__) {return ((__PIObject__*)__o__)->name();} \ + static ret __stat_eh_##name##__(void * __o__) { \ + return ((__PIObject__*)__o__)->name();} \ virtual ret name() #define EVENT_VHANDLER1(ret, name, a0, n0) \ EH_INIT1(ret, name, a0, n0) \ - static ret __stat_eh_##name##__(void * __o__, a0 n0) {return ((__PIObject__*)__o__)->name(n0);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0));} \ + static ret __stat_eh_##name##__(void * __o__, a0 n0) { \ + return ((__PIObject__*)__o__)->name(n0);} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) { \ + return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0));} \ virtual ret name(a0 n0) #define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \ EH_INIT2(ret, name, a0, n0, a1, n1) \ - static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) {return ((__PIObject__*)__o__)->name(n0, n1);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1));} \ + static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) { \ + return ((__PIObject__*)__o__)->name(n0, n1);} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1) { \ + return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1));} \ virtual ret name(a0 n0, a1 n1) #define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \ EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \ - static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) {return ((__PIObject__*)__o__)->name(n0, n1, n2);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2));} \ + static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) { \ + return ((__PIObject__*)__o__)->name(n0, n1, n2);} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2) { \ + return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2));} \ virtual ret name(a0 n0, a1 n1, a2 n2) #define EVENT_VHANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ - static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) {return ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \ - static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2), __VVALUE(a3, v3));} \ + static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) { \ + return ((__PIObject__*)__o__)->name(n0, n1, n2, n3);} \ + static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1, const PIVariantSimple & v2, const PIVariantSimple & v3) { \ + return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2), __VVALUE(a3, v3));} \ virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3) #define EVENT_VHANDLER EVENT_VHANDLER0 -#define EVENT0(name) EVENT_HANDLER0(void, name) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid);} -#define EVENT1(name, a0, n0) EVENT_HANDLER1(void, name, a0, n0) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0);} -#define EVENT2(name, a0, n0, a1, n1) EVENT_HANDLER2(void, name, a0, n0, a1, n1) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1);} -#define EVENT3(name, a0, n0, a1, n1, a2, n2) EVENT_HANDLER3(void, name, a0, n0, a1, n1, a2, n2) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1, n2);} -#define EVENT4(name, a0, n0, a1, n1, a2, n2, a3, n3) EVENT_HANDLER4(void, name, a0, n0, a1, n1, a2, n2, a3, n3) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1, n2, n3);} +#define EVENT0(name) EVENT_HANDLER0(void, name) { \ + static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid);} + +#define EVENT1(name, a0, n0) EVENT_HANDLER1(void, name, a0, n0) { \ + static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0);} + +#define EVENT2(name, a0, n0, a1, n1) EVENT_HANDLER2(void, name, a0, n0, a1, n1) { \ + static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1);} + +#define EVENT3(name, a0, n0, a1, n1, a2, n2) EVENT_HANDLER3(void, name, a0, n0, a1, n1, a2, n2) { \ + static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1, n2);} + +#define EVENT4(name, a0, n0, a1, n1, a2, n2, a3, n3) EVENT_HANDLER4(void, name, a0, n0, a1, n1, a2, n2, a3, n3) { \ + static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0, n1, n2, n3);} + #define EVENT EVENT0 + #define RAISE_EVENT0(src, event) (src)->event(); #define RAISE_EVENT1(src, event, v0) (src)->event(v0); #define RAISE_EVENT2(src, event, v0, v1) (src)->event(v0, v1); @@ -429,35 +447,81 @@ #define RAISE_EVENT4(src, event, v0, v1, v2, v3) (src)->event(v0, v1, v2, v3); #define RAISE_EVENT RAISE_EVENT0 -#define CONNECTU(src, event, dest, handler) PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION); -#define CONNECTU_QUEUED(src, event, dest, handler, performer) PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION, performer); -#define CONNECTL(src, event, functor) PIObject::piConnectLS(src, PIStringAscii(#event), PIObject::__newFunctor(&(src)->__stat_eh_##event##__, functor), LOCATION); -#define CONNECT0(ret, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*))(&(src)->__stat_eh_##event##__), 0, LOCATION); -#define CONNECT1(ret, a0, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0))(&(src)->__stat_eh_##event##__), 1, LOCATION); -#define CONNECT2(ret, a0, a1, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1))(&(src)->__stat_eh_##event##__), 2, LOCATION); -#define CONNECT3(ret, a0, a1, a2, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1, a2))(&(src)->__stat_eh_##event##__), 3, LOCATION); -#define CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0, a1, a2, a3))(&(src)->__stat_eh_##event##__), 4, LOCATION); +#define CONNECTU(src, event, dest, handler) \ + PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION); + +#define CONNECTU_QUEUED(src, event, dest, handler, performer) \ + PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION, performer); + +#define CONNECTL(src, event, functor) \ + PIObject::piConnectLS(src, PIStringAscii(#event), PIObject::__newFunctor(&(src)->__stat_eh_##event##__, functor), LOCATION); + + +#define CONNECT0(ret, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), \ + (void*)(void(*)(void*))(&(src)->__stat_eh_##event##__), 0, LOCATION); + +#define CONNECT1(ret, a0, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), \ + (void*)(void(*)(void*, a0))(&(src)->__stat_eh_##event##__), 1, LOCATION); + +#define CONNECT2(ret, a0, a1, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__), \ + (void*)(void(*)(void*, a0, a1))(&(src)->__stat_eh_##event##__), 2, LOCATION); + +#define CONNECT3(ret, a0, a1, a2, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), \ + (void*)(void(*)(void*, a0, a1, a2))(&(src)->__stat_eh_##event##__), 3, LOCATION); + +#define CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), \ + (void*)(void(*)(void*, a0, a1, a2, a3))(&(src)->__stat_eh_##event##__), 4, LOCATION); + #define CONNECT CONNECT0 -#define WEAK_CONNECT0(ret, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), 0, 0, LOCATION); -#define WEAK_CONNECT1(ret, a0, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), 0, 1, LOCATION); -#define WEAK_CONNECT2(ret, a0, a1, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__), 0, 2, LOCATION); -#define WEAK_CONNECT3(ret, a0, a1, a2, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), 0, 3, LOCATION); -#define WEAK_CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), 0, 4, LOCATION); + +#define WEAK_CONNECT0(ret, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), 0, 0, LOCATION); + +#define WEAK_CONNECT1(ret, a0, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), 0, 1, LOCATION); + +#define WEAK_CONNECT2(ret, a0, a1, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__), 0, 2, LOCATION); + +#define WEAK_CONNECT3(ret, a0, a1, a2, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), 0, 3, LOCATION); + +#define WEAK_CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) \ + PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), 0, 4, LOCATION); + #define WEAK_CONNECT WEAK_CONNECT0 -#define DISCONNECT0(ret, src, event, dest, handler) PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__)); -#define DISCONNECT1(ret, a0, src, event, dest, handler) PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__)); -#define DISCONNECT2(ret, a0, a1, src, event, dest, handler) PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__)); -#define DISCONNECT3(ret, a0, a1, a2, src, event, dest, handler) PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__)); -#define DISCONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__)); + +#define DISCONNECT0(ret, src, event, dest, handler) \ + PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__)); + +#define DISCONNECT1(ret, a0, src, event, dest, handler) \ + PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__)); + +#define DISCONNECT2(ret, a0, a1, src, event, dest, handler) \ + PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1))(&(dest)->__stat_eh_##handler##__)); + +#define DISCONNECT3(ret, a0, a1, a2, src, event, dest, handler) \ + PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1, a2))(&(dest)->__stat_eh_##handler##__)); + +#define DISCONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) \ + PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__)); + #define DISCONNECT DISCONNECT0 + #define HANDLER(handler) __stat_eh_##handler##__ #define __PIOBJECT_SIGNATURE__ 0xabcdbadc + #endif diff --git a/libs/main/core/pistring_std.h b/libs/main/core/pistring_std.h index 8d1d05e1..909c5348 100644 --- a/libs/main/core/pistring_std.h +++ b/libs/main/core/pistring_std.h @@ -1,5 +1,5 @@ -/*! \file pistring.h - * \brief String +/*! \file pistring_std.h + * \brief STD for PIString * * This file declare std operators and string conversions */ @@ -23,11 +23,12 @@ */ #ifndef PISTRING_STD_H #define PISTRING_STD_H + + #include #ifdef QNX typedef std::basic_string wstring; #endif - #include "pistringlist.h" @@ -97,4 +98,5 @@ inline std::ostream & operator <<(std::ostream & s, const PIStringList & v) { return s; } + #endif // PISTRING_STD_H diff --git a/libs/main/math/pimathbase.h b/libs/main/math/pimathbase.h index d270c619..ee845dd8 100644 --- a/libs/main/math/pimathbase.h +++ b/libs/main/math/pimathbase.h @@ -95,8 +95,9 @@ const double deg2rad = M_PI_180; const double rad2deg = M_180_PI; -inline int sign(const float & x) {return (x < 0.) ? -1 : (x > 0. ? 1 : 0);} -inline int sign(const double & x) {return (x < 0.) ? -1 : (x > 0. ? 1 : 0);} +inline int sign(const float & x) {return (x < 0.f) ? -1 : (x > 0.f ? 1 : 0);} +inline int sign(const double & x) {return (x < 0. ) ? -1 : (x > 0. ? 1 : 0);} +inline int sign(const ldouble & x) {return (x < 0.L) ? -1 : (x > 0.L ? 1 : 0);} inline int pow2(const int p) {return 1 << p;} inline double sinc(const double & v) {if (v == 0.) return 1.; double t = M_PI * v; return sin(t) / t;} @@ -107,15 +108,15 @@ PIP_EXPORT double piY0(const double & v); PIP_EXPORT double piY1(const double & v); PIP_EXPORT double piYn(int n, const double & v); -template inline constexpr T toDb(T val) {return T(10.) * std::log10(val);} -template inline constexpr T fromDb(T val) {return std::pow(T(10.), val / T(10.));} -inline constexpr float toRad(float deg) {return deg * M_PI_180;} -inline constexpr double toRad(double deg) {return deg * M_PI_180;} -inline constexpr long double toRad(long double deg) {return deg * M_PI_180;} -inline constexpr float toDeg(float rad) {return rad * M_180_PI;} -inline constexpr double toDeg(double rad) {return rad * M_180_PI;} -inline constexpr long double toDeg(long double rad) {return rad * M_180_PI;} +inline constexpr float toRad(float deg) {return deg * M_PI_180;} +inline constexpr double toRad(double deg) {return deg * M_PI_180;} +inline constexpr ldouble toRad(ldouble deg) {return deg * M_PI_180;} +inline constexpr float toDeg(float rad) {return rad * M_180_PI;} +inline constexpr double toDeg(double rad) {return rad * M_180_PI;} +inline constexpr ldouble toDeg(ldouble rad) {return rad * M_180_PI;} template inline constexpr T sqr(const T & v) {return v * v;} +template inline constexpr T toDb (T val) {return T(10.) * std::log10(val);} +template inline constexpr T fromDb(T val) {return std::pow(T(10.), val / T(10.));} // [-1 ; 1] PIP_EXPORT double randomd(); diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 2d9dffd1..8f4304b0 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -809,7 +809,7 @@ public: * @return matrix type _CMatrix */ _CMatrix &swapRows(uint c0, uint c1) { - PIMM_FOR_R piSwap(_V2D::element(c0, i), _V2D::element(c1, i)); + PIMM_FOR_R piSwap(_V2D::element(c0, i), _V2D::element(c1, i)); return *this; }