HyperspaceExplorer 0.7.1
|
00001 /* 00002 Hyperspace Explorer - vizualizing higher-dimensional geometry 00003 Copyright (C) 2010 Lene Preuss <lene.preuss@gmail.com> 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License along 00016 with this program; if not, write to the Free Software Foundation, Inc., 00017 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 00019 */ 00020 00021 #ifndef VECMATH_VECTOR_IMPL_H 00022 #define VECMATH_VECTOR_IMPL_H 1 00023 00024 #include "Vector.h" 00025 00026 namespace VecMath { 00027 //------------ Vector member functions 00028 00029 // ------------ management ------------ 00030 00031 template <unsigned D, typename N> 00032 Vector<D, N>::Vector() : _x() { 00033 for (unsigned i = 0; i < D; i++) _x[i] = 0; 00034 } 00035 00037 template <unsigned D, typename N> 00038 Vector<D, N>::Vector(const N &x) : _x() { 00039 for (unsigned i = 0; i < D; i++) _x[i] = x; 00040 } 00041 00047 template <unsigned D, typename N> 00048 Vector<D, N>::Vector (N x0, N x1, ... ) : 00049 _x () { 00050 _x[0] = x0; 00051 _x[1] = x1; 00052 va_list argp; 00053 va_start (argp, x1); 00054 for (unsigned i = 2; i < D; i++) { 00055 _x[i] = va_arg (argp, N); 00056 } 00057 va_end (argp); 00058 } 00059 00060 //---------- access ---------- 00061 00064 template <unsigned D, typename N> 00065 N &Vector<D, N>::operator[] (unsigned i) { 00066 assert(i < D); 00067 return _x[i]; 00068 } 00069 00072 template <unsigned D, typename N> 00073 N Vector<D, N>::operator[] (unsigned i) const { 00074 assert(i < D); 00075 return _x[i]; 00076 } 00077 00079 template <unsigned D, typename N> 00080 unsigned Vector<D, N>::dimension (void) { 00081 return D; 00082 } 00083 00084 //---------- arithmetics ---------- 00085 00088 template <unsigned D, typename N> 00089 Vector<D, N> &Vector<D, N>::operator+= (const Vector<D, N> &Y) { 00090 for (unsigned i = 0; i < D; i++) _x[i] += Y._x[i]; 00091 return *this; 00092 } 00093 00096 template <unsigned D, typename N> 00097 Vector<D, N> &Vector<D, N>::operator-= (const Vector<D, N> &Y) { 00098 for (unsigned i = 0; i < D; i++) _x[i] -= Y._x[i]; 00099 return *this; 00100 } 00101 00104 template <unsigned D, typename N> 00105 Vector<D, N> &Vector<D, N>::operator*= (const N &s) { 00106 for (unsigned i = 0; i < D; i++) _x[i] *= s; 00107 return *this; 00108 } 00109 00111 template <unsigned D, typename N> 00112 const N *Vector<D, N>::data () const { 00113 return _x; 00114 } 00115 00123 template <unsigned D, typename N> 00124 template <typename T> 00125 Vector<D, N>::operator const T * () const { 00126 static T data[D]; 00127 for (unsigned i = 0; i < D; i++) data[i] = (T)_x[i]; 00128 return data; 00129 } 00130 00131 template <unsigned D, typename N> 00132 std::string Vector<D, N>::toString() const { 00133 std::ostringstream o; 00134 o << *this << std::ends; 00135 return o.str(); 00136 } 00137 00138 // -------- non-member functions ----------------------------------------------- 00139 00141 template <unsigned D, typename N> 00142 Vector<D, N> operator-(const Vector<D, N> &v) { 00143 Vector<D, N> Z(v); 00144 for (unsigned i = 0; i < D; i++) Z[i] = -v[i] ; 00145 return Z; 00146 } 00147 00152 template <unsigned D, typename N> 00153 Vector<D, N> operator+(const Vector<D, N> &x, const Vector<D, N> &y) { 00154 Vector<D, N> z(x); 00155 return (z += y); 00156 } 00157 00162 template <unsigned D, typename N> 00163 Vector<D, N> operator-(const Vector<D, N> &x, const Vector<D, N> &y) { 00164 Vector<D, N> z(x); 00165 return (z -= y); 00166 } 00167 00172 template <unsigned D, typename N> 00173 Vector<D, N> operator* (const Vector<D, N> &x, const N &s) { 00174 Vector<D, N> z(x); 00175 return z *= s; 00176 } 00177 00182 template <unsigned D, typename N> 00183 Vector<D, N> operator* (const N &s, const Vector<D, N> &x) { 00184 return x*s; 00185 } 00186 00191 template <unsigned D, typename N> 00192 N operator*(const Vector<D, N> &x, const Vector<D, N> &y) { 00193 N dot = 0.; 00194 for (unsigned i = 0; i < D; i++) dot += x[i]*y[i]; 00195 00196 return dot; 00197 } 00198 00203 template <unsigned D, typename N> 00204 Vector<D, N> operator/ (const Vector<D, N> &x, const N &s) { 00205 return x*(1./s); 00206 } 00207 00212 template <unsigned D, typename N> 00213 Vector<D, N> operator/ (const Vector<D, N> &x, const Vector<D, N> &y) { 00214 Vector<D, N> tmp; 00215 for (unsigned i = 0; i < D; i++) 00216 tmp[i] = x[i]/y[i]; 00217 return tmp; 00218 } 00219 00224 template <unsigned D, typename N> 00225 Vector<D, N> scale (const Vector<D, N> &x, const Vector<D, N> &y) { 00226 Vector<D, N> tmp; 00227 for (unsigned i = 0; i < D; i++) 00228 tmp[i] = x[i]*y[i]; 00229 return tmp; 00230 } 00231 00232 template <unsigned D, typename N> 00233 bool operator==(const Vector<D, N> &one, const Vector<D, N> &other) { 00234 for (unsigned i = 0; i < D; i++) { 00235 if (one[i] != other[i]) return false; 00236 } 00237 return true; 00238 } 00239 00240 template <unsigned D, typename N> 00241 bool operator!=(const Vector<D, N> &one, const Vector<D, N> &other) { 00242 return !(one == other); 00243 } 00244 00248 template <unsigned D, typename N> 00249 bool operator<(const Vector<D, N> &one, const Vector<D, N> &other) { 00250 if (sqnorm(one) == sqnorm(other)) { 00251 for (unsigned i = 0; i < D; i++) { 00252 if (one[i] < other[i]) return true; 00253 if (one[i] > other[i]) return false; 00254 } 00255 } 00256 return sqnorm(one) < sqnorm(other); 00257 } 00258 00260 template <unsigned D, typename N> 00261 N sqnorm (const Vector<D, N> &x) { 00262 return x*x; 00263 } 00264 00272 template <unsigned D, typename N> 00273 std::ostream &operator << (std::ostream &o, const Vector<D, N> &v) { 00274 // i might want to use other brackets one day 00275 o << "<"; 00276 for (unsigned i = 0; i < v.dimension ()-1; i++) 00277 o << std::setprecision(4) << v[i] << ","; 00278 o << std::setprecision(4) << v[v.dimension ()-1] << ">"; 00279 return o; 00280 } 00281 00289 template <unsigned D, typename N> 00290 std::istringstream &operator >> (std::istringstream &in, 00291 Vector<D, N> &v) { 00292 char bracket = ' '; 00293 while (bracket != '<' && !in.eof()) { in >> bracket; } 00294 for (unsigned i = 0; i < v.dimension ()-1; i++) { 00295 in >> v[i] >> bracket; 00296 } 00297 in >> v[v.dimension ()-1] >> bracket; 00298 return in; 00299 } 00300 00301 00310 template <typename N> 00311 Vector<3, N> vcross (Vector<3, N> a, Vector<3, N> b) { 00312 static Vector<3, N> c; 00313 00314 c[0] = a[1]*b[2]-a[2]*b[1]; 00315 c[1] = a[2]*b[0]-a[0]*b[2]; 00316 c[2] = a[0]*b[1]-a[1]*b[0]; 00317 00318 return c; 00319 } 00320 00330 template <typename N> 00331 Vector<4, N> vcross (Vector<4, N> a, Vector<4, N> b, Vector<4, N> c) { 00332 static Vector<4, N> d; 00333 N A = b[0]*c[1]-b[1]*c[0], 00334 B = b[0]*c[2]-b[2]*c[0], 00335 C = b[0]*c[3]-b[3]*c[0], 00336 D = b[1]*c[2]-b[2]*c[1], 00337 E = b[1]*c[3]-b[3]*c[1], 00338 F = b[2]*c[3]-b[3]*c[2]; 00339 00340 d[0] = a[1]*F - a[2]*E + a[3]*D; 00341 d[1] = -a[0]*F + a[2]*C - a[3]*B; 00342 d[2] = a[0]*E - a[1]*C + a[3]*A; 00343 d[3] = -a[0]*D + a[1]*B - a[2]*A; 00344 00345 return d; 00346 } 00347 00354 template <unsigned D, typename N> 00355 Vector<D, N> vnormalize( const Vector<D, N> &x ) { 00356 static Vector<D, N> n; 00357 N norm = sqrt(sqnorm(x)); 00358 for ( unsigned i = 0; i < D; i++ ) n[i] = x[i]/norm; 00359 return n; 00360 } 00361 00362 //------------ functions that generate a Vector without taking resort to variable arglists 00363 00369 template <typename N> Vector<2, N> makeVector(N const &x0, N const &x1) { 00370 Vector<2, N> x; 00371 00372 x[0] = x0; 00373 x[1] = x1; 00374 00375 return x; 00376 } 00377 00384 template <typename N> Vector<3, N> makeVector( 00385 N const &x0, N const &x1, N const &x2) { 00386 00387 Vector<3, N> x; 00388 00389 x[0] = x0; 00390 x[1] = x1; 00391 x[2] = x2; 00392 00393 return x; 00394 } 00395 00403 template <typename N> Vector<4, N> makeVector( 00404 N const &x0, N const &x1, N const &x2, N const &x3) { 00405 00406 Vector<4, N> x; 00407 00408 x[0] = x0; 00409 x[1] = x1; 00410 x[2] = x2; 00411 x[3] = x3; 00412 00413 return x; 00414 } 00415 00424 template <typename N> Vector<5, N> makeVector( 00425 N const &x0, N const &x1, N const &x2, N const &x3, N const &x4) { 00426 00427 Vector<5, N> x; 00428 00429 x[0] = x0; 00430 x[1] = x1; 00431 x[2] = x2; 00432 x[3] = x3; 00433 x[4] = x4; 00434 00435 return x; 00436 } 00437 00447 template <typename N> Vector<6, N> makeVector( 00448 N const &x0, N const &x1, N const &x2, N const &x3, N const &x4, 00449 N const &x5) { 00450 00451 Vector<6, N> x; 00452 00453 x[0] = x0; 00454 x[1] = x1; 00455 x[2] = x2; 00456 x[3] = x3; 00457 x[4] = x4; 00458 x[5] = x5; 00459 00460 return x; 00461 } 00462 00473 template <typename N> Vector<7, N> makeVector( 00474 N const &x0, N const &x1, N const &x2, N const &x3, N const &x4, 00475 N const &x5, N const &x6) { 00476 00477 Vector<7, N> x; 00478 00479 x[0] = x0; 00480 x[1] = x1; 00481 x[2] = x2; 00482 x[3] = x3; 00483 x[4] = x4; 00484 x[5] = x5; 00485 x[6] = x6; 00486 00487 return x; 00488 } 00489 00501 template <typename N> Vector<8, N> makeVector( 00502 N const &x0, N const &x1, N const &x2, N const &x3, N const &x4, 00503 N const &x5, N const &x6, N const &x7) { 00504 00505 Vector<8, N> x; 00506 00507 x[0] = x0; 00508 x[1] = x1; 00509 x[2] = x2; 00510 x[3] = x3; 00511 x[4] = x4; 00512 x[5] = x5; 00513 x[6] = x6; 00514 x[7] = x7; 00515 00516 return x; 00517 } 00518 00531 template <typename N> Vector<9, N> makeVector( 00532 N const &x0, N const &x1, N const &x2, N const &x3, N const &x4, 00533 N const &x5, N const &x6, N const &x7, N const &x8) { 00534 00535 Vector<9, N> x; 00536 00537 x[0] = x0; 00538 x[1] = x1; 00539 x[2] = x2; 00540 x[3] = x3; 00541 x[4] = x4; 00542 x[5] = x5; 00543 x[6] = x6; 00544 x[7] = x7; 00545 x[8] = x8; 00546 00547 return x; 00548 } 00549 00563 template <typename N> Vector<10, N> makeVector( 00564 N const &x0, N const &x1, N const &x2, N const &x3, N const &x4, 00565 N const &x5, N const &x6, N const &x7, N const &x8, N const &x9) { 00566 00567 Vector<10, N> x; 00568 00569 x[0] = x0; 00570 x[1] = x1; 00571 x[2] = x2; 00572 x[3] = x3; 00573 x[4] = x4; 00574 x[5] = x5; 00575 x[6] = x6; 00576 x[7] = x7; 00577 x[8] = x8; 00578 x[9] = x9; 00579 00580 return x; 00581 } 00582 00583 } 00584 00585 #endif