00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
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
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
00120
00121
00122
00123
00124
00125
00126
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
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
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