Merge pull request 'vectors&matrixes' (#48) from vectors&matrixes into master

Reviewed-on: https://git.shs.tools/SHS/pip/pulls/48
This commit was merged in pull request #48.
This commit is contained in:
2020-10-22 18:04:49 +03:00
11 changed files with 683 additions and 530 deletions

View File

@@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0017 NEW) # need include() with .cmake cmake_policy(SET CMP0017 NEW) # need include() with .cmake
project(pip) project(pip)
set(pip_MAJOR 2) set(pip_MAJOR 2)
set(pip_MINOR 13) set(pip_MINOR 14)
set(pip_REVISION 0) set(pip_REVISION 0)
set(pip_SUFFIX beta) set(pip_SUFFIX alpha)
set(pip_COMPANY SHS) set(pip_COMPANY SHS)
set(pip_DOMAIN org.SHS) set(pip_DOMAIN org.SHS)

View File

@@ -358,7 +358,7 @@ inline bool piCompareBinary(const void * f, const void * s, size_t size) {
* *
* Example: * Example:
* \snippet piincludes.cpp round */ * \snippet piincludes.cpp round */
template<typename T> inline int piRound(const T & v) {return int(v >= T(0.) ? v + T(0.5) : v - T(0.5));} template<typename T> 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 /*! \brief Templated function return floor of float falue
* \details Floor is the largest integer that is not greater than value \n * \details Floor is the largest integer that is not greater than value \n
@@ -368,7 +368,7 @@ template<typename T> inline int piRound(const T & v) {return int(v >= T(0.) ? v
* *
* Example: * Example:
* \snippet piincludes.cpp floor */ * \snippet piincludes.cpp floor */
template<typename T> inline int piFloor(const T & v) {return v < T(0) ? int(v) - 1 : int(v);} template<typename T> inline constexpr int piFloor(const T & v) {return v < T(0) ? int(v) - 1 : int(v);}
/*! \brief Templated function return ceil of float falue /*! \brief Templated function return ceil of float falue
* \details Ceil is the smallest integer that is not less than value \n * \details Ceil is the smallest integer that is not less than value \n
@@ -378,7 +378,7 @@ template<typename T> inline int piFloor(const T & v) {return v < T(0) ? int(v) -
* *
* Example: * Example:
* \snippet piincludes.cpp ceil */ * \snippet piincludes.cpp ceil */
template<typename T> inline int piCeil(const T & v) {return v < T(0) ? int(v) : int(v) + 1;} template<typename T> inline constexpr int piCeil(const T & v) {return v < T(0) ? int(v) : int(v) + 1;}
/*! \brief Templated function return absolute of numeric falue /*! \brief Templated function return absolute of numeric falue
* \details Absolute is the positive or equal 0 value \n * \details Absolute is the positive or equal 0 value \n
@@ -392,7 +392,7 @@ template<typename T> inline int piCeil(const T & v) {return v < T(0) ? int(v) :
* *
* Example: * Example:
* \snippet piincludes.cpp abs */ * \snippet piincludes.cpp abs */
template<typename T> inline T piAbs(const T & v) {return (v >= T(0) ? v : -v);} template<typename T> inline constexpr T piAbs(const T & v) {return (v >= T(0) ? v : -v);}
/*! \brief Templated function return minimum of two values /*! \brief Templated function return minimum of two values
* \details There are some macros: * \details There are some macros:
@@ -405,7 +405,7 @@ template<typename T> inline T piAbs(const T & v) {return (v >= T(0) ? v : -v);}
* *
* Example: * Example:
* \snippet piincludes.cpp min2 */ * \snippet piincludes.cpp min2 */
template<typename T> inline T piMin(const T & f, const T & s) {return ((f > s) ? s : f);} template<typename T> inline constexpr T piMin(const T & f, const T & s) {return ((f > s) ? s : f);}
/*! \brief Templated function return minimum of tree values /*! \brief Templated function return minimum of tree values
* \details There are some macros: * \details There are some macros:
@@ -418,7 +418,7 @@ template<typename T> inline T piMin(const T & f, const T & s) {return ((f > s) ?
* *
* Example: * Example:
* \snippet piincludes.cpp min3 */ * \snippet piincludes.cpp min3 */
template<typename T> inline T piMin(const T & f, const T & s, const T & t) {return ((f < s && f < t) ? f : ((s < t) ? s : t));} template<typename T> 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 /*! \brief Templated function return maximum of two values
* \details There are some macros: * \details There are some macros:
@@ -431,7 +431,7 @@ template<typename T> inline T piMin(const T & f, const T & s, const T & t) {retu
* *
* Example: * Example:
* \snippet piincludes.cpp max2 */ * \snippet piincludes.cpp max2 */
template<typename T> inline T piMax(const T & f, const T & s) {return ((f < s) ? s : f);} template<typename T> inline constexpr T piMax(const T & f, const T & s) {return ((f < s) ? s : f);}
/*! \brief Templated function return maximum of tree values /*! \brief Templated function return maximum of tree values
* \details There are some macros: * \details There are some macros:
@@ -444,7 +444,7 @@ template<typename T> inline T piMax(const T & f, const T & s) {return ((f < s) ?
* *
* Example: * Example:
* \snippet piincludes.cpp max3 */ * \snippet piincludes.cpp max3 */
template<typename T> inline T piMax(const T & f, const T & s, const T & t) {return ((f > s && f > t) ? f : ((s > t) ? s : t));} template<typename T> 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 /*! \brief Templated function return clamped value
* \details Clamped is the not greater than "max" and not lesser than "min" value \n * \details Clamped is the not greater than "max" and not lesser than "min" value \n
@@ -458,7 +458,7 @@ template<typename T> inline T piMax(const T & f, const T & s, const T & t) {retu
* *
* Example: * Example:
* \snippet piincludes.cpp clamp */ * \snippet piincludes.cpp clamp */
template<typename T> inline T piClamp(const T & v, const T & min, const T & max) {return (v > max ? max : (v < min ? min : v));} template<typename T> 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 /// Function inverse byte order in memory block
inline void piLetobe(void * data, int size) { inline void piLetobe(void * data, int size) {

View File

@@ -1,7 +1,7 @@
/*! \file piobject.h /*! \file piobject.h
* \brief Base object * \brief Base object
* *
* This file declare PIObject class and associated macros * This file declare PIObject class
*/ */
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives

View File

@@ -1,7 +1,7 @@
/*! \file piobject.h /*! \file piobject_macros.h
* \brief Base object * \brief Base object
* *
* This file declare PIObject class and associated macros * This file declare macros for PIObject
*/ */
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
@@ -25,8 +25,6 @@
#ifndef PIOBJECT_MACROS_H #ifndef PIOBJECT_MACROS_H
#define PIOBJECT_MACROS_H #define PIOBJECT_MACROS_H
//#include "piobject_macros.h"
#ifdef DOXYGEN #ifdef DOXYGEN
@@ -385,43 +383,63 @@
#define EVENT_VHANDLER0(ret, name) \ #define EVENT_VHANDLER0(ret, name) \
EH_INIT0(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() virtual ret name()
#define EVENT_VHANDLER1(ret, name, a0, n0) \ #define EVENT_VHANDLER1(ret, name, a0, n0) \
EH_INIT1(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_##name##__(void * __o__, a0 n0) { \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) {return ((__PIObject__*)__o__)->name(__VVALUE(a0, v0));} \ 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) virtual ret name(a0 n0)
#define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \ #define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \
EH_INIT2(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_##name##__(void * __o__, a0 n0, a1 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));} \ 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) virtual ret name(a0 n0, a1 n1)
#define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \ #define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \
EH_INIT3(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_##name##__(void * __o__, a0 n0, a1 n1, a2 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));} \ 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) virtual ret name(a0 n0, a1 n1, a2 n2)
#define EVENT_VHANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \ #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) \ 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_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 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));} \ 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) virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)
#define EVENT_VHANDLER EVENT_VHANDLER0 #define EVENT_VHANDLER EVENT_VHANDLER0
#define EVENT0(name) EVENT_HANDLER0(void, name) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid);} #define EVENT0(name) EVENT_HANDLER0(void, name) { \
#define EVENT1(name, a0, n0) EVENT_HANDLER1(void, name, a0, n0) {static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid, n0);} static uint eid = PIStringAscii(#name).hash(); PIObject::raiseEvent(this, eid);}
#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 EVENT1(name, a0, n0) EVENT_HANDLER1(void, name, a0, n0) { \
#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);} 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 EVENT EVENT0
#define RAISE_EVENT0(src, event) (src)->event(); #define RAISE_EVENT0(src, event) (src)->event();
#define RAISE_EVENT1(src, event, v0) (src)->event(v0); #define RAISE_EVENT1(src, event, v0) (src)->event(v0);
#define RAISE_EVENT2(src, event, v0, v1) (src)->event(v0, v1); #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_EVENT4(src, event, v0, v1, v2, v3) (src)->event(v0, v1, v2, v3);
#define RAISE_EVENT RAISE_EVENT0 #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 CONNECTU(src, event, dest, handler) \
#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); PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), 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 CONNECTU_QUEUED(src, event, dest, handler, performer) \
#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); 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 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_CONNECT0(ret, src, event, dest, handler) \
#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); PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), 0, 0, 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_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 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 DISCONNECT0(ret, src, event, dest, 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##__)); PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void*)(ret(*)(void*))(&(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 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 DISCONNECT DISCONNECT0
#define HANDLER(handler) __stat_eh_##handler##__ #define HANDLER(handler) __stat_eh_##handler##__
#define __PIOBJECT_SIGNATURE__ 0xabcdbadc #define __PIOBJECT_SIGNATURE__ 0xabcdbadc
#endif #endif

View File

@@ -1,5 +1,5 @@
/*! \file pistring.h /*! \file pistring_std.h
* \brief String * \brief STD for PIString
* *
* This file declare std operators and string conversions * This file declare std operators and string conversions
*/ */
@@ -23,11 +23,12 @@
*/ */
#ifndef PISTRING_STD_H #ifndef PISTRING_STD_H
#define PISTRING_STD_H #define PISTRING_STD_H
#include <string> #include <string>
#ifdef QNX #ifdef QNX
typedef std::basic_string<wchar_t> wstring; typedef std::basic_string<wchar_t> wstring;
#endif #endif
#include "pistringlist.h" #include "pistringlist.h"
@@ -97,4 +98,5 @@ inline std::ostream & operator <<(std::ostream & s, const PIStringList & v) {
return s; return s;
} }
#endif // PISTRING_STD_H #endif // PISTRING_STD_H

View File

@@ -95,12 +95,10 @@
const double deg2rad = M_PI_180; const double deg2rad = M_PI_180;
const double rad2deg = M_180_PI; const double rad2deg = M_180_PI;
inline int sign(const float & 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 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 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;} 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); PIP_EXPORT double piJ0(const double & v);
@@ -109,22 +107,27 @@ PIP_EXPORT double piJn(int n, const double & v);
PIP_EXPORT double piY0(const double & v); PIP_EXPORT double piY0(const double & v);
PIP_EXPORT double piY1(const double & v); PIP_EXPORT double piY1(const double & v);
PIP_EXPORT double piYn(int n, 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 constexpr float toRad(float deg) {return deg * M_PI_180;}
inline double toRad(double deg) {return deg * M_PI_180;} inline constexpr double toRad(double deg) {return deg * M_PI_180;}
inline double toDeg(double rad) {return rad * M_180_PI;} 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 <typename T> inline constexpr T sqr(const T & v) {return v * v;}
template <typename T> inline constexpr T toDb (T val) {return T(10.) * std::log10(val);}
template <typename T> inline constexpr T fromDb(T val) {return std::pow(T(10.), val / T(10.));}
// [-1 ; 1] // [-1 ; 1]
PIP_EXPORT double randomd(); PIP_EXPORT double randomd();
// [-1 ; 1] normal // [-1 ; 1] normal
PIP_EXPORT double randomn(double dv = 0., double sv = 1.); PIP_EXPORT double randomn(double dv = 0., double sv = 1.);
template<typename T> inline PIVector<T> piAbs(const PIVector<T> & v) {
inline PIVector<double> abs(const PIVector<double> & v) { PIVector<T> result;
PIVector<double> result;
result.resize(v.size()); result.resize(v.size());
for (uint i = 0; i < v.size(); i++) for (uint i = 0; i < v.size(); i++)
result[i] = fabs(v[i]); result[i] = piAbs<T>(v[i]);
return result; return result;
} }

View File

@@ -31,12 +31,9 @@
/// Matrix templated /// Matrix templated
#define PIMM_FOR(r, c) for (uint c = 0; c < Cols; ++c) { for (uint r = 0; r < Rows; ++r) { #define PIMM_FOR for (uint r = 0; r < Rows; ++r) for (uint c = 0; c < Cols; ++c)
#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_C for (uint i = 0; i < Cols; ++i)
#define PIMM_FOR_I(r, c) for (uint r = 0; r < Rows; ++r) { for (uint c = 0; c < Cols; ++c) { #define PIMM_FOR_R for (uint i = 0; i < Rows; ++i)
#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)
#pragma pack(push, 1) #pragma pack(push, 1)
@@ -56,22 +53,26 @@ class PIP_EXPORT PIMathMatrixT {
static_assert(Cols > 0, "Column count must be > 0"); static_assert(Cols > 0, "Column count must be > 0");
public: public:
/** /**
* @brief Constructor that calls the private resize method * @brief Constructs PIMathMatrixT that is filled by \a new_value
*
* @return identitied matrix of type PIMathMatrixT
*/ */
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 * @brief Contructs PIMathMatrixT from PIVector
*
* @param val is the PIVector with which the matrix is filled
* @return identitied matrix of type PIMathMatrixT
*/ */
PIMathMatrixT(const PIVector<Type> &val) { PIMathMatrixT(const PIVector<Type> &val) {
resize(Rows, Cols); assert(Rows*Cols == val.size());
int i = 0; 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<Type> init_list) {
assert(Rows*Cols == init_list.size());
int i = 0;
PIMM_FOR m[r][c] = init_list.begin()[i++];
} }
/** /**
@@ -81,98 +82,23 @@ public:
*/ */
static _CMatrix identity() { static _CMatrix identity() {
_CMatrix tm = _CMatrix(); _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; 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_WB(r, c) 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 * @brief Method which returns number of columns in matrix
* *
* @return type uint shows number of columns * @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 * @brief Method which returns number of rows in matrix
* *
* @return type uint shows number of rows * @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. * @brief Method which returns the selected column in PIMathVectorT format.
@@ -183,7 +109,7 @@ public:
*/ */
_CMCol col(uint index) { _CMCol col(uint index) {
_CMCol tv; _CMCol tv;
PIMM_FOR_R(i) tv[i] = m[i][index]; PIMM_FOR_R tv[i] = m[i][index];
return tv; return tv;
} }
@@ -196,7 +122,7 @@ public:
*/ */
_CMRow row(uint index) { _CMRow row(uint index) {
_CMRow tv; _CMRow tv;
PIMM_FOR_C(i) tv[i] = m[index][i]; PIMM_FOR_C tv[i] = m[index][i];
return tv; return tv;
} }
@@ -209,7 +135,7 @@ public:
* @return matrix type _CMatrix * @return matrix type _CMatrix
*/ */
_CMatrix &setCol(uint index, const _CMCol &v) { _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; return *this;
} }
@@ -222,7 +148,7 @@ public:
* @return matrix type _CMatrix * @return matrix type _CMatrix
*/ */
_CMatrix &setRow(uint index, const _CMRow &v) { _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; return *this;
} }
@@ -234,13 +160,8 @@ public:
* @param r1 is the number of the second selected row * @param r1 is the number of the second selected row
* @return matrix type _CMatrix * @return matrix type _CMatrix
*/ */
_CMatrix &swapRows(uint r0, uint r1) { _CMatrix &swapRows(uint rf, uint rs) {
Type t; PIMM_FOR_C piSwap<Type>(m[rf][i], m[rs][i]);
PIMM_FOR_C(i) {
t = m[r0][i];
m[r0][i] = m[r1][i];
m[r1][i] = t;
}
return *this; return *this;
} }
@@ -252,13 +173,8 @@ public:
* @param c1 is the number of the second selected column * @param c1 is the number of the second selected column
* @return matrix type _CMatrix * @return matrix type _CMatrix
*/ */
_CMatrix &swapCols(uint c0, uint c1) { _CMatrix &swapCols(uint cf, uint cs) {
Type t; PIMM_FOR_R piSwap<Type>(m[i][cf], m[i][cs]);
PIMM_FOR_R(i) {
t = m[i][c0];
m[i][c0] = m[i][c1];
m[i][c1] = t;
}
return *this; return *this;
} }
@@ -269,7 +185,7 @@ public:
* @return filled matrix type _CMatrix * @return filled matrix type _CMatrix
*/ */
_CMatrix &fill(const Type &v) { _CMatrix &fill(const Type &v) {
PIMM_FOR_WB(r, c) m[r][c] = v; PIMM_FOR m[r][c] = v;
return *this; return *this;
} }
@@ -278,7 +194,7 @@ public:
* *
* @return true if matrix is square, else false * @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 * @brief Method which checks if main diagonal of matrix consists of ones and another elements are zeros
@@ -286,7 +202,7 @@ public:
* @return true if matrix is identitied, else false * @return true if matrix is identitied, else false
*/ */
bool isIdentity() const { 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; return true;
} }
@@ -296,34 +212,45 @@ public:
* @return true if matrix is null, else false * @return true if matrix is null, else false
*/ */
bool isNull() const { 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; 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" * 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 row of matrix
* @param col is a parameter that shows the column number of the matrix of the selected element * @param col of matrix
* @return element of matrix by row "row" and col "col" * @return copy of element of matrix
*/ */
Type at(uint row, uint col) const { return m[row][col]; } 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" * @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 * @return matrix row pointer
*/ */
Type *operator[](uint row) { return m[row]; } Type *operator[](uint row) { return m[row]; }
@@ -331,37 +258,26 @@ 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" * @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 * @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 * @param sm matrix for compare
* @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
* @return if matrices are equal true, else false * @return if matrices are equal true, else false
*/ */
bool operator==(const _CMatrix &sm) const { 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; return true;
} }
/** /**
* @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 * @return if matrices are not equal true, else false
*/ */
bool operator!=(const _CMatrix &sm) const { return !(*this == sm); } bool operator!=(const _CMatrix &sm) const { return !(*this == sm); }
@@ -371,28 +287,33 @@ public:
* *
* @param sm matrix for the addition assigment * @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" * @brief Subtraction assignment with matrix "sm"
* *
* @param sm matrix for the subtraction assigment * @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" * @brief Multiplication assignment with value "v"
* *
* @param v value for the multiplication assigment * @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" * @brief Division assignment with value "v"
* *
* @param v value for the division assigment * @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) {
assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
PIMM_FOR m[r][c] /= v;
}
/** /**
* @brief Matrix substraction * @brief Matrix substraction
@@ -401,7 +322,7 @@ public:
*/ */
_CMatrix operator-() const { _CMatrix operator-() const {
_CMatrix tm; _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; return tm;
} }
@@ -413,7 +334,7 @@ public:
*/ */
_CMatrix operator+(const _CMatrix &sm) const { _CMatrix operator+(const _CMatrix &sm) const {
_CMatrix tm = _CMatrix(*this); _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; return tm;
} }
@@ -425,7 +346,7 @@ public:
*/ */
_CMatrix operator-(const _CMatrix &sm) const { _CMatrix operator-(const _CMatrix &sm) const {
_CMatrix tm = _CMatrix(*this); _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; return tm;
} }
@@ -437,7 +358,7 @@ public:
*/ */
_CMatrix operator*(const Type &v) const { _CMatrix operator*(const Type &v) const {
_CMatrix tm = _CMatrix(*this); _CMatrix tm = _CMatrix(*this);
PIMM_FOR_WB(r, c) tm.m[r][c] *= v; PIMM_FOR tm.m[r][c] *= v;
return tm; return tm;
} }
@@ -448,8 +369,9 @@ public:
* @return the result of matrix division * @return the result of matrix division
*/ */
_CMatrix operator/(const Type &v) const { _CMatrix operator/(const Type &v) const {
assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
_CMatrix tm = _CMatrix(*this); _CMatrix tm = _CMatrix(*this);
PIMM_FOR_WB(r, c) tm.m[r][c] /= v; PIMM_FOR tm.m[r][c] /= v;
return tm; return tm;
} }
@@ -467,10 +389,7 @@ public:
if (ok) *ok = k; if (ok) *ok = k;
if (!k) return ret; if (!k) return ret;
ret = Type(1); ret = Type(1);
for (uint c = 0; c < Cols; ++c) PIMM_FOR if (r == c) ret *= m[r][c];
for (uint r = 0; r < Rows; ++r)
if (r == c)
ret *= m[r][c];
return ret; return ret;
} }
@@ -506,7 +425,7 @@ public:
for (uint k = i; k < Cols; ++k) smat.m[k][j] -= mul * smat.m[k][i]; for (uint k = i; k < Cols; ++k) smat.m[k][j] -= mul * smat.m[k][i];
} }
if (i < Cols - 1) { if (i < Cols - 1) {
if (fabs(smat.m[i + 1][i + 1]) < Type(1E-200)) { if (piAbs<Type>(smat.m[i + 1][i + 1]) < Type(1E-200)) {
if (ok != 0) *ok = false; if (ok != 0) *ok = false;
return *this; return *this;
} }
@@ -550,7 +469,7 @@ public:
for (uint k = 0; k < Cols; ++k) mtmp.m[k][j] -= mul * mtmp.m[k][i]; for (uint k = 0; k < Cols; ++k) mtmp.m[k][j] -= mul * mtmp.m[k][i];
} }
if (i < Cols - 1) { if (i < Cols - 1) {
if (fabs(smat.m[i + 1][i + 1]) < Type(1E-200)) { if (piAbs<Type>(smat.m[i + 1][i + 1]) < Type(1E-200)) {
if (ok != 0) *ok = false; if (ok != 0) *ok = false;
return *this; return *this;
} }
@@ -590,111 +509,43 @@ public:
*/ */
_CMatrixI transposed() const { _CMatrixI transposed() const {
_CMatrixI tm; _CMatrixI tm;
PIMM_FOR_WB(r, c) tm[c][r] = m[r][c]; PIMM_FOR tm[c][r] = m[r][c];
return tm; return tm;
} }
private: _CMatrix rotate(Type angle) {
void resize(uint rows_, uint cols_, const Type &new_value = Type()) { static_assert(Rows == 2 && Cols == 2, "Works only with 2x2 matrix");
r_ = rows_; Type c = std::cos(angle);
c_ = cols_; Type s = std::sin(angle);
PIMM_FOR_WB(r, c) m[r][c] = new_value; PIMathMatrixT<2u, 2u> tm;
tm[0][0] = tm[1][1] = c;
tm[0][1] = -s;
tm[1][0] = s;
*this = *this * tm;
return *this;
} }
int c_, r_; private:
Type m[Rows][Cols]; Type m[Rows][Cols];
}; };
#pragma pack(pop) #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 #ifdef PIP_STD_IOSTREAM
template<uint Rows, uint Cols, typename Type> template<uint Rows, uint Cols, typename Type>
inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT<Rows, Cols, Type> & 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<Rows, Cols, Type> & 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 #endif
/** /**
@@ -707,9 +558,13 @@ inline std::ostream & operator <<(std::ostream & s, const PIMathMatrixT<Rows, Co
template<uint Rows, uint Cols, typename Type> template<uint Rows, uint Cols, typename Type>
inline PICout operator<<(PICout s, const PIMathMatrixT<Rows, Cols, Type> &m) { inline PICout operator<<(PICout s, const PIMathMatrixT<Rows, Cols, Type> &m) {
s << "{"; s << "{";
PIMM_FOR_I(r, c) s << m[r][c]; for (uint r = 0; r < Rows; ++r) {
if (c < Cols - 1 || r < Rows - 1) s << ", "; } for (uint c = 0; c < Cols; ++c) {
if (r < Rows - 1) s << PICoutManipulators::NewLine << " "; } s << m[r][c];
if (c < Cols - 1 || r < Rows - 1) s << ", ";
}
if (r < Rows - 1) s << PICoutManipulators::NewLine << " ";
}
s << "}"; s << "}";
return s; return s;
} }
@@ -804,9 +659,6 @@ template<typename Type>
class PIMathMatrix; class PIMathMatrix;
#undef PIMM_FOR #undef PIMM_FOR
#undef PIMM_FOR_WB
#undef PIMM_FOR_I
#undef PIMM_FOR_I_WB
#undef PIMM_FOR_C #undef PIMM_FOR_C
#undef PIMM_FOR_R #undef PIMM_FOR_R
@@ -816,11 +668,10 @@ class PIMathMatrix;
/// Matrix /// 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 for (uint r = 0; r < _V2D::rows_; ++r) for (uint c = 0; c < _V2D::cols_; ++c)
#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 for (uint i = 0; i < _V2D::mat.size(); ++i)
#define PIMM_FOR_A(v) for (uint v = 0; v < _V2D::mat.size(); ++v) #define PIMM_FOR_C for (uint i = 0; i < _V2D::cols_; ++i)
#define PIMM_FOR_C(v) for (uint v = 0; v < _V2D::cols_; ++v) #define PIMM_FOR_R for (uint i = 0; i < _V2D::rows_; ++i)
#define PIMM_FOR_R(v) for (uint v = 0; v < _V2D::rows_; ++v)
//! \brief A class that works with matrix operations, the input data of which is the data type of the matrix //! \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(=, +=, -=, *=, /=, ==, !=, +, -, *, /) //! @tparam There are can be basic C++ language data and different classes where the arithmetic operators(=, +=, -=, *=, /=, ==, !=, +, -, *, /)
@@ -829,7 +680,6 @@ template<typename Type>
class PIP_EXPORT PIMathMatrix : public PIVector2D<Type> { class PIP_EXPORT PIMathMatrix : public PIVector2D<Type> {
typedef PIVector2D<Type> _V2D; typedef PIVector2D<Type> _V2D;
typedef PIMathMatrix<Type> _CMatrix; typedef PIMathMatrix<Type> _CMatrix;
typedef PIMathVector<Type> _CMCol;
public: public:
/** /**
* @brief Constructor of class PIMathMatrix, which creates a matrix * @brief Constructor of class PIMathMatrix, which creates a matrix
@@ -850,7 +700,7 @@ public:
PIMathMatrix(const uint cols, const uint rows, const PIVector<Type> &val) { PIMathMatrix(const uint cols, const uint rows, const PIVector<Type> &val) {
_V2D::resize(rows, cols); _V2D::resize(rows, cols);
int i = 0; int i = 0;
PIMM_FOR_I(c, r) _V2D::element(r, c) = val[i++]; PIMM_FOR _V2D::element(r, c) = val[i++];
} }
/** /**
@@ -861,7 +711,11 @@ public:
PIMathMatrix(const PIVector<PIVector<Type> > &val) { PIMathMatrix(const PIVector<PIVector<Type> > &val) {
if (!val.isEmpty()) { if (!val.isEmpty()) {
_V2D::resize(val.size(), val[0].size()); _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];
}
} }
} }
@@ -873,7 +727,7 @@ public:
PIMathMatrix(const PIVector2D<Type> &val) { PIMathMatrix(const PIVector2D<Type> &val) {
if (!val.isEmpty()) { if (!val.isEmpty()) {
_V2D::resize(val.rows(), val.cols()); _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);
} }
} }
@@ -890,26 +744,13 @@ public:
return tm; 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 * @brief Creates a row matrix of every element that is equal to every element of the vector
* *
* @param val is the vector type PIMathVector * @param val is the vector type PIMathVector
* @return row matrix of every element that is equal to every element of the vector * @return row matrix of every element that is equal to every element of the vector
*/ */
static _CMatrix matrixRow(const PIMathVector<Type> &val) { return _CMatrix(val.size(), 1, val.toVector()); } static _CMatrix matrixRow(const PIMathVector<Type> &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 * @brief Creates a column matrix of every element that is equal to every element of the vector
@@ -917,18 +758,19 @@ public:
* @param val is the vector type PIMathVector * @param val is the vector type PIMathVector
* @return column matrix of every element that is equal to every element of the vector * @return column matrix of every element that is equal to every element of the vector
*/ */
static _CMatrix matrixCol(const PIMathVector<Type> &val) { return _CMatrix(1, val.size(), val.toVector()); } static _CMatrix matrixCol(const PIMathVector<Type> &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 * @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 index is the number of the selected column
* @param v is a vector of the type _CMCol that needs to fill the column * @param v is a vector of the type _CMCol that needs to fill the column
* @return matrix type _CMatrix * @return matrix type _CMatrix
*/ */
_CMatrix &setCol(uint index, const _CMCol &v) { _CMatrix &setCol(uint index, const PIMathVector<Type> &v) {
PIMM_FOR_R(i) _V2D::element(i, index) = v[i]; assert(_V2D::rows == v.size());
PIMM_FOR_R _V2D::element(i, index) = v[i];
return *this; return *this;
} }
@@ -939,8 +781,9 @@ public:
* @param v is a vector of the type _CMCol that needs to fill the row * @param v is a vector of the type _CMCol that needs to fill the row
* @return matrix type _CMatrix * @return matrix type _CMatrix
*/ */
_CMatrix &setRow(uint index, const _CMCol &v) { _CMatrix &setRow(uint index, const PIMathVector<Type> &v) {
PIMM_FOR_C(i) _V2D::element(index, i) = v[i]; assert(_V2D::cols == v.size());
PIMM_FOR_C _V2D::element(index, i) = v[i];
return *this; return *this;
} }
@@ -953,7 +796,7 @@ public:
* @return matrix type _CMatrix * @return matrix type _CMatrix
*/ */
_CMatrix &swapCols(uint r0, uint r1) { _CMatrix &swapCols(uint r0, uint r1) {
PIMM_FOR_C(i) { piSwap(_V2D::element(i, r0), _V2D::element(i, r1)); } PIMM_FOR_C piSwap<Type>(_V2D::element(i, r0), _V2D::element(i, r1));
return *this; return *this;
} }
@@ -966,7 +809,7 @@ public:
* @return matrix type _CMatrix * @return matrix type _CMatrix
*/ */
_CMatrix &swapRows(uint c0, uint c1) { _CMatrix &swapRows(uint c0, uint c1) {
PIMM_FOR_R(i) { piSwap(_V2D::element(c0, i), _V2D::element(c1, i)); } PIMM_FOR_R piSwap<Type>(_V2D::element(c0, i), _V2D::element(c1, i));
return *this; return *this;
} }
@@ -977,7 +820,7 @@ public:
* @return filled matrix type _CMatrix * @return filled matrix type _CMatrix
*/ */
_CMatrix &fill(const Type &v) { _CMatrix &fill(const Type &v) {
PIMM_FOR_A(i) _V2D::mat[i] = v; PIMM_FOR_A _V2D::mat[i] = v;
return *this; return *this;
} }
@@ -994,7 +837,7 @@ public:
* @return true if matrix is identity, else false * @return true if matrix is identity, else false
*/ */
bool isIdentity() const { 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; return true;
} }
@@ -1004,7 +847,7 @@ public:
* @return true if matrix elements equal to zero, else false * @return true if matrix elements equal to zero, else false
*/ */
bool isNull() const { 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; return true;
} }
@@ -1023,7 +866,7 @@ public:
void operator+=(const _CMatrix &sm) { void operator+=(const _CMatrix &sm) {
assert(_V2D::rows() == sm.rows()); assert(_V2D::rows() == sm.rows());
assert(_V2D::cols() == sm.cols()); assert(_V2D::cols() == sm.cols());
PIMM_FOR_A(i) _V2D::mat[i] += sm.mat[i]; PIMM_FOR_A _V2D::mat[i] += sm.mat[i];
} }
/** /**
@@ -1034,7 +877,7 @@ public:
void operator-=(const _CMatrix &sm) { void operator-=(const _CMatrix &sm) {
assert(_V2D::rows() == sm.rows()); assert(_V2D::rows() == sm.rows());
assert(_V2D::cols() == sm.cols()); assert(_V2D::cols() == sm.cols());
PIMM_FOR_A(i) _V2D::mat[i] -= sm.mat[i]; PIMM_FOR_A _V2D::mat[i] -= sm.mat[i];
} }
/** /**
@@ -1042,14 +885,19 @@ public:
* *
* @param v value for the multiplication assigment * @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" * @brief Division assignment with value "v"
* *
* @param v value for the division assigment * @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<Type>(v) > PIMATHVECTOR_ZERO_CMP);
PIMM_FOR_A _V2D::mat[i] /= v;
}
/** /**
* @brief Matrix substraction * @brief Matrix substraction
@@ -1058,7 +906,7 @@ public:
*/ */
_CMatrix operator-() const { _CMatrix operator-() const {
_CMatrix tm(*this); _CMatrix tm(*this);
PIMM_FOR_A(i) tm.mat[i] = -_V2D::mat[i]; PIMM_FOR_A tm.mat[i] = -_V2D::mat[i];
return tm; return tm;
} }
@@ -1072,7 +920,7 @@ public:
_CMatrix tm(*this); _CMatrix tm(*this);
assert(tm.rows() == sm.rows()); assert(tm.rows() == sm.rows());
assert(tm.cols() == sm.cols()); 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; return tm;
} }
@@ -1086,7 +934,7 @@ public:
_CMatrix tm(*this); _CMatrix tm(*this);
assert(tm.rows() == sm.rows()); assert(tm.rows() == sm.rows());
assert(tm.cols() == sm.cols()); 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; return tm;
} }
@@ -1098,7 +946,7 @@ public:
*/ */
_CMatrix operator*(const Type &v) const { _CMatrix operator*(const Type &v) const {
_CMatrix tm(*this); _CMatrix tm(*this);
PIMM_FOR_A(i) tm.mat[i] *= v; PIMM_FOR_A tm.mat[i] *= v;
return tm; return tm;
} }
@@ -1109,8 +957,9 @@ public:
* @return the result of matrix division * @return the result of matrix division
*/ */
_CMatrix operator/(const Type &v) const { _CMatrix operator/(const Type &v) const {
assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
_CMatrix tm(*this); _CMatrix tm(*this);
PIMM_FOR_A(i) tm.mat[i] /= v; PIMM_FOR_A tm.mat[i] /= v;
return tm; return tm;
} }
@@ -1204,7 +1053,7 @@ public:
* @param sv is a vector multiplier * @param sv is a vector multiplier
* @return copy of inverted matrix * @return copy of inverted matrix
*/ */
_CMatrix &invert(bool *ok = 0, _CMCol *sv = 0) { _CMatrix &invert(bool *ok = 0, PIMathVector<Type> *sv = 0) {
if (!isSquare()) { if (!isSquare()) {
if (ok != 0) *ok = false; if (ok != 0) *ok = false;
return *this; return *this;
@@ -1227,7 +1076,7 @@ public:
++crow; ++crow;
smat.swapRows(i, crow); smat.swapRows(i, crow);
mtmp.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) { for (uint j = i + 1; j < _V2D::rows_; ++j) {
mul = smat.element(i, j) / smat.element(i, i); mul = smat.element(i, j) / smat.element(i, i);
@@ -1278,7 +1127,7 @@ public:
*/ */
_CMatrix transposed() const { _CMatrix transposed() const {
_CMatrix tm(_V2D::rows_, _V2D::cols_); _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; return tm;
} }
}; };
@@ -1438,7 +1287,6 @@ PIMathMatrix<complex<T> > hermitian(const PIMathMatrix<complex<T> > &m) {
} }
#undef PIMM_FOR #undef PIMM_FOR
#undef PIMM_FOR_I
#undef PIMM_FOR_A #undef PIMM_FOR_A
#undef PIMM_FOR_C #undef PIMM_FOR_C
#undef PIMM_FOR_R #undef PIMM_FOR_R

View File

@@ -28,85 +28,202 @@
template<uint Cols, uint Rows, typename Type> template<uint Cols, uint Rows, typename Type>
class PIMathMatrixT; class PIMathMatrixT;
#define PIMATHVECTOR_ZERO_CMP Type(1E-100)
/// Vector templated /// 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<uint Size, typename Type = double> template<uint Size, typename Type = double>
class PIP_EXPORT PIMathVectorT { class PIP_EXPORT PIMathVectorT {
typedef PIMathVectorT<Size, Type> _CVector; typedef PIMathVectorT<Size, Type> _CVector;
static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic"); static_assert(std::is_arithmetic<Type>::value, "Type must be arithmetic");
static_assert(Size > 0, "Size count must be > 0"); static_assert(Size > 0, "Size must be > 0");
public: public:
PIMathVectorT() {resize();} PIMathVectorT(const Type & v = Type()) {PIMV_FOR c[i] = v;}
PIMathVectorT(const PIVector<Type> & val) {resize(); PIMV_FOR(i, 0) c[i] = val[i];} PIMathVectorT(const PIVector<Type> & val) {
PIMathVectorT(const _CVector & st, const _CVector & fn) {resize(); set(st, fn);} assert(Size == val.size());
PIMV_FOR c[i] = val[i];
}
PIMathVectorT(std::initializer_list<Type> 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];
return tv;
}
uint size() const {return Size;} constexpr uint size() const {return Size;}
_CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} _CVector & fill(const Type & v) {PIMV_FOR 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 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 c[i] += v[i]; return *this;}
_CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;} _CVector & swapElements(uint f, uint s) {
Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += (c[i] * c[i]); return tv;} piSwap<Type>(c[f], c[s]);
Type length() const {return sqrt(lengthSqr());} return *this;
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 lengthSqr() const {
Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);} Type tv(0);
Type angleRad(const _CVector & v) const {return acos(angleCos(v));} PIMV_FOR tv += c[i] * c[i];
Type angleDeg(const _CVector & v) const {return toDeg(acos(angleCos(v)));} return tv;
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));} Type length() const {return std::sqrt(lengthSqr());}
_CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; if (piAbs<Type>(tv) <= Type(1E-100)) {fill(Type(0)); return *this;} PIMV_FOR(i, 0) c[i] /= tv; return *this;} Type manhattanLength() const {
Type tv(0);
PIMV_FOR tv += piAbs<Type>(c[i]);
return tv;
}
Type angleCos(const _CVector & v) const {
Type tv = v.length() * length();
assert(piAbs<Type>(tv) > PIMATHVECTOR_ZERO_CMP);
return dot(v) / tv;
}
Type angleSin(const _CVector & v) const {
Type tv = angleCos(v);
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 angleElevation(const _CVector & v) const {return 90.0 - angleDeg(v - *this);}
_CVector projection(const _CVector & v) {
Type tv = v.length();
assert(piAbs<Type>(tv) > PIMATHVECTOR_ZERO_CMP);
return v * (dot(v) / tv);
}
_CVector & normalize() {
Type tv = length();
assert(piAbs<Type>(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 normalized() {_CVector tv(*this); tv.normalize(); return tv;}
_CVector cross(const _CVector & v) {return (*this) * v;} bool isNull() const {PIMV_FOR if (c[i] != Type(0)) return false; return true;}
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 isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} 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) {return c[index];}
Type operator [](uint index) const {return c[index];} const Type & operator [](uint index) const {return c[index];}
_CVector & operator =(const _CVector & v) {memcpy(c, v.c, sizeof(Type) * Size); return *this;} Type at(uint index) const {return c[index];}
_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);} 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 _CVector & v) {PIMV_FOR c[i] += v[i];}
void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;} void operator -=(const _CVector & v) {PIMV_FOR c[i] -= v[i];}
void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];} void operator *=(const Type & v) {PIMV_FOR c[i] *= v;}
void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;} void operator /=(const Type & v) {
void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];} assert(piAbs<Type>(v) > PIMATHVECTOR_ZERO_CMP);
_CVector operator -() const {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;} PIMV_FOR c[i] /= v;
_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 {
_CVector operator *(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;} _CVector tv;
_CVector operator /(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;} PIMV_FOR tv[i] = -c[i];
_CVector operator /(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v[i]; return tv;} 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;} _CVector operator +(const _CVector & v) const {
Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;} _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<Type>(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;
}
_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;
}
_CVector div(const _CVector & v) const {
_CVector tv(*this);
PIMV_FOR {
assert(piAbs<Type>(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> transposed() const {
PIMathMatrixT<1, Size, Type> ret; PIMathMatrixT<1, Size, Type> ret;
PIMV_FOR(i, 0) ret[0][i] = c[i]; PIMV_FOR ret[0][i] = c[i];
return ret; return ret;
} }
Type distToLine(const _CVector & lp0, const _CVector & lp1) { Type distToLine(const _CVector & lp0, const _CVector & lp1) {
_CVector a(lp0, lp1), b(lp0, *this), c(lp1, *this); _CVector a(lp0, lp1);
Type f = fabs(a[0]*b[1] - a[1]*b[0]) / a.length(); Type tv = a.length();
return f;} assert(piAbs<Type>(tv) > PIMATHVECTOR_ZERO_CMP);
_CVector b(lp0, *this);
return piAbs<Type>(a[0]*b[1] - a[1]*b[0]) / tv;
}
template<uint Size1, typename Type1> /// vector {Size, Type} to vector {Size1, Type1} template<uint Size1, typename Type1> /// vector {Size, Type} to vector {Size1, Type1}
PIMathVectorT<Size1, Type1> turnTo() const {PIMathVectorT<Size1, Type1> tv; uint sz = piMin<uint>(Size, Size1); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;} PIMathVectorT<Size1, Type1> turnTo() const {
PIMathVectorT<Size1, Type1> tv;
uint sz = piMin<uint>(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;} 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;
}
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: private:
void resize(const Type & new_value = Type()) {for (uint i = 0; i < Size; ++i) c[i] = new_value;}
Type c[Size]; Type c[Size];
}; };
@@ -117,26 +234,8 @@ inline PIMathVectorT<Size, Type> operator *(const Type & x, const PIMathVectorT<
} }
template<uint Size, typename Type> template<uint Size, typename Type>
inline PICout operator <<(PICout s, const PIMathVectorT<Size, Type> & v) {s << "{"; PIMV_FOR(i, 0) {s << v[i]; if (i < Size - 1) s << ", ";} s << "}"; return s;} inline PICout operator <<(PICout s, const PIMathVectorT<Size, Type> & v) {s << "{"; PIMV_FOR {s << v[i]; if (i < Size - 1) s << ", ";} s << "}"; return s;}
template<uint Size, typename Type>
inline bool operator ||(const PIMathVectorT<Size, Type> & f, const PIMathVectorT<Size, Type> & s) {return (f * s).isNull();}
template<uint Size, typename Type>
inline PIMathVectorT<Size, Type> sqrt(const PIMathVectorT<Size, Type> & v) {PIMathVectorT<Size, Type> ret; PIMV_FOR(i, 0) {ret[i] = sqrt(v[i]);} return ret;}
template<uint Size, typename Type>
inline PIMathVectorT<Size, Type> sqr(const PIMathVectorT<Size, Type> & v) {PIMathVectorT<Size, Type> ret; PIMV_FOR(i, 0) {ret[i] = sqr(v[i]);} return ret;}
template<uint Size, typename Type>
inline PIByteArray & operator <<(PIByteArray & s, const PIMathVectorT<Size, Type> & v) {for (uint i = 0; i < Size; ++i) s << v[i]; return s;}
template<uint Size, typename Type>
inline PIByteArray & operator >>(PIByteArray & s, PIMathVectorT<Size, Type> & v) {for (uint i = 0; i < Size; ++i) s >> v[i]; return s;}
template<typename T>
inline PIMathVectorT<2u, T> createVectorT2(T x, T y) {return PIMathVectorT<2u, T>(PIVector<T>() << x << y);}
template<typename T>
inline PIMathVectorT<3u, T> createVectorT3(T x, T y, T z) {return PIMathVectorT<3u, T>(PIVector<T>() << x << y << z);}
template<typename T>
inline PIMathVectorT<4u, T> createVectorT4(T x, T y, T z, T w) {return PIMathVectorT<4u, T>(PIVector<T>() << x << y << z << w);}
typedef PIMathVectorT<2u, int> PIMathVectorT2i; typedef PIMathVectorT<2u, int> PIMathVectorT2i;
typedef PIMathVectorT<3u, int> PIMathVectorT3i; typedef PIMathVectorT<3u, int> PIMathVectorT3i;
@@ -144,21 +243,13 @@ typedef PIMathVectorT<4u, int> PIMathVectorT4i;
typedef PIMathVectorT<2u, double> PIMathVectorT2d; typedef PIMathVectorT<2u, double> PIMathVectorT2d;
typedef PIMathVectorT<3u, double> PIMathVectorT3d; typedef PIMathVectorT<3u, double> PIMathVectorT3d;
typedef PIMathVectorT<4u, double> PIMathVectorT4d; typedef PIMathVectorT<4u, double> PIMathVectorT4d;
#define createVectorT2i createVectorT2<int>
#define createVectorT3i createVectorT3<int>
#define createVectorT4i createVectorT4<int>
#define createVectorT2f createVectorT2<float>
#define createVectorT3f createVectorT3<float>
#define createVectorT4f createVectorT4<float>
#define createVectorT2d createVectorT2<double>
#define createVectorT3d createVectorT3<double>
#define createVectorT4d createVectorT4<double>
#undef PIMV_FOR #undef PIMV_FOR
/// Vector /// 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<typename Type> template<typename Type>
class PIP_EXPORT PIMathVector { class PIP_EXPORT PIMathVector {
@@ -166,73 +257,228 @@ class PIP_EXPORT PIMathVector {
template<typename TypeOp> friend PIByteArray & operator <<(PIByteArray & s, const PIMathVector<TypeOp> & v); template<typename TypeOp> friend PIByteArray & operator <<(PIByteArray & s, const PIMathVector<TypeOp> & v);
template<typename TypeOp> friend PIByteArray & operator >>(PIByteArray & s, PIMathVector<TypeOp> & v); template<typename TypeOp> friend PIByteArray & operator >>(PIByteArray & s, PIMathVector<TypeOp> & v);
public: public:
PIMathVector(const uint size = 0) {c.resize(size);} PIMathVector(const uint size = 0, const Type & new_value = Type()) {c.resize(size, new_value);}
PIMathVector(const PIVector<Type> & val) {c.resize(val.size()); PIMV_FOR(i, 0) c[i] = val[i];} PIMathVector(const PIVector<Type> & val) {c = val;}
PIMathVector(const _CVector & st, const _CVector & fn) {c.resize(st.size()); PIMV_FOR(i, 0) c[i] = fn[i] - st[i];} PIMathVector(std::initializer_list<Type> init_list) {c = PIVector<Type>(init_list);}
uint size() const {return c.size();} template<uint Size>
_CVector & resize(uint size, const Type & new_value = Type()) {c.resize(size, new_value); return *this;} PIMathVector(const PIMathVectorT<Size, Type> & val) {c.resize(Size); PIMV_FOR c[i] = val[i];}
_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<Type>(c[fe], c[se]); return *this;}
Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) 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 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<Type>(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;}
bool isValid() const {return !c.isEmpty();}
bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} static PIMathVector fromTwoPoints(const _CVector & st, const _CVector & fn) {
assert(st.size() == fn.size());
Type & at(uint index) {return c[index];} _CVector v(st.size());
Type at(uint index) const {return c[index];} for (uint i = 0; i < v.size(); ++i) v.c[i] = fn[i] - st[i];
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;} uint size() const {return c.size();}
_CVector & operator =(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} _CVector & resize(uint size, const Type & new_value = Type()) {
bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;} c.resize(size, new_value);
bool operator !=(const _CVector & v) const {return !(*this == c);} return *this;
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];} _CVector resized(uint size, const Type & new_value = Type()) {
void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;} _CVector tv = _CVector(*this);
void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];} tv.resize(size, new_value);
void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;} return tv;
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 & fill(const Type & v) {
_CVector operator +(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;} c.fill(v);
_CVector operator -(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;} return *this;
_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 & move(const Type & v) {
_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;} PIMV_FOR c[i] += v;
_CVector operator &(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v[i]; return tv;} return *this;
Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;} }
_CVector & move(const _CVector & v) {
Type distToLine(const _CVector & lp0, const _CVector & lp1) { assert(c.size() == v.size());
_CVector a(lp0, lp1), b(lp0, *this), c(lp1, *this); PIMV_FOR c[i] += v[i];
Type f = fabs(a[0]*b[1] - a[1]*b[0]) / a.length(); return *this;
return f; }
_CVector & swapElements(uint f, uint s) {
piSwap<Type>(c[f], c[s]);
return *this;
}
Type lengthSqr() const {
Type tv(0);
PIMV_FOR tv += c[i] * c[i];
return tv;
}
Type length() const {return std::sqrt(lengthSqr());}
Type manhattanLength() const {
Type tv(0);
PIMV_FOR tv += piAbs<Type>(c[i]);
return tv;
}
Type angleCos(const _CVector & v) const {
assert(c.size() == v.size());
Type tv = v.length() * length();
assert(piAbs<Type>(tv) > PIMATHVECTOR_ZERO_CMP);
return dot(v) / tv;
}
Type angleSin(const _CVector & v) const {
assert(c.size() == v.size());
Type tv = angleCos(v);
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));}
_CVector projection(const _CVector & v) {
assert(c.size() == v.size());
Type tv = v.length();
assert(piAbs<Type>(tv) > PIMATHVECTOR_ZERO_CMP);
return v * (dot(v) / tv);
}
_CVector & normalize() {
Type tv = length();
assert(piAbs<Type>(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 dot(v) == Type(0);}
Type & operator [](uint index) {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];
}
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<Type>(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<Type>(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;
}
_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;
}
_CVector div(const _CVector & v) const {
assert(c.size() == v.size());
_CVector tv(*this);
PIMV_FOR {
assert(piAbs<Type>(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());
assert(c.size() == lp1.size());
_CVector a = _CVector::fromTwoPoints(lp0, lp1);
Type tv = a.length();
assert(piAbs<Type>(tv) > PIMATHVECTOR_ZERO_CMP);
_CVector b = _CVector::fromTwoPoints(lp0, *this);
return piAbs<Type>(a[0]*b[1] - a[1]*b[0]) / tv;
} }
template<typename Type1>
PIMathVector turnTo(uint size) const {PIMathVector<Type1> tv; uint sz = piMin<uint>(c.size(), size); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;}
PIVector<Type> toVector() const {return c;} PIVector<Type> toVector() const {return c;}
inline Type * data() {return c.data();} inline Type * data() {return c.data();}
inline const Type * data() const {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;
}
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: private:
PIVector<Type> c; PIVector<Type> c;
}; };
template<typename Type>
inline PIMathVector<Type> operator *(const Type & x, const PIMathVector<Type> & v) {
return v * x;
}
#undef PIMV_FOR #undef PIMV_FOR
#ifdef PIP_STD_IOSTREAM #ifdef PIP_STD_IOSTREAM

View File

@@ -40,7 +40,7 @@ PIMathVectorT3d PIQuaternion::eyler() const {
angle_z = atan2(-rmat[0][1] / c, rmat[0][0] / c); angle_z = atan2(-rmat[0][1] / c, rmat[0][0] / c);
} }
if (angle_z < 0) angle_z = 2*M_PI + angle_z; 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});
} }
@@ -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 PIQuaternion::fromEyler(double ax, double ay, double az) {
PIQuaternion q_heading; PIQuaternion q_heading;
PIQuaternion q_pinch; PIQuaternion q_pinch;
@@ -153,7 +143,7 @@ PIQuaternion PIQuaternion::fromAngles(double ax, double ay, double az) {
} }
PIQuaternion PIQuaternion::fromAngles2(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.); if (om == 0.) return PIQuaternion(PIMathVectorT3d(), 1.);
PIQuaternion res; PIQuaternion res;
res.q[0] = cos(om/2); res.q[0] = cos(om/2);
@@ -199,8 +189,8 @@ PIQuaternion PIQuaternion::fromRotationMatrix(const PIMathMatrixT33d & m) {
PIQuaternion operator*(const PIQuaternion & q0, const PIQuaternion & q1) { PIQuaternion operator*(const PIQuaternion & q0, const PIQuaternion & q1) {
PIMathVectorT3d v0(q0.vector()), v1(q1.vector()); PIMathVectorT3d v0(q0.vector()), v1(q1.vector());
double r0 = q0.q[0] * 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*v1; PIMathVectorT3d qv = v1*q0.q[0] + v0*q1.q[0] + v0.cross(v1);
PIQuaternion ret; PIQuaternion ret;
ret.q[0] = r0; ret.q[0] = r0;
ret.q[1] = qv[0]; ret.q[1] = qv[0];

View File

@@ -39,7 +39,7 @@ public:
double & scalar() {return q[0];} double & scalar() {return q[0];}
double scalar() const {return q[0];} double scalar() const {return q[0];}
PIMathVectorT3d vector() const {return createVectorT3<double>(q[1], q[2], q[3]);} PIMathVectorT3d vector() const {return PIMathVectorT3d({q[1], q[2], q[3]});}
PIMathVectorT3d eyler() const; PIMathVectorT3d eyler() const;
PIMathMatrixT33d rotationMatrix() const; PIMathMatrixT33d rotationMatrix() const;
@@ -52,9 +52,6 @@ public:
protected: protected:
double q[4]; double q[4];
PIMathMatrixT44d makeMatrix() const;
}; };
PIP_EXPORT PIQuaternion operator *(const double & a, const PIQuaternion & q); PIP_EXPORT PIQuaternion operator *(const double & a, const PIQuaternion & q);

View File

@@ -40,11 +40,14 @@ inline PIByteArray & operator >>(PIByteArray & ba, MM & v) {piCout << ">>"
int main() { int main() {
PIMathMatrixd m = PIMathMatrixd::identity(5,5); PIMathVectorT3d v3({1,2,3});
// m.fill(9); PIMathVectord v(v3);
//PIMathMatrixd m2 = PIMathMatrixd::identity(3,4); PIMathVectord v2({3,2,1});
piCout << v;
piCout << v2;
PIMathMatrixT22d m = PIMathMatrixT22d::identity();
piCout << m; piCout << m;
m.resize(3,3); m.rotate(toRad(90.));
piCout << m; piCout << m;
return 0; return 0;
} }