Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

Vect3D.hpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 1998 Marcel Bosc  
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  *
00018  */
00021 #ifndef _Vect3D_hpp
00022 #define _Vect3D_hpp
00023 
00024 #include<stdio.h>
00025 #include<stdlib.h>
00026 #include<stdio.h>
00027 #include<math.h>
00028 #include<string.h>
00029 #include<iostream>
00030 #include<algorithm>
00031 #include<ImLib3D/CppTools.hpp>
00032 #include<ImLib3D/istream_flag_resetter.hpp>
00033 
00034 // ********************** Vect3D ********************
00036 template<class Value,class Real=Value>
00037 class Vect3D
00038 {
00039     typedef Vect3D<Value,Real> _Self;
00040 public:
00041     Value x,y,z;
00042 
00043 //  ~Vect3D(){;}
00044     Vect3D(Value _x,Value _y,Value _z):x(_x),y(_y),z(_z){}
00045     Vect3D(){}
00046 
00047     Real Norme2()const {return(x*x+y*y+z*z);}
00048     Real Norm2() const {return(x*x+y*y+z*z);}
00049     Real Norme() const {return(sqrt(Norme2()));}
00050     Real Norm()  const {return(sqrt(Norme2()));}
00051     Real Unit();
00052     Real SafeUnit();
00053 
00054     Real Dist2(const Vect3D &p2) const {return((p2.x-x)*(p2.x-x)+(p2.y-y)*(p2.y-y)+(p2.z-z)*(p2.z-z));}
00055     Real Dist(const Vect3D &p2) const {return(sqrt(Dist2(p2)));}
00056     Real Distance2(const Vect3D &p2) const {return((p2.x-x)*(p2.x-x)+(p2.y-y)*(p2.y-y)+(p2.z-z)*(p2.z-z));}
00057     Real Distance(const Vect3D &p2) const {return(sqrt(Dist2(p2)));}
00058 
00059     void Rotate(Vect3D axis,double angle)
00060     {
00061         Vect3D &V=*this;
00062         axis.Unit();
00063         Vect3D Vn=(V*axis)*axis;
00064         *this=Vn+cos(angle)*(V-Vn)+sin(angle)*(axis^V);
00065     }
00066 
00067     int MaxCoord() const {return (x>y ? (x>z ? 0 : 2) : (y>z ? 1 : 2));}
00068     int MinCoord() const {return (x<y ? (x<z ? 0 : 2) : (y<z ? 1 : 2));}
00069     int MaxAbsCoord() const 
00070     {
00071         return (fabs((float)x)>fabs((float)y) ? 
00072                 (fabs((float)x)>fabs((float)z) ? 0 : 2) : 
00073                 (fabs((float)y)>fabs((float)z) ? 1 : 2));
00074     }
00075     int MinAbsCoord() const 
00076     {
00077         return (fabs((float)x)<fabs((float)y) ? 
00078                 (fabs((float)x)<fabs((float)z) ? 0 : 2) : 
00079                 (fabs((float)y)<fabs((float)z) ? 1 : 2));
00080     }
00081     _Self OrthogonalVect() const 
00082     {_Self v(0,0,0);v(MinAbsCoord())=1;return (*this)^v;}
00083 
00084     void Show() const {Show("","");}
00085     void Show(const char *p) const {Show(p,"");}
00086     void Show(const char *p,const char *s) const 
00087     {
00088 #ifdef _CppTools_hpp
00089         if(IsSameType<Value,int>())
00090         {printf("%s%d %d %d%s",p,(int)x,(int)y,(int)z,s);}
00091         else{printf("%s%f %f %f%s",p,(float)x,(float)y,(float)z,s);}
00092 #else // _CppTools_hpp
00093         printf("%s%f %f %f%s",p,(float)x,(float)y,(float)z,s);
00094 #endif // _CppTools_hpp
00095     }
00096 
00097 
00098     Value & operator()(int i)
00099     {
00100         switch(i)
00101         {case 0:return x;case 1:return y;case 2:return z;}
00102         return x;
00103     }
00104 
00105     Value  operator()(int i) const
00106     {
00107         switch(i)
00108         {case 0:return x;case 1:return y;case 2:return z;}
00109         return x;
00110     }
00111     Vect3D<Value,Real>& operator=(Value val)
00112     {
00113         x=val;
00114         y=val;
00115         z=val;
00116         return *this;
00117     }
00118     
00119 // can't get these to compile on all compilers???
00120 //      friend Vect3D operator+ (const Vect3D& v1,const Vect3D& v2);
00121 //      friend Vect3D operator- (const Vect3D& v1,const Vect3D& v2);
00122 //      friend Value operator*  (const Vect3D& v1,const Vect3D& v2);
00123 //      friend Vect3D operator* (Value l,const Vect3D& v2);
00124 //      friend Vect3D operator* (int l,const Vect3D& v2);
00125 //      friend Vect3D operator/ (const Vect3D& v1,Value l);
00126 //      friend Vect3D operator^ (const Vect3D& v1,const Vect3D& v2);
00127 
00128     bool operator==(const Vect3D &other) const {return other.x==x && other.y==y && other.z==z;}
00129     bool operator!=(const Vect3D &other) const {return !((*this)==other);}
00130     Vect3D &operator+=(const Vect3D &v){x+=v.x;y+=v.y;z+=v.z;return(*this);}
00131     Vect3D &operator-=(const Vect3D &v){x-=v.x;y-=v.y;z-=v.z;return(*this);}
00132     Vect3D &operator/=(const Value &d) {x/=d;  y/=d;  z/=d;return(*this);}
00133     Vect3D &operator*=(const Value &d) {x*=d;  y*=d;  z*=d;return(*this);}
00134     Vect3D  operator-() const {return Vect3D(-x,-y,-z);}
00135 
00136     template<class V1,class R1>
00137     operator Vect3D<V1,R1> () const {return Vect3D<V1,R1>(x,y,z);}
00138 };
00139 
00140 template<class Value,class Real>
00141 inline
00142 Real
00143 Vect3D<Value,Real>::Unit()
00144 {
00145     Real n2=Norme2();
00146 #ifdef _CppTools_hpp
00147     if (n2==0) { ThrowError("Vect3D::Unit: UNIT FAILED");}
00148 #else  // _CppTools_hpp
00149     fprintf(stderr,"Vect3D::Unit: UNIT FAILED\n");
00150 #endif // _CppTools_hpp
00151     if(n2==1){return 1;}
00152     Real n=sqrt(n2);
00153     x/=(Value)n;
00154     y/=(Value)n;
00155     z/=(Value)n;
00156     return(n);
00157 }
00158 template<class Value,class Real>
00159 inline
00160 Real
00161 Vect3D<Value,Real>::SafeUnit()
00162 {
00163     Real n2=Norme2();
00164     if(!finite(n2) || n2==0) { *this=Vect3D(1,0,0);return sqrt(n2);}
00165     if(n2==1){return 1;}
00166     Real n=sqrt(n2);
00167     x/=(Value)n;
00168     y/=(Value)n;
00169     z/=(Value)n;
00170     return(n);
00171 }
00172 
00173 
00174 template<class Value,class Real>
00175 inline Vect3D<Value,Real>
00176 operator+ (const Vect3D<Value,Real>& v1,const Vect3D<Value,Real>& v2)
00177 {
00178     Vect3D<Value,Real> opres;
00179     opres.x=v1.x+v2.x;
00180     opres.y=v1.y+v2.y;
00181     opres.z=v1.z+v2.z;
00182     return opres;
00183 }
00184 
00185 
00186 template<class Value,class Real>
00187 inline Vect3D<Value,Real>
00188 operator- (const Vect3D<Value,Real>& v1,const Vect3D<Value,Real>& v2)
00189 {
00190     Vect3D<Value,Real> opres;
00191     opres.x=v1.x-v2.x;
00192     opres.y=v1.y-v2.y;
00193     opres.z=v1.z-v2.z;
00194     return opres;
00195 }
00196 
00197 template<class Value,class Real>
00198 inline Value 
00199 operator* (const Vect3D<Value,Real>& v1,const Vect3D<Value,Real>& v2)
00200 {
00201     return(v1.x*v2.x+v1.y*v2.y+v1.z*v2.z);
00202 }
00203 
00204 template<class Value,class Real>
00205 inline Vect3D<Value,Real>
00206 operator/(const Vect3D<Value,Real>& v1,Value l)
00207 {
00208     Vect3D<Value,Real> opres;
00209     opres.x=v1.x/l;
00210     opres.y=v1.y/l;
00211     opres.z=v1.z/l;
00212     return opres;
00213 }
00214 
00215 
00216 template<class Value,class Real>
00217 inline Vect3D<Value,Real>
00218 operator* (float l,const Vect3D<Value,Real>& v1)
00219 {
00220     Vect3D<Value,Real> opres;
00221     opres.x=v1.x*l;
00222     opres.y=v1.y*l;
00223     opres.z=v1.z*l;
00224     return opres;
00225 }
00226 template<class Value,class Real>
00227 inline Vect3D<Value,Real>
00228 operator* (double l,const Vect3D<Value,Real>& v1)
00229 {
00230     Vect3D<Value,Real> opres;
00231     opres.x=(Value)(v1.x*l);
00232     opres.y=(Value)(v1.y*l);
00233     opres.z=(Value)(v1.z*l);
00234     return opres;
00235 }
00236 
00237 template<class Value,class Real>
00238 inline Vect3D<Value,Real>
00239 operator* (int l,const Vect3D<Value,Real>& v1)
00240 {
00241     Vect3D<Value,Real> opres;
00242     opres.x=v1.x*l;
00243     opres.y=v1.y*l;
00244     opres.z=v1.z*l;
00245     return opres;
00246 }
00247 
00248 template<class Value,class Real>
00249 inline Vect3D<Value,Real>
00250 operator^ (const Vect3D<Value,Real>& v1,const Vect3D<Value,Real>& v2)
00251 {
00252     Vect3D<Value,Real> opres;
00253     opres.x=v1.y*v2.z-v1.z*v2.y;
00254     opres.y=v1.z*v2.x-v1.x*v2.z;
00255     opres.z=v1.x*v2.y-v1.y*v2.x;
00256     return opres;
00257 }
00258 
00259 template<class Value,class Real>
00260 inline Vect3D<Value,Real>
00261 operator% (const Vect3D<Value,Real>& v1,const Vect3D<Value,Real>& v2)
00262 {
00263     Vect3D<Value,Real> opres;
00264     opres.x=v1.x*v2.x;
00265     opres.y=v1.y*v2.y;
00266     opres.z=v1.z*v2.z;
00267     return opres;
00268 }
00269 
00270 template<class Value, class Real>
00271 inline ostream& operator<< (ostream& s, const Vect3D<Value, Real>& vect)
00272 {
00273     s << vect.x << " " << vect.y << " " << vect.z;
00274 //      s << "(" << vect.x << ", "<< vect.y << ", " << vect.z << ")" << endl;
00275     return s;
00276 }
00277 
00279 template<class Value, class Real>
00280 inline istream& operator>> (istream& s, Vect3D<Value, Real>& vect)
00281 {
00282     istream_flag_resetter resetter(s);
00283     s.setf(ios::skipws);
00284     char c;
00285     s >> c;
00286     if (c=='(')
00287     {
00288         s >> vect.x >> c;
00289         if (c==',' || c==';')
00290         {
00291             s >> vect.y >> c;
00292             if (c==',' || c==';')
00293                 s >> vect.z >> c;
00294 #ifdef _CppTools_hpp
00295             if (c!=')') ThrowError("istream& operator>> (istream& s, Vect3D<Value, Real>& vect) bad format");
00296 #endif // _CppTools_hpp
00297         }
00298     }
00299     else
00300     {
00301         s.putback(c);
00302         s >> vect.x >> vect.y >> vect.z;
00303     }
00304     return s;
00305 }
00306 
00307 typedef Vect3D<float,float>   Vect3Df;
00308 typedef Vect3D<double,double> Vect3Dd;
00309 typedef Vect3D<int,float>     Vect3Di;
00310 
00311 // for some reason the compiler doesnt use the conversion operators to deduce these??
00312 inline Vect3Df operator+ (const Vect3Di& v1,const Vect3Df& v2) {return (Vect3Df)v1+v2;}
00313 inline Vect3Df operator+ (const Vect3Df& v1,const Vect3Di& v2) {return v1+(Vect3Df)v2;}
00314 inline Vect3Df operator- (const Vect3Di& v1,const Vect3Df& v2) {return (Vect3Df)v1-v2;}
00315 inline Vect3Df operator- (const Vect3Df& v1,const Vect3Di& v2) {return v1-(Vect3Df)v2;}
00316 
00317 
00318 
00319 template<class Value,class Real>
00320 Vect3D<Value,Real> max(const Vect3D<Value,Real> &v1,const Vect3D<Value,Real> &v2)
00321 {
00322     return Vect3D<Value,Real>(max(v1.x,v2.x),max(v1.y,v2.y),max(v1.z,v2.z));
00323 }
00324 template<class Value,class Real>
00325 Vect3D<Value,Real> min(const Vect3D<Value,Real> &v1,const Vect3D<Value,Real> &v2)
00326 {
00327     return Vect3D<Value,Real>(min(v1.x,v2.x),min(v1.y,v2.y),min(v1.z,v2.z));
00328 }
00329 
00330 inline Vect3Di floor(const Vect3Df &p){return Vect3Di((int)floor(p.x),(int)floor(p.y),(int)floor(p.z));}
00331 inline Vect3Di ceil (const Vect3Df &p){return Vect3Di((int)ceil (p.x),(int)ceil (p.y),(int)ceil (p.z));}
00332 inline Vect3Di rint (const Vect3Df &p){return Vect3Di((int)rint (p.x),(int)rint (p.y),(int)rint (p.z));}
00333 
00334 
00335 #ifdef _CppTools_hpp
00336 
00337 template<>  inline string TypeName<Vect3Df>(){return "Vect3Df";}
00338 #endif // _CppTools_hpp
00339 
00340 
00341 #endif // _Vect3D_hpp
00342 

Generated on Fri Jun 17 13:36:09 2005 for ImLib3D by  doxygen 1.4.2