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__