//=========================================================================== // SISL - SINTEF Spline Library, version 4.5.0. // Definition and interrogation of NURBS curves and surfaces. // // Copyright (C) 2000-2005, 2010 SINTEF ICT, Applied Mathematics, Norway. // // 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 version 2 of the License. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., // 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. // // Contact information: E-mail: tor.dokken@sintef.no // SINTEF ICT, Department of Applied Mathematics, // P.O. Box 124 Blindern, // 0314 Oslo, Norway. // // Other licenses are also available for this software, notably licenses // for: // - Building commercial software. // - Building software whose source code you wish to keep private. //=========================================================================== 00028 #ifndef JONVEC_H_INCLUDED 00029 #define JONVEC_H_INCLUDED 00030 00031 #include <stdio.h> 00032 #include <math.h> 00033 #include <vector> 00034 00035 #include "aux2.h" 00036 00037 00061 template<typename T> 00062 class vector3t 00063 { 00064 public: 00065 T coo[3]; 00066 00067 vector3t() 00068 { 00069 coo[0]=0.0; 00070 coo[1]=0.0; 00071 coo[2]=0.0; 00072 }; 00073 vector3t(const T a, const T b, const T c) 00074 { 00075 coo[0]=a; 00076 coo[1]=b; 00077 coo[2]=c; 00078 } 00079 vector3t(const float *a) 00080 { 00081 coo[0]=a[0]; 00082 coo[1]=a[1]; 00083 coo[2]=a[2]; 00084 } 00085 vector3t(const double *a) 00086 { 00087 coo[0]=a[0]; 00088 coo[1]=a[1]; 00089 coo[2]=a[2]; 00090 } 00091 // 030819: Disse to ødelegger et eller annet. Fordi de erstatter en default (og bitwise) copy constructor, uten at de samtidig er gode nok til å gjøre det??? Skjønner ikke helt hva som skjer... Må sjekkes opp... @@@ 00092 // vector3t(vector3t<float> &v0) // 030819 00093 // { 00094 // coo[0]=v0.x(); 00095 // coo[1]=v0.y(); 00096 // coo[2]=v0.z(); 00097 // } 00098 // vector3t(vector3t<double> &v0) // 030819 00099 // { 00100 // coo[0]=v0.x(); 00101 // coo[1]=v0.y(); 00102 // coo[2]=v0.z(); 00103 // } 00104 ~vector3t(void) {} 00105 00106 // vector rotate2d(T,int); 00107 // vector transform(coo_system &); 00108 00109 // 00110 // 010122: For fast access used in OpenGL: 00111 // 00112 inline const T *raw(void) const 00113 { 00114 return coo; 00115 } 00116 00117 // 00118 // 010125 00119 // 021024: Added the reference-versions. 00120 // 00121 inline T x(void) const { return coo[0]; } 00122 inline T y(void) const { return coo[1]; } 00123 inline T z(void) const { return coo[2]; } 00124 inline T &x(void) { return coo[0]; } 00125 inline T &y(void) { return coo[1]; } 00126 inline T &z(void) { return coo[2]; } 00127 00128 // 00129 // 010207 00130 // 00131 inline void setx(const T a) { coo[0]=a; } 00132 inline void sety(const T a) { coo[1]=a; } 00133 inline void setz(const T a) { coo[2]=a; } 00134 00135 // 00136 // Check out this on gcc... Why does only SGI CC complain? 00137 // 00138 inline bool operator==(const vector3t &v) const 00139 { 00140 return ((coo[0]==v.coo[0]) && (coo[1]==v.coo[1]) && (coo[2]==v.coo[2])); 00141 } 00142 00143 // 00144 // 050120: Adding this... Would also be nice with one "and"'ing the 00145 // results on each component... No, not necessary... 00146 // Remember that deMorgan gives that a<&b <=> !(a>|b). 00147 // 00148 inline bool operator<(const vector3t &v) const 00149 { 00150 return ((coo[0]<v.coo[0]) || (coo[1]<v.coo[1]) || (coo[2]<v.coo[2])); 00151 } 00152 inline bool operator>(const vector3t &v) const 00153 { 00154 return ((coo[0]>v.coo[0]) || (coo[1]>v.coo[1]) || (coo[2]>v.coo[2])); 00155 } 00156 00157 // 00158 // Note: Prefer a!=b to !(a==b) since the former is probably faster! 00159 // 00160 inline bool operator!=(const vector3t &v) const 00161 { 00162 return ((coo[0]!=v.coo[0]) || (coo[1]!=v.coo[1]) || (coo[2]!=v.coo[2])); 00163 } 00164 00165 // 00166 // Ok, the strange warning produced when actually using this operator, 00167 // stemmed from a missing 'const' at the end of the declaration of 00168 // this operator. (Then the function could have altered *this, and 00169 // that would have discarded any const'ness...) 00170 // 00171 inline const vector3t operator+(const vector3t &v) const 00172 { 00173 return vector3t(coo[0]+v.coo[0], coo[1]+v.coo[1], coo[2]+v.coo[2]); 00174 } 00175 00176 inline vector3t &operator+=(const vector3t &v) 00177 { 00178 coo[0]+=v.coo[0]; coo[1]+=v.coo[1]; coo[2]+=v.coo[2]; 00179 return *this; 00180 } 00181 00182 // 030819 00183 // inline vector3t<float> &operator+=(const vector3t<double> &v) 00184 // { 00185 // coo[0]+=v.coo[0]; coo[1]+=v.coo[1]; coo[2]+=v.coo[2]; 00186 // return *this; 00187 // } 00188 00189 inline vector3t &operator-=(const vector3t &v) 00190 { 00191 coo[0]-=v.coo[0]; coo[1]-=v.coo[1]; coo[2]-=v.coo[2]; 00192 return *this; 00193 } 00194 00195 // 030513 00196 inline vector3t &operator-=(const T &d) 00197 { 00198 coo[0]-=d; coo[1]-=d; coo[2]-=d; 00199 return *this; 00200 } 00201 00202 // 030626 00203 inline vector3t &operator+=(const T &d) 00204 { 00205 coo[0]+=d; coo[1]+=d; coo[2]+=d; 00206 return *this; 00207 } 00208 00209 // 030709 00210 inline vector3t &operator*=(const double x) 00211 { 00212 coo[0]*=x; coo[1]*=x; coo[2]*=x; 00213 return *this; 00214 } 00215 00216 // 030709 00217 inline vector3t &operator/=(const double x) 00218 { 00219 coo[0]/=x; coo[1]/=x; coo[2]/=x; 00220 return *this; 00221 } 00222 00223 inline const vector3t operator-(const vector3t &v) const 00224 { 00225 return vector3t(coo[0]-v.coo[0], coo[1]-v.coo[1], coo[2]-v.coo[2]); 00226 } 00227 00228 // 000310 00229 inline const vector3t operator-(const T &d) const 00230 { 00231 return vector3t(coo[0]-d, coo[1]-d, coo[2]-d); 00232 } 00233 00234 inline const vector3t operator-(void) const 00235 { 00236 return vector3t(-coo[0], -coo[1], -coo[2]); 00237 } 00238 00239 // 00240 // Why can't a non-member operator like this be 'const'? 00241 // 00242 inline const friend vector3t operator*(const T &a, const vector3t &v) 00243 { 00244 return vector3t(a*v.coo[0], a*v.coo[1], a*v.coo[2]); 00245 } 00246 00247 // 030120: 00248 inline const friend vector3t operator+(const double &a, const vector3t &v) 00249 { 00250 return vector3t(a+v.coo[0], a+v.coo[1], a+v.coo[2]); 00251 } 00252 inline const friend vector3t operator+(const float &a, const vector3t &v) 00253 { 00254 return vector3t(a+v.coo[0], a+v.coo[1], a+v.coo[2]); 00255 } 00256 00257 inline T operator*(const vector3t &v) const 00258 { 00259 return (coo[0]*v.coo[0] + coo[1]*v.coo[1] + coo[2]*v.coo[2]); 00260 } 00261 00262 inline vector3t operator/(const vector3t &v) const 00263 { 00264 return (vector3t(coo[1]*v.coo[2]-coo[2]*v.coo[1], 00265 coo[2]*v.coo[0]-coo[0]*v.coo[2], 00266 coo[0]*v.coo[1]-coo[1]*v.coo[0])); 00267 } 00268 00269 // 00270 // Why can't I make this a const function? 00271 // 00272 inline friend T cosangle(const vector3t &v0, const vector3t &v1) 00273 { 00274 return ((v0*v1)/sqrt((v0*v0)*(v1*v1))); 00275 } 00276 00277 inline const vector3t &clamp(const vector3t &v0, const vector3t &v1) 00278 { 00279 coo[0]=std::max(v0.coo[0], std::min(v1.coo[0], coo[0])); 00280 coo[1]=std::max(v0.coo[1], std::min(v1.coo[1], coo[1])); 00281 coo[2]=std::max(v0.coo[2], std::min(v1.coo[2], coo[2])); 00282 return *this; 00283 } 00284 00285 // 00286 // Added 021010: 00287 // (Hmm... What is the sensible thing to do in such a case, 00288 // return a new object, like for 'clamp' above, or to just modify 00289 // *this, like in this definition??) 00290 // 00291 #ifdef MICROSOFT 00292 // 00293 // 030208: I simply don't know where these get defined as macros... 00294 // (But I suspect some Microsoft .h-file does it...) 00295 // 00296 # undef min 00297 # undef max 00298 #endif 00299 inline void min(const vector3t &v) 00300 { 00301 coo[0]=std::min(v.x(), x()); 00302 coo[1]=std::min(v.y(), y()); 00303 coo[2]=std::min(v.z(), z()); 00304 } 00305 inline void max(const vector3t &v) 00306 { 00307 coo[0]=std::max(v.x(), x()); 00308 coo[1]=std::max(v.y(), y()); 00309 coo[2]=std::max(v.z(), z()); 00310 } 00311 00312 00313 // 00314 // When I do this, how come that I'm allowed to do something like this: 00315 // 00316 // vector3t x, y, z, w; 00317 // z=x.conv(y); 00318 // z+=w; 00319 // 00320 // Aha. Because it's the z I modify, not the return value of conv. 00321 // This shouldn't work: 00322 // 00323 // (x.conv(y)).conv(w) 00324 // 00325 // And it does not. Therefore, 'inline vec...' instead of 00326 // 'inline const vec...'. 00327 // 00328 inline vector3t &conv(const vector3t &v) 00329 { 00330 coo[0]*=v.coo[0]; 00331 coo[1]*=v.coo[1]; 00332 coo[2]*=v.coo[2]; 00333 return *this; 00334 } 00335 // 050122: Added this variation. 00336 inline friend vector3t conv2(const vector3t &v1, const vector3t &v2) 00337 { 00338 return vector3t(v1.x()*v2.x(), v1.y()*v2.y(), v1.z()*v2.z()); 00339 } 00340 00341 // 050122: Added this... Note, no checking on components being zero! 00342 // So, to scale V to the box with corners A and B: 00343 // conv2((B-A).reciprocal(), V-A); 00344 inline vector3t reciprocal(void) const 00345 { 00346 return vector3t(1.0/coo[0], 1.0/coo[1], 1.0/coo[2]); 00347 } 00348 00349 // 050122: Might as well add this, then, for better clarity in calling code. 00350 // Hmm... 'transform' or something would have been a better name. 00351 inline vector3t &rescale(const vector3t &mi, const vector3t &ma, 00352 const vector3t &new_mi, const vector3t &new_ma) 00353 { 00354 *this=conv2(conv2((ma-mi).reciprocal(), *this-mi), new_ma-new_mi)+new_mi; 00355 return *this; 00356 } 00357 00358 inline T length_squared(void) const 00359 { 00360 return (coo[0]*coo[0]+coo[1]*coo[1]+coo[2]*coo[2]); 00361 } 00362 00363 inline T length(void) const 00364 { 00365 return (sqrt(length_squared())); 00366 //return (sqrt(coo[0]*coo[0]+coo[1]*coo[1]+coo[2]*coo[2])); 00367 } 00368 00369 inline void normalize(void) 00370 { 00371 const T tmp=1.0/length(); 00372 coo[0]*=tmp; 00373 coo[1]*=tmp; 00374 coo[2]*=tmp; 00375 } 00376 00377 inline vector3t normalized(void) const 00378 { 00379 return (1.0/length())*(*this); 00380 } 00381 00382 void print(void) const 00383 { 00384 printf("vector3t(%f %f %f)\n", 00385 (double)coo[0], (double)coo[1], (double)coo[2]); 00386 } 00387 00388 // 041212: Added version which does not print a newline. 00389 void print2(void) const 00390 { 00391 printf("vector3t(%f %f %f)", 00392 (double)coo[0], (double)coo[1], (double)coo[2]); 00393 } 00394 00395 // 050214: Added version which does not print a newline, fixed size. 00396 void print3(void) const 00397 { 00398 printf("(%7.3f %7.3f %7.3f)", 00399 (double)coo[0], (double)coo[1], (double)coo[2]); 00400 } 00401 00402 inline T min_coo(void) const 00403 { 00404 return std::min(coo[0], std::min(coo[1], coo[2])); 00405 } 00406 00407 inline T max_coo(void) const 00408 { 00409 return std::max(coo[0], std::max(coo[1], coo[2])); 00410 } 00411 00412 inline bool dequal(const vector3t<T> &v) const 00413 { 00414 return (DEQUAL(x(), v.x()) && DEQUAL(y(), v.y()) && DEQUAL(z(), v.z())); 00415 } 00416 00417 inline bool dequal2(const vector3t<T> &v) const 00418 { 00419 return (DEQUAL2(x(), v.x()) && 00420 DEQUAL2(y(), v.y()) && 00421 DEQUAL2(z(), v.z())); 00422 } 00423 00424 // 030711: For floats 00425 inline bool dequal3(const vector3t<T> &v) const 00426 { 00427 return (DEQUAL3(x(), v.x()) && 00428 DEQUAL3(y(), v.y()) && 00429 DEQUAL3(z(), v.z())); 00430 } 00431 00432 // 030209: Useful because we avoid casting to a vector2t. 00433 inline bool dequal_2d(const vector3t<T> &v) const 00434 { 00435 return (DEQUAL(x(), v.x()) && DEQUAL(y(), v.y())); 00436 } 00437 00438 // 030709: Rotation in the xy-plane, i.e., around the z-axis. 00439 inline void rotate_xy(const double cosa, const double sina) 00440 { 00441 double oldx=coo[0], oldy=coo[1]; 00442 coo[0] = cosa*oldx + sina*oldy; 00443 coo[1] = -sina*oldx + cosa*oldy; 00444 } 00445 00446 // 030709: Rotation in the xz-plane, i.e., around the y-axis, but note the 00447 // "opposite" orientation... 00448 inline void rotate_xz(const double cosa, const double sina) 00449 { 00450 double oldx=coo[0], oldz=coo[2]; 00451 coo[0] = cosa*oldx + sina*oldz; 00452 coo[2] = -sina*oldx + cosa*oldz; 00453 } 00454 00455 // 030819: Rotation in the yz-plane, i.e., around the x-axis. 00456 inline void rotate_yz(const double cosa, const double sina) 00457 { 00458 double oldy=coo[1], oldz=coo[2]; 00459 coo[1] = cosa*oldy + sina*oldz; 00460 coo[2] = -sina*oldy + cosa*oldz; 00461 } 00462 }; 00463 00464 00465 00466 00467 00468 00469 #endif
1.6.3