www.pudn.com > cad3d.zip > Vector.h
/***************************************************************************
Vector.h - description
-------------------
begin : 2002
copyright : (C) 2002 by Martin Marinov
email : martin_marinov@hotmail.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
//#ifndef __Vector_h__
//#define __Vector_h__
namespace tmc
{//namespace Template Math Classes
// imported macros
/*
#define DIMENSION 3
#define UNROLL_VEC(EXPR) UNROLL_VEC_3_OP(EXPR,;)
#define UNROLL_ARGS(EXPR) UNROLL_ARGS_3(EXPR)
#define UNROLL_VEC_OP(EXPR,OP) UNROLL_VEC_3_OP(EXPR,OP)
#define SET_CONSTRUCTOR SET_CONSTRUCTOR_BASIC
#define SET_MEMBER SET_MEMBER_BASIC
*/
//#define local macros
#define ARG_CONSTREF_EXPR(i) const _T& rC##i
#define ARG_REF_EXPR(i) _T& rC##i
#define SET_EXPR(i) VEC_EL(i) = rC##i;
#define VEC_EL(i) m_coords[i]
#define DUMP_EXPR(i) printf( "CVector("#i")= %f\n", VEC_EL(i));
//#define GEN_VEC_CLASS_NAME(n) CVector##n
//#define VECTOR_CLASS_NAME GEN_VEC_CLASS_NAME(DIMENSION)
template
class VECTOR_CLASS_NAME
{
public:
enum { nDim = DIMENSION };
typedef VECTOR_CLASS_NAME<_T> _MyType;
protected:
_T m_coords[nDim];
protected:
public:
__inline__ VECTOR_CLASS_NAME()
{
}
__inline__ VECTOR_CLASS_NAME(const _MyType& rA)
{
(*this) = rA;
}
__inline__ explicit VECTOR_CLASS_NAME(const _T& rC)
{
Set(rC);
}
__inline__ SET_CONSTRUCTOR
__inline__ void Set(const _T& rC)
{
#define SET_CONST_EXPR(i) VEC_EL(i) = rC;
UNROLL_VEC(SET_CONST_EXPR)
#undef SET_CONST_EXPR
}
__inline__ SET_MEMBER
__inline__ void Set(uint i, const _T& rK)
{
CHECK_INDEX(i, 0, nDim);
VEC_EL(i) = rK;
}
__inline__ const _T& GetRef(uint i) const
{
CHECK_INDEX(i, 0, nDim);
return VEC_EL(i);
}
__inline__ _T& GetRef(uint i)
{
CHECK_INDEX(i, 0, nDim);
return VEC_EL(i);
}
__inline__ void Dump()
{
UNROLL_VEC(DUMP_EXPR)
}
__inline__ _T& operator ()(uint i)
{
CHECK_INDEX(i, 0, nDim);
return VEC_EL(i);
}
__inline__ const _T& operator ()(uint i) const
{
CHECK_INDEX(i, 0, nDim);
return VEC_EL(i);
}
__inline__ operator _T* () {return m_coords; }
__inline__ operator const _T* () const {return m_coords; }
//reference returning members
///////////////////////////////////////////////////////
__inline__ _MyType& operator = (const _MyType& rA)
{
#define COPY_EXPR(i) VEC_EL(i) = rA.VEC_EL(i);
UNROLL_VEC(COPY_EXPR)
#undef COPY_EXPR
return *this;
}
__inline__ _MyType& operator += (const _MyType& rA)
{
#define ADD_EXPR(i) VEC_EL(i) += rA.VEC_EL(i);
UNROLL_VEC(ADD_EXPR)
#undef ADD_EXPR
return *this;
}
__inline__ _MyType& operator -= (const _MyType& rA)
{
#define SUB_EXPR(i) VEC_EL(i) -= rA.VEC_EL(i);
UNROLL_VEC(SUB_EXPR)
#undef SUB_EXPR
return *this;
}
__inline__ _MyType& operator *= (const _T& dK)
{
#define MUL_EXPR(i) VEC_EL(i) *= dK;
UNROLL_VEC(MUL_EXPR)
#undef MUL_EXPR
return *this;
}
__inline__ _MyType& operator /= (const _T& dK)
{
CHECK(!IsZero(dK));
return (*this)*=(1/dK);
}
__inline__ _MyType& Normalize()
{
CHECK( !IsNull() );
return (*this) /= Norm();
}
__inline__ _MyType& SetLinear(const _T& rC, const _MyType& rA)
{
#define LINEAR_EXPR(i) VEC_EL(i) = rC*rA.VEC_EL(i);
UNROLL_VEC(LINEAR_EXPR)
#undef LINEAR_EXPR
return *this;
//return ((*this) = rA) *= rC;
}
__inline__ _MyType& SetLinear2( const _T& rC1, const _MyType& rA,
const _T& rC2, const _MyType& rB)
{
#define LINEAR_EXPR(i) VEC_EL(i) = rC1*rA.VEC_EL(i) + rC2*rB.VEC_EL(i);
UNROLL_VEC(LINEAR_EXPR)
#undef LINEAR_EXPR
return *this;
}
__inline__ _MyType& SetSum(const _MyType& rA, const _MyType& rB)
{
#define ADD_EXPR(i) VEC_EL(i) = rA.VEC_EL(i) + rB.VEC_EL(i);
UNROLL_VEC(ADD_EXPR)
#undef ADD_EXPR
return *this;
}
__inline__ _MyType& SetDiff(const _MyType& rA, const _MyType& rB)
{
#define SUB_EXPR(i) VEC_EL(i) = rA.VEC_EL(i) - rB.VEC_EL(i);
UNROLL_VEC(SUB_EXPR)
#undef SUB_EXPR
return *this;
}
#define CROSS_PRODUCT(OP_NAME,OP) \
__inline__ _MyType& ##OP_NAME##Cross(const _MyType& rA, const _MyType& rB) \
{ \
CHECK(size() == 3); \
VEC_EL(0) OP rA.VEC_EL(1)*rB.VEC_EL(2) - rA.VEC_EL(2)*rB.VEC_EL(1); \
VEC_EL(1) OP rA.VEC_EL(2)*rB.VEC_EL(0) - rA.VEC_EL(0)*rB.VEC_EL(2); \
VEC_EL(2) OP rA.VEC_EL(0)*rB.VEC_EL(1) - rA.VEC_EL(1)*rB.VEC_EL(0); \
return *this; \
}
CROSS_PRODUCT(Set, =)
CROSS_PRODUCT(Add, +=)
CROSS_PRODUCT(Sub, -=)
#undef CROSS_PRODUCT
//scalar returning members
///////////////////////////////////////////////////////
__inline__ _T operator * (const _MyType& rA) const
{
#define MULT_EXPR(i) VEC_EL(i)*rA.VEC_EL(i)
return UNROLL_VEC_OP(MULT_EXPR,+);
#undef MULT_EXPR
}
__inline__ _T Norm2() const
{
return (*this)*(*this);
}
__inline__ _T Norm() const
{
return (_T)sqrt(Norm2());
}
//bool returning members
///////////////////////////////////////////////////////
__inline__ bool operator == (const _MyType& rA) const
{
#define COMP_EXPR(i) (VEC_EL(i) == rA.VEC_EL(i))
return UNROLL_VEC_OP(COMP_EXPR, && );
#undef COMP_EXPR
}
__inline__ bool IsNormalized() const
{
return IsEq(Norm(), 1);
}
__inline__ bool IsNull() const
{
return IsZero(Norm());
}
__inline__ uint size() const
{
return nDim;
}
__inline__ void Clear()
{
Set(0);
}
//_MyType returning members (slow!)
///////////////////////////////////////////////////////
__inline__ _MyType operator ^ (const _MyType& rA) const
{
return _MyType().SetCross(*this, rA);
}
__inline__ _MyType operator + (const _MyType& rA) const
{
return _MyType().SetSum(*this, rA);
}
__inline__ _MyType operator - (const _MyType& rA) const
{
return _MyType().SetDiff(*this, rA);
}
__inline__ _MyType operator * (const _T& rC) const
{
return _MyType().SetLinear(rC, *this);
}
__inline__ _MyType operator / (const _T& rC) const
{
CHECK(!IsZero(rC));
return _MyType().SetLinear(1/rC, *this);
}
};
// #undef local macros
#undef ARG_CONSTREF_EXPR
#undef ARG_REF_EXPR
#undef SET_EXPR
#undef VEC_EL
#undef DUMP_EXPR
#undef VECTOR_CLASS_NAME
// #undef "imported" macros
#undef UNROLL_VEC_OP
#undef UNROLL_ARGS
#undef UNROLL_VEC
#undef SET_CONSTRUCTOR
#undef SET_MEMBER
#undef DIMENSION
};//namespace Template Math Classes
//#endif//__Vector_h__