00001
00002 #include <cmath>
00003
00004 #include <Rstd/misc.hxx>
00005
00006
00007 template<typename T>
00008 RayGina::CORE::RVec3<T>::RVec3()
00009 {
00010 set(0,0,0);
00011 }
00012
00013
00014 template<typename T>
00015 RayGina::CORE::RVec3<T>::RVec3(T x, T y, T z)
00016 {
00017 set(x,y,z);
00018 }
00019
00020
00021 template<typename T>
00022 template<typename S>
00023 RayGina::CORE::RVec3<T>::RVec3(const RVec3<S>& other)
00024 {
00025 set( other.x(), other.y(), other.z() );
00026 }
00027
00028
00029 template<typename T>
00030 void
00031 RayGina::CORE::RVec3<T>::set(T x, T y, T z)
00032 {
00033 m_data[0] = x;
00034 m_data[1] = y;
00035 m_data[2] = z;
00036 }
00037
00038
00039 template<typename T>
00040 T&
00041 RayGina::CORE::RVec3<T>::at(unsigned int i)
00042 {
00043 return (*this).operator[](i);
00044 }
00045
00046
00047 template<typename T>
00048 const T&
00049 RayGina::CORE::RVec3<T>::at(unsigned int i) const
00050 {
00051 return (*this).operator[](i);
00052 }
00053
00054
00055 template<typename T>
00056 T&
00057 RayGina::CORE::RVec3<T>::operator[](unsigned int i)
00058 {
00059 return m_data[i];
00060 }
00061
00062
00063 template<typename T>
00064 const T&
00065 RayGina::CORE::RVec3<T>::operator[](unsigned int i) const
00066 {
00067 return m_data[i];
00068 }
00069
00070
00071 template<typename T>
00072 T&
00073 RayGina::CORE::RVec3<T>::x()
00074 {
00075 return m_data[0];
00076 }
00077
00078
00079 template<typename T>
00080 const T&
00081 RayGina::CORE::RVec3<T>::x() const
00082 {
00083 return m_data[0];
00084 }
00085
00086
00087 template<typename T>
00088 T&
00089 RayGina::CORE::RVec3<T>::y()
00090 {
00091 return m_data[1];
00092 }
00093
00094
00095 template<typename T>
00096 const T&
00097 RayGina::CORE::RVec3<T>::y() const
00098 {
00099 return m_data[1];
00100 }
00101
00102
00103 template<typename T>
00104 T&
00105 RayGina::CORE::RVec3<T>::z()
00106 {
00107 return m_data[2];
00108 }
00109
00110
00111 template<typename T>
00112 const T&
00113 RayGina::CORE::RVec3<T>::z() const
00114 {
00115 return m_data[2];
00116 }
00117
00118
00119 template<typename T>
00120 RayGina::CORE::RVec3<T>&
00121 RayGina::CORE::RVec3<T>::reverse()
00122 {
00123 m_data[0] = -m_data[0];
00124 m_data[1] = -m_data[1];
00125 m_data[2] = -m_data[2];
00126 return *this;
00127 }
00128
00129
00130 template<typename T>
00131 RayGina::CORE::RVec3<T>&
00132 RayGina::CORE::RVec3<T>::zero()
00133 {
00134 set(0,0,0);
00135 return *this;
00136 }
00137
00138
00139 template<typename T>
00140 T
00141 RayGina::CORE::RVec3<T>::length()
00142 {
00143 return sqrt( m_data[0]*m_data[0] + m_data[1]*m_data[1] + m_data[2]*m_data[2] );
00144 }
00145
00146
00147 template<typename T>
00148 RayGina::CORE::RVec3<T>&
00149 RayGina::CORE::RVec3<T>::normalize()
00150 {
00151 T len = length();
00152
00153 if ((len != T(1)) && (len != 0))
00154 {
00155 T _len = T(1)/len;
00156 m_data[0] *= _len;
00157 m_data[1] *= _len;
00158 m_data[2] *= _len;
00159 }
00160 return *this;
00161 }
00162
00163
00164 template<typename T>
00165 RayGina::CORE::RVec3<T>
00166 RayGina::CORE::RVec3<T>::cross(const RVec3& a, const RVec3& b)
00167 {
00168 return RVec3 (
00169 a.m_data[1]*b.m_data[2] - a.m_data[2]*b.m_data[1],
00170 a.m_data[2]*b.m_data[0] - a.m_data[0]*b.m_data[2],
00171 a.m_data[0]*b.m_data[1] - a.m_data[1]*b.m_data[0]
00172 );
00173 }
00174
00175
00176 template<typename T>
00177 RayGina::CORE::RVec3<T>
00178 RayGina::CORE::RVec3<T>::projection(const RVec3& a, const RVec3& b)
00179 {
00180 RVec3 eb = b;
00181 eb.normalize();
00182 return dot( a, eb ) * eb;
00183 }
00184
00185
00186 template<typename T>
00187 T
00188 RayGina::CORE::RVec3<T>::dot(const RVec3& a, const RVec3& b)
00189 {
00190 return a.m_data[0]*b.m_data[0] + a.m_data[1]*b.m_data[1] + a.m_data[2]*b.m_data[2];
00191 }
00192
00193
00194 template<typename T>
00195 T
00196 RayGina::CORE::RVec3<T>::spat(const RVec3& a, const RVec3& b, const RVec3& c)
00197 {
00198 return dot( a, cross(b,c) );
00199 }
00200
00201
00202 template<typename T>
00203 typename RayGina::CORE::RVec3<T>::AXIS
00204 RayGina::CORE::RVec3<T>::minDim() const
00205 {
00206 return (m_data[0] < m_data[1])?((m_data[0] < m_data[2])? AXIS_X : AXIS_Z) : ((m_data[1] < m_data[2]) ? AXIS_Y : AXIS_Z);
00207 }
00208
00209 template<typename T>
00210 typename RayGina::CORE::RVec3<T>::AXIS
00211 RayGina::CORE::RVec3<T>::maxDim() const
00212 {
00213 return (m_data[0] > m_data[1])?((m_data[0] > m_data[2])? AXIS_X : AXIS_Z) : ((m_data[1] > m_data[2]) ? AXIS_Y : AXIS_Z);
00214 }
00215
00216 template<typename T>
00217 typename RayGina::CORE::RVec3<T>::AXIS
00218 RayGina::CORE::RVec3<T>::absMinDim() const
00219 {
00220 T x = fabs(m_data[0]);
00221 T y = fabs(m_data[1]);
00222 T z = fabs(m_data[2]);
00223 return (x < y)?((x < z)? AXIS_X : AXIS_Z) : ((y < z) ? AXIS_Y : AXIS_Z);
00224 }
00225
00226 template<typename T>
00227 typename RayGina::CORE::RVec3<T>::AXIS
00228 RayGina::CORE::RVec3<T>::absMaxDim() const
00229 {
00230 T x = fabs(m_data[0]);
00231 T y = fabs(m_data[1]);
00232 T z = fabs(m_data[2]);
00233 return (x > y)?((x > z)? AXIS_X : AXIS_Z) : ((y > z) ? AXIS_Y : AXIS_Z);
00234 }
00235
00236
00237
00238 template<typename T>
00239 void
00240 RayGina::CORE::RVec3<T>::operator+=(const RVec3& b)
00241 {
00242 m_data[0] += b.m_data[0];
00243 m_data[1] += b.m_data[1];
00244 m_data[2] += b.m_data[2];
00245 }
00246
00247
00248 template<typename T>
00249 void
00250 RayGina::CORE::RVec3<T>::operator-=(const RVec3& b)
00251 {
00252 m_data[0] -= b.m_data[0];
00253 m_data[1] -= b.m_data[1];
00254 m_data[2] -= b.m_data[2];
00255 }
00256
00257
00258 template<typename T>
00259 void
00260 RayGina::CORE::RVec3<T>::operator*=(T scalar)
00261 {
00262 m_data[0] *= scalar;
00263 m_data[1] *= scalar;
00264 m_data[2] *= scalar;
00265 }
00266
00267
00268 template<typename T>
00269 bool
00270 RayGina::CORE::RVec3<T>::operator==(const RVec3& other)
00271 {
00272 return (m_data[0] == other.m_data[0] && m_data[1] == other.m_data[1] && m_data[2] == other.m_data[2]);
00273 }
00274
00275 template<typename T>
00276 bool
00277 RayGina::CORE::RVec3<T>::operator!=(const RVec3& other)
00278 {
00279 return (m_data[0] != other.m_data[0] || m_data[1] != other.m_data[1] || m_data[2] != other.m_data[2]);
00280 }
00281
00282
00283 template<typename T>
00284 bool
00285 RayGina::CORE::RVec3<T>::equal(const RVec3& vec, T delta)
00286 {
00287 return (
00288 RayGina::Rstd::equal_delta( m_data[0], vec.m_data[0], delta )
00289 && RayGina::Rstd::equal_delta( m_data[1], vec.m_data[1], delta )
00290 && RayGina::Rstd::equal_delta( m_data[2], vec.m_data[2], delta )
00291 );
00292 }
00293
00294
00295
00296
00297
00298 template<typename T>
00299 RayGina::CORE::RVec3<T>
00300 RayGina::CORE::operator*(const RVec3<T>& vec, T scalar)
00301 {
00302 RVec3<T> result = vec;
00303 result *= scalar;
00304 return result;
00305 }
00306
00307
00308 template<typename T>
00309 RayGina::CORE::RVec3<T>
00310 RayGina::CORE::operator*(T scalar, const RVec3<T>& vec)
00311 {
00312 return RayGina::CORE::operator*(vec,scalar);
00313 }
00314
00315
00316 template<typename T>
00317 RayGina::CORE::RVec3<T>
00318 RayGina::CORE::operator+(const RVec3<T>& a, const RVec3<T>& b)
00319 {
00320 RVec3<T> result = a;
00321 result += b;
00322 return result;
00323 }
00324
00325
00326 template<typename T>
00327 RayGina::CORE::RVec3<T>
00328 RayGina::CORE::operator-(const RVec3<T>& a, const RVec3<T>& b)
00329 {
00330 RVec3<T> result = a;
00331 result -= b;
00332 return result;
00333 }
00334
00335
00336 template<typename T>
00337 RayGina::CORE::RVec3<T>
00338 RayGina::CORE::operator-(const RVec3<T>& vec)
00339 {
00340 return RVec3<T>( -vec.x(), -vec.y(), -vec.z() );
00341 }
00342
00343
00344 template<typename T>
00345 std::ostream&
00346 RayGina::CORE::operator<<(std::ostream& os, const RVec3<T>& v)
00347 {
00348 os << "(" << v[0] << "," << v[1] << "," << v[2] << ")";
00349 return os;
00350 }
00351
00352 template<typename T>
00353 const RayGina::CORE::RString
00354 RayGina::CORE::operator+(const RayGina::CORE::RString& str, const RVec3<T>& v)
00355 {
00356 return (str + "(" + v[0] + "," + v[1] + "," + v[2] + ")");
00357
00358 }