00001 #ifndef VECTOR3_H_
00002 #define VECTOR3_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "lrint.h"
00018 #include <sstream>
00019 #include <string>
00020 #include <cmath>
00021 #include <float.h>
00022
00023
00024 template<typename Element>
00025 class BasicVector3
00026 {
00027
00028
00029 Element m_elements[3];
00030
00031 public:
00032
00033
00034 BasicVector3 ()
00035 {
00036 }
00037
00038
00039 template<typename OtherElement>
00040 BasicVector3 (const BasicVector3<OtherElement>& other)
00041 {
00042 x() = static_cast<Element> (other.x());
00043 y() = static_cast<Element> (other.y());
00044 z() = static_cast<Element> (other.z());
00045 }
00046
00049 BasicVector3 (const Element& x_, const Element& y_, const Element& z_)
00050 {
00051 x() = x_;
00052 y() = y_;
00053 z() = z_;
00054 }
00055
00059 BasicVector3 (const Element* array)
00060 {
00061 for (int i = 0; i < 3; ++i)
00062 m_elements[i] = array[i];
00063 }
00064
00072 BasicVector3 (const std::string& str)
00073 {
00074
00075 m_elements[0] = m_elements[1] = m_elements[2] = 0;
00076
00077 std::stringstream strm(str);
00078 strm << std::skipws;
00079 strm >> x();
00080 strm >> y();
00081 strm >> z();
00082 }
00083
00086 void set (const Element& x, const Element& y, const Element& z)
00087 {
00088 m_elements[0] = x;
00089 m_elements[1] = y;
00090 m_elements[2] = z;
00091 }
00092
00093
00094 Element& x ()
00095 {
00096 return m_elements[0];
00097 }
00098 Element& y ()
00099 {
00100 return m_elements[1];
00101 }
00102 Element& z ()
00103 {
00104 return m_elements[2];
00105 }
00106
00107
00108 const Element& x () const
00109 {
00110 return m_elements[0];
00111 }
00112 const Element& y () const
00113 {
00114 return m_elements[1];
00115 }
00116 const Element& z () const
00117 {
00118 return m_elements[2];
00119 }
00120
00123 bool operator== (const BasicVector3& other) const
00124 {
00125 return (other.x() == x() && other.y() == y() && other.z() == z());
00126 }
00127
00130 bool operator!= (const BasicVector3& other) const
00131 {
00132 return !(*this == other);
00133 }
00134
00135
00136
00137
00138 BasicVector3<Element> operator- () const
00139 {
00140 return BasicVector3<Element> (-m_elements[0], -m_elements[1], -m_elements[2]);
00141 }
00142
00143
00144
00145
00146 template<typename OtherElement>
00147 BasicVector3<Element> operator+ (const BasicVector3<OtherElement>& other) const
00148 {
00149 return BasicVector3<Element> (m_elements[0] + static_cast<Element> (other.x()), m_elements[1]
00150 + static_cast<Element> (other.y()), m_elements[2] + static_cast<Element> (other.z()));
00151 }
00152
00153 template<typename OtherElement>
00154 void operator+= (const BasicVector3<OtherElement>& other)
00155 {
00156 m_elements[0] += static_cast<Element> (other.x());
00157 m_elements[1] += static_cast<Element> (other.y());
00158 m_elements[2] += static_cast<Element> (other.z());
00159 }
00160
00161
00162
00163
00164 template<typename OtherElement>
00165 BasicVector3<Element> operator- (const BasicVector3<OtherElement>& other) const
00166 {
00167 return BasicVector3<Element> (m_elements[0] - static_cast<Element> (other.x()), m_elements[1]
00168 - static_cast<Element> (other.y()), m_elements[2] - static_cast<Element> (other.z()));
00169 }
00170
00171 template<typename OtherElement>
00172 void operator-= (const BasicVector3<OtherElement>& other)
00173 {
00174 m_elements[0] -= static_cast<Element> (other.x());
00175 m_elements[1] -= static_cast<Element> (other.y());
00176 m_elements[2] -= static_cast<Element> (other.z());
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 template<typename OtherElement>
00188 BasicVector3<Element> operator* (const BasicVector3<OtherElement>& other) const
00189 {
00190 return BasicVector3<Element> (m_elements[0] * static_cast<Element> (other.x()), m_elements[1]
00191 * static_cast<Element> (other.y()), m_elements[2] * static_cast<Element> (other.z()));
00192 }
00193
00194 template<typename OtherElement>
00195 void operator*= (const BasicVector3<OtherElement>& other)
00196 {
00197 m_elements[0] *= static_cast<Element> (other.x());
00198 m_elements[1] *= static_cast<Element> (other.y());
00199 m_elements[2] *= static_cast<Element> (other.z());
00200 }
00201
00202
00203
00204 template<typename OtherElement>
00205 BasicVector3<Element> operator* (const OtherElement& other) const
00206 {
00207 Element factor = static_cast<Element> (other);
00208 return BasicVector3<Element> (m_elements[0] * factor, m_elements[1] * factor, m_elements[2] * factor);
00209 }
00210
00211 template<typename OtherElement>
00212 void operator*= (const OtherElement& other)
00213 {
00214 Element factor = static_cast<Element> (other);
00215 m_elements[0] *= factor;
00216 m_elements[1] *= factor;
00217 m_elements[2] *= factor;
00218 }
00219
00220
00221
00222
00223 template<typename OtherElement>
00224 BasicVector3<Element> operator/ (const BasicVector3<OtherElement>& other) const
00225 {
00226 return BasicVector3<Element> (m_elements[0] / static_cast<Element> (other.x()), m_elements[1]
00227 / static_cast<Element> (other.y()), m_elements[2] / static_cast<Element> (other.z()));
00228 }
00229
00230 template<typename OtherElement>
00231 void operator/= (const BasicVector3<OtherElement>& other)
00232 {
00233 m_elements[0] /= static_cast<Element> (other.x());
00234 m_elements[1] /= static_cast<Element> (other.y());
00235 m_elements[2] /= static_cast<Element> (other.z());
00236 }
00237
00238
00239
00240 template<typename OtherElement>
00241 BasicVector3<Element> operator/ (const OtherElement& other) const
00242 {
00243 Element divisor = static_cast<Element> (other);
00244 return BasicVector3<Element> (m_elements[0] / divisor, m_elements[1] / divisor, m_elements[2] / divisor);
00245 }
00246
00247 template<typename OtherElement>
00248 void operator/= (const OtherElement& other)
00249 {
00250 Element divisor = static_cast<Element> (other);
00251 m_elements[0] /= divisor;
00252 m_elements[1] /= divisor;
00253 m_elements[2] /= divisor;
00254 }
00255
00256
00257
00258
00259
00265 double getLength () const
00266 {
00267 double lenSquared = m_elements[0] * m_elements[0] + m_elements[1] * m_elements[1] + m_elements[2]
00268 * m_elements[2];
00269 return sqrt(lenSquared);
00270 }
00271
00274 double getLengthSquared () const
00275 {
00276 double lenSquared = m_elements[0] * m_elements[0] + m_elements[1] * m_elements[1] + m_elements[2]
00277 * m_elements[2];
00278 return lenSquared;
00279 }
00280
00281
00282
00283 BasicVector3<Element> getNormalised () const
00284 {
00285 return (*this) / getLength();
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 template<typename OtherT>
00299 Element dot (const BasicVector3<OtherT>& other) const
00300 {
00301 return Element(m_elements[0] * other.x() + m_elements[1] * other.y() + m_elements[2] * other.z());
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 template<typename OtherT>
00315 BasicVector3<Element> crossProduct (const BasicVector3<OtherT>& other) const
00316 {
00317 return BasicVector3<Element> (m_elements[1] * other.z() - m_elements[2] * other.y(), m_elements[2]
00318 * other.x() - m_elements[0] * other.z(), m_elements[0] * other.y() - m_elements[1] * other.x());
00319 }
00320
00324 std::string toString () const
00325 {
00326 std::stringstream ss;
00327 ss << m_elements[0] << " " << m_elements[1] << " " << m_elements[2];
00328 return ss.str();
00329 }
00330
00337 operator const Element* () const
00338 {
00339 return m_elements;
00340 }
00341
00342 operator Element* ()
00343 {
00344 return m_elements;
00345 }
00346
00347 };
00348
00352 template<typename T>
00353 std::ostream& operator<< (std::ostream& st, BasicVector3<T> vec)
00354 {
00355 st << "<" << vec.x() << ", " << vec.y() << ", " << vec.z() << ">";
00356 return st;
00357 }
00358
00359
00360
00361
00362 typedef BasicVector3<float> Vector3;
00363
00364
00365
00366 const Vector3 g_vector3_identity(0, 0, 0);
00367 const Vector3 g_vector3_max = Vector3(FLT_MAX, FLT_MAX, FLT_MAX);
00368 const Vector3 g_vector3_axis_x(1, 0, 0);
00369 const Vector3 g_vector3_axis_y(0, 1, 0);
00370 const Vector3 g_vector3_axis_z(0, 0, 1);
00371
00372 const Vector3 g_vector3_axes[3] = { g_vector3_axis_x, g_vector3_axis_y, g_vector3_axis_z };
00373
00374 template<typename Element, typename OtherElement>
00375 inline void vector3_swap (BasicVector3<Element>& self, BasicVector3<OtherElement>& other)
00376 {
00377 std::swap(self.x(), other.x());
00378 std::swap(self.y(), other.y());
00379 std::swap(self.z(), other.z());
00380 }
00381
00382 template<typename Element, typename OtherElement, typename Epsilon>
00383 inline bool vector3_equal_epsilon (const BasicVector3<Element>& self, const BasicVector3<OtherElement>& other,
00384 Epsilon epsilon)
00385 {
00386 return float_equal_epsilon(self.x(), other.x(), epsilon) && float_equal_epsilon(self.y(), other.y(), epsilon)
00387 && float_equal_epsilon(self.z(), other.z(), epsilon);
00388 }
00389
00390 template<typename Element>
00391 inline BasicVector3<Element> vector3_mid (const BasicVector3<Element>& begin, const BasicVector3<Element>& end)
00392 {
00393 return (begin + end) * 0.5;
00394 }
00395
00396 template<typename Element>
00397 inline Element float_divided (Element f, Element other)
00398 {
00399 return f / other;
00400 }
00401
00402 template<typename Element>
00403 inline void vector3_normalise (BasicVector3<Element>& self)
00404 {
00405 self = self.getNormalised();
00406 }
00407
00408 template<typename Element>
00409 inline BasicVector3<Element> vector3_snapped (const BasicVector3<Element>& self)
00410 {
00411 return BasicVector3<Element> (Element(float_to_integer(self.x())), Element(float_to_integer(self.y())), Element(
00412 float_to_integer(self.z())));
00413 }
00414
00415 template<typename Element>
00416 inline void vector3_snap (BasicVector3<Element>& self)
00417 {
00418 self = vector3_snapped(self);
00419 }
00420
00421 template<typename Element, typename OtherElement>
00422 inline BasicVector3<Element> vector3_snapped (const BasicVector3<Element>& self, const OtherElement& snap)
00423 {
00424 return BasicVector3<Element> (Element(float_snapped(self.x(), snap)), Element(float_snapped(self.y(), snap)),
00425 Element(float_snapped(self.z(), snap)));
00426 }
00427 template<typename Element, typename OtherElement>
00428 inline void vector3_snap (BasicVector3<Element>& self, const OtherElement& snap)
00429 {
00430 self = vector3_snapped(self, snap);
00431 }
00432
00433 inline Vector3 vector3_for_spherical (double theta, double phi)
00434 {
00435 return Vector3(static_cast<float> (cos(theta) * cos(phi)), static_cast<float> (sin(theta) * cos(phi)),
00436 static_cast<float> (sin(phi)));
00437 }
00438
00439 #endif