00001 #ifndef _RVEC2_HXX_
00002 #define _RVEC2_HXX_
00003
00004 #include <RBasicTypes.hxx>
00005 #include <cmath>
00006 #include <Rstd/misc.hxx>
00007
00008
00009 namespace RayGina
00010 {
00011 namespace CORE
00012 {
00013 template<typename T>
00014 class RVec2;
00015
00016 typedef RVec2<RReal> RVec2r;
00017 typedef RVec2<RReal32> RVec2f;
00018 typedef RVec2<RReal64> RVec2d;
00019 typedef RVec2<RInt32> RVec2i;
00020 typedef RVec2<RUInt32> RVec2u;
00021
00022 template<typename T>
00023 RVec2<T> operator+(const RVec2<T> & a, const RVec2<T> & b) {
00024 return RVec2<T>( a.x() + b.x(), a.y() + b.y() );
00025 }
00026 template<typename T>
00027 RVec2<T> operator-(const RVec2<T> & a, const RVec2<T> & b) {
00028 return RVec2<T>( a.x() - b.x(), a.y() - b.y() );
00029 }
00030 template<typename T>
00031 RVec2<T> operator-(const RVec2<T> & vec) {
00032 return RVec2<T>( -vec.x(), -vec.y() );
00033 }
00034 template<typename T>
00035 RVec2<T> operator*(const RVec2<T> & v, T scalar) {
00036 return RVec2<T>( v.x() * scalar, v.y() * scalar );
00037 }
00038 template<typename T>
00039 RVec2<T> operator*(T scalar, const RVec2<T> & v) {
00040 return RVec2<T>( v.x() * scalar, v.y() * scalar );
00041 }
00042
00044 template<typename T>
00045 std::ostream& operator<<(std::ostream& os, const RVec2<T>& v) {
00046 os << "(" << v.at(0) << "," << v.at(1) << ")";
00047 return os;
00048 }
00049
00050 }
00051 }
00052
00053
00054 template<typename T>
00055 class RayGina::CORE::RVec2
00056 {
00057 public:
00058
00059 enum AXIS {
00060 AXIS_X = 0,
00061 AXIS_Y,
00062 };
00063
00064 inline RVec2<T>() {
00065 set(0,0);
00066 }
00067
00068 inline RVec2<T>(T x, T y){
00069 set(x,y);
00070 }
00071
00072 template<typename S> inline RVec2<T>(const RVec2<S>& other) {
00073 set( other.x(), other.y() );
00074 }
00075
00076 inline void set(T x, T y) {
00077 m_data[0] = x;
00078 m_data[1] = y;
00079 }
00080
00081 inline T& at(unsigned int i) {
00082 return m_data[i];
00083 }
00084 inline const T& at(unsigned int i) const {
00085 return m_data[i];
00086 }
00087
00088 inline T& operator[](unsigned int i) {
00089 return m_data[i];
00090 }
00091 inline const T& operator[](unsigned int i) const{
00092 return m_data[i];
00093 }
00094
00095 inline T& x() { return m_data[0]; }
00096 inline const T& x() const { return m_data[0]; }
00097 inline T& y() { return m_data[1]; };
00098 inline const T& y() const { return m_data[1]; }
00099
00100 inline T length() const {
00101 return sqrt(m_data[0]*m_data[0] + m_data[1]*m_data[1]);
00102 }
00103 inline T manhattanLength() const {
00104 return x()+y();
00105 }
00106
00107 inline AXIS maxDim() const {
00108 return ( x() < y() ? AXIS_Y : AXIS_X );
00109 }
00110 inline AXIS absMaxDim() const {
00111 return ( fabs(x()) < fabs(y()) ? AXIS_Y : AXIS_X );
00112 }
00113 inline AXIS minDim() const {
00114 return ( x() > y() ? AXIS_Y : AXIS_X );
00115 }
00116 inline AXIS absMinDim()const {
00117 return ( fabs(x()) > fabs(y()) ? AXIS_Y : AXIS_X );
00118 }
00119
00120 inline RVec2& reverse() {
00121 m_data[0] = - m_data[0];
00122 m_data[1] = - m_data[1];
00123 return *this;
00124 }
00125 inline RVec2<T>& zero() {
00126 set(0,0);
00127 return *this;
00128 }
00129 inline RVec2& normalize() {
00130 T len = length();
00131 assert(len != 0);
00132 if (len != T(1)) {
00133 T _len = T(1)/len;
00134 m_data[0] *= _len;
00135 m_data[1] *= _len;
00136 }
00137 return *this;
00138 }
00139
00140 inline void operator+=(const RVec2& b) {
00141 m_data[0] += b.m_data[0];
00142 m_data[1] += b.m_data[1];
00143 }
00144 inline void operator-=(const RVec2& b) {
00145 m_data[0] -= b.m_data[0];
00146 m_data[1] -= b.m_data[1];
00147 }
00148 inline void operator*=(T scalar) {
00149 m_data[0] *= scalar;
00150 m_data[1] *= scalar;
00151 }
00152
00153 inline bool equal(const RVec2& vec, T delta) {
00154 return equal_delta( x(), vec.x(), delta ) && equal_delta( y(), vec.y() );
00155 }
00156
00157 private:
00158 T m_data[2];
00159 };
00160
00161 #endif