00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00020 #ifndef _RectZone3D_hpp
00021 #define _RectZone3D_hpp
00022
00023 #include<math.h>
00024 #include<ImLib3D/Vect3D.hpp>
00025 #include<ImLib3D/Size3D.hpp>
00026 #include<ImLib3D/CppTools.hpp>
00027
00028 template<class PType> class PropertyWrapPtr;
00029
00031 template<class RectType,class Real=RectType>
00032 class RectZone3D
00033 {
00034 friend class PropertyWrapPtr<RectZone3D<RectType,Real> >;
00035 protected:
00036 public:
00037 typedef Vect3D<RectType,Real> Vect3DType;
00038
00039 RectType x0,y0,z0;
00040 RectType x1,y1,z1;
00041
00042 RectType Width() const {return x1-x0;}
00043 RectType Height() const {return y1-y0;}
00044 RectType Depth() const {return z1-z0;}
00045 Vect3DType SizeV(){return Vect3DType(Width(),Height(),Depth());}
00046 RectType Volume() {return Width()*Height()*Depth();}
00047 Vect3DType GetP0() const {return Vect3DType(x0,y0,z0);}
00048 Vect3DType GetP1() const {return Vect3DType(x1,y1,z1);}
00050 Vect3DType GetCorner(int number) const
00051 {
00052 Vect3DType res=GetP0();
00053 for(uint dir=0;dir<3;dir++)
00054 {
00055 if(number&(1<<dir)){res(dir)=GetP1()(dir);}
00056 }
00057 return res;
00058 }
00059 void SetP0(const Vect3DType &p0) {x0=p0.x;y0=p0.y;z0=p0.z;}
00060 void SetP1(const Vect3DType &p1) {x1=p1.x;y1=p1.y;z1=p1.z;}
00061
00062 Vect3Df SelfCoords(const Vect3DType &P) const
00063 {
00064 return Vect3Df((P.x-x0)/(float)(x1-x0),
00065 (P.y-y0)/(float)(y1-y0),
00066 (P.z-z0)/(float)(z1-z0) );
00067 }
00068
00069 RectZone3D<RectType,Real> Intersection(const RectZone3D<RectType,Real> &other) const
00070 {
00071 RectZone3D<RectType,Real> res(other);
00072 res.x0=max(x0,other.x0);
00073 res.y0=max(y0,other.y0);
00074 res.z0=max(z0,other.z0);
00075
00076 res.x1=min(x1,other.x1);
00077 res.y1=min(y1,other.y1);
00078 res.z1=min(z1,other.z1);
00079
00080 return res;
00081 }
00082 bool IsOk() const {return x0<=x1 && y0<=y1 && z0<=z1;}
00083 void Translate(const Vect3DType& vec){Translate(vec.x, vec.y, vec.z);}
00084 void Translate(const RectType x,const RectType y,const RectType z)
00085 {
00086 x0+=x;
00087 y0+=y;
00088 z0+=z;
00089 x1+=x;
00090 y1+=y;
00091 z1+=z;
00092 }
00093 inline void ToStart(RectType &x,RectType &y,RectType &z) const {x=x0;y=y0;z=z0;}
00094 bool IsInside(const Vect3DType & vect) const {return IsInside(vect.x, vect.y, vect.z);}
00095 bool IsInside(RectType x,RectType y,RectType z) const
00096 {
00097 if( x<x0 ) {return false;}
00098 if( y<y0 ) {return false;}
00099 if( z<z0 ) {return false;}
00100 if( x>x1 ) {return false;}
00101 if( y>y1 ) {return false;}
00102 if( z>z1 ) {return false;}
00103 return true;
00104 }
00105
00106 bool IsOnSurface(const Vect3DType & vect) const {return IsOnSurface(vect.x, vect.y, vect.z);}
00107 bool IsOnSurface(RectType x,RectType y,RectType z) const
00108 {
00109 return (x==x0 || y==y0 || z==z0 || x==x1 || y==y1 || z==z1) && IsInside(x,y,z);
00110 }
00111 Vect3DType ClosestPoint(const Vect3DType &p)
00112 {
00113 if(IsInside(p)){return p;}
00114 Vect3DType res=p;
00115 if(res.x<x0){res.x=x0;}
00116 if(res.y<y0){res.y=y0;}
00117 if(res.z<z0){res.z=z0;}
00118 if(res.x>x1){res.x=x1;}
00119 if(res.y>y1){res.y=y1;}
00120 if(res.z>z1){res.z=z1;}
00121 return res;
00122 }
00123 Vect3DType FurthestPoint(const Vect3DType &p)
00124 {
00125 return Vect3DType(AbsoluteValue(p.x-x0)>AbsoluteValue(p.x-x1) ? x0 : x1,
00126 AbsoluteValue(p.y-y0)>AbsoluteValue(p.y-y1) ? y0 : y1,
00127 AbsoluteValue(p.z-z0)>AbsoluteValue(p.z-z1) ? z0 : z1 );
00128 }
00129
00130 bool operator!=(const RectZone3D<RectType> &other) const
00131 {
00132 return !((*this)==other);
00133 }
00134 bool operator==(const RectZone3D<RectType> &other) const
00135 {
00136 return
00137 x0==other.x0 &&
00138 y0==other.y0 &&
00139 z0==other.z0 &&
00140 x1==other.x1 &&
00141 y1==other.y1 &&
00142 z1==other.z1 ;
00143 }
00144 RectZone3D( const Vect3DType &p0,const Vect3DType &p1):
00145 x0(p0.x),y0(p0.y),z0(p0.z),
00146 x1(p1.x),y1(p1.y),z1(p1.z)
00147 {
00148 }
00149
00150 RectZone3D( RectType _x0, RectType _y0, RectType _z0,
00151 RectType _x1, RectType _y1, RectType _z1 ) :
00152 x0(_x0),y0(_y0),z0(_z0),
00153 x1(_x1),y1(_y1),z1(_z1)
00154 {
00155 }
00156
00157 RectZone3D() :
00158 x0(0),y0(0),z0(0),
00159 x1(-1),y1(-1),z1(-1)
00160 {;}
00161 };
00162
00163 typedef RectZone3D<float> RectZone3Df;
00164
00165 class RectZone3Di : public RectZone3D<int,float>
00166 {
00167 public:
00168 int Width() const {return x1-x0+1;}
00169 int Height() const {return y1-y0+1;}
00170 int Depth() const {return z1-z0+1;}
00171 int Volume() {return Width()*Height()*Depth();}
00172 Size3D Size() const {return SizeV();}
00173 Vect3Di SizeV() const {return Vect3Di(Width(),Height(),Depth());}
00174 inline int ToNext(int &x,int &y,int &z) const
00175 {
00176 x++;
00177 if(x>x1)
00178 {
00179 x=x0;
00180 y++;
00181 if(y>y1)
00182 {
00183 y=y0;
00184 z++;
00185 if(z>z1){return 3;}
00186 return 2;
00187 }
00188 return 1;
00189 }
00190 else { return 0;}
00191 }
00192 inline int ToPrev(int &x,int &y,int &z) const
00193 {
00194 x--;
00195 if(x<x0)
00196 {
00197 x=x1;
00198 y--;
00199 if(y<y0)
00200 {
00201 y=y1;
00202 z--;
00203 if(z<z0){return 3;}
00204 return 2;
00205 }
00206 return 1;
00207 }
00208 else { return 0;}
00209 }
00210
00211 inline int ToNextOnSurface(int &x,int &y,int &z) const
00212 {
00213 if(z==z0){return ToNext(x,y,z);}
00214 else
00215 if(z==z1){return ToNext(x,y,z);}
00216 else
00217 if(y==y0){return ToNext(x,y,z);}
00218 else
00219 if(y==y1){return ToNext(x,y,z);}
00220 else
00221 if(x==x1){y++;x=x0;return 1;}
00222 else
00223 if(x==x0){x=x1;return 1;}
00224 else
00225 {ThrowError("RectZone3Di::ToNextOnSurface: initial point not on surface?");}
00226 return 1;
00227 }
00228 inline int ToPrevOnSurface(int &x,int &y,int &z) const
00229 {
00230 x--;
00231 if(x<x0)
00232 {
00233 x=x1;
00234 y--;
00235 if(y<y0)
00236 {
00237 y=y1;
00238 z--;
00239 if(z<z0){return 3;}
00240 return 2;
00241 }
00242 return 1;
00243 }
00244 else { return 0;}
00245 }
00246
00247 RectZone3Di Intersection(const RectZone3Di &other) const
00248 {
00249 RectZone3Di res(other);
00250 res.x0=max(x0,other.x0);
00251 res.y0=max(y0,other.y0);
00252 res.z0=max(z0,other.z0);
00253
00254 res.x1=min(x1,other.x1);
00255 res.y1=min(y1,other.y1);
00256 res.z1=min(z1,other.z1);
00257
00258 return res;
00259 }
00260
00261
00262 RectZone3Di ( const RectZone3Df & , int );
00263 RectZone3Di ( const Vect3Di &p0,const Size3D &size):
00264 RectZone3D<int,float>(p0,p0+size.GetV()-Vect3Di(1,1,1))
00265 {
00266 }
00267 RectZone3Di (const Vect3Di &p0,const Vect3Di &p1):
00268 RectZone3D<int,float>(p0,p1)
00269 {
00270 ;
00271 }
00272 RectZone3Di( int _x0, int _y0, int _z0,
00273 int _x1, int _y1, int _z1 ) :
00274 RectZone3D<int,float>(_x0,_y0,_z0,_x1,_y1,_z1)
00275 {
00276 ;
00277 }
00278 RectZone3Di( ) : RectZone3D<int,float>()
00279 {
00280 ;
00281 }
00282
00283 };
00284
00285
00286 inline RectZone3Di::RectZone3Di( const RectZone3Df &s0, int type)
00287 {
00288 if(type==0)
00289 {
00290 x0= (int)ceil (s0.x0);
00291 y0= (int)ceil (s0.y0);
00292 z0= (int)ceil (s0.z0);
00293 x1= (int)floor(s0.x1);
00294 y1= (int)floor(s0.y1);
00295 z1= (int)floor(s0.z1);
00296 }
00297 else
00298 {
00299 x0= (int)floor(s0.x0);
00300 y0= (int)floor(s0.y0);
00301 z0= (int)floor(s0.z0);
00302 x1= (int)ceil (s0.x1);
00303 y1= (int)ceil (s0.y1);
00304 z1= (int)ceil (s0.z1);
00305 }
00306 }
00307
00308 template<class RectType,class Real>
00309 inline ostream& operator<< (ostream& s, const RectZone3D<RectType, Real>& rect)
00310 {
00311 s << rect.GetP0() << " " << rect.GetP1() << " ";
00312 return s;
00313 }
00314
00315 template<class RectType,class Real>
00316 inline istream& operator>> (istream& s, RectZone3D<RectType, Real>& rect)
00317 {
00318 Vect3D<RectType,Real> p0,p1;
00319 s >> p0 >> p1;
00320 rect.SetP0(p0);
00321 rect.SetP1(p1);
00322 return s;
00323 }
00324
00326 template<> inline string TypeName<RectZone3Df>(){return "RectZone3Df";}
00327 template<> inline string TypeName<RectZone3Di>(){return "RectZone3Di";}
00328
00329
00330
00331 #endif // _RectZone3D_hpp