Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef __VCGLIB_SPATIAL_ITERATORS_2D
00025 #define __VCGLIB_SPATIAL_ITERATORS_2D
00026
00027 #include <vector>
00028 #include <vcg/space/intersection2.h>
00029 #include <vcg/space/point2.h>
00030 #include <vcg/space/box2.h>
00031 #include <vcg/space/ray2.h>
00032 #include <vcg/math/base.h>
00033 #include <algorithm>
00034 #include <float.h>
00035 #include <limits>
00036
00037
00038
00039 namespace vcg{
00040 template <class Spatial_Idexing,class INTFUNCTOR,class TMARKER>
00041 class RayIterator2D
00042 {
00043 public:
00044 typedef typename Spatial_Idexing::ScalarType ScalarType;
00045 typedef typename vcg::Ray2<ScalarType> RayType;
00046 typedef typename Spatial_Idexing::Box2x IndexingBoxType;
00047 protected:
00048 typedef typename Spatial_Idexing::ObjType ObjType;
00049 typedef typename vcg::Point2<ScalarType> CoordType;
00050 typedef typename Spatial_Idexing::CellIterator CellIterator;
00051 ScalarType max_dist;
00052
00053
00054 bool _controlEnd()
00055 {
00056 return (currBox.Collide(Si.bbox));
00057 }
00058
00059
00060 void _NextCell()
00061 {
00062 currBox.min+=step;
00063 currBox.max+=step;
00064 dist+=step.Norm();
00065 end=!_controlEnd();
00066 }
00067
00068
00069
00070 bool Refresh()
00071 {
00072 std::vector<ObjType*> objectPtrs;
00073 GridGetInBox2D(Si,tm,currBox,objectPtrs,false);
00074
00075 for(size_t i=0;i<objectPtrs.size();i++)
00076 {
00077 ObjType* elem=objectPtrs[i];
00078 if (elem->IsD())continue;
00079 if (tm.IsMarked(elem))continue;
00080
00081
00082 ScalarType t;
00083 CoordType Int;
00084 if((int_funct((*elem),r,t))&&
00085 (t<=max_dist))
00086 {
00087 Int=r.Origin()+r.Direction()*t;
00088 Elems.push_back(Entry_Type(elem,t,Int));
00089 }
00090 }
00091 if (Elems.size()==0) return false;
00092
00093 std::sort(Elems.begin(),Elems.end());
00094 CurrentElem=Elems.rbegin();
00095
00096 return(Dist()<dist);
00097 }
00098
00099 public:
00100
00101
00102
00103 RayIterator2D(Spatial_Idexing &_Si,
00104 INTFUNCTOR &_int_funct,
00105 const ScalarType &_max_dist,
00106 TMARKER &_tm)
00107 :Si(_Si),int_funct(_int_funct),tm(_tm)
00108 {
00109 max_dist=_max_dist;
00110 };
00111
00112
00113
00114 void Init(const RayType _r)
00115 {
00116 r=_r;
00117 r.Normalize();
00118
00119
00120 end=false;
00121 tm.UnMarkAll();
00122 Elems.clear();
00123
00124 CoordType start;
00125
00126
00127 if (Si.bbox.IsIn(r.Origin()))
00128 start=r.Origin();
00129 else
00130 if (!(vcg::RayBoxIntersection<ScalarType>(r,Si.bbox,start)))
00131 {
00132 end=true;
00133 return;
00134 }
00135
00136
00137 stepsize=Si.voxel.Norm()*2;
00138 step=r.Direction()*stepsize;
00139
00140
00141 currBox.SetNull();
00142 currBox.Add(start);
00143 currBox.Add(start+step);
00144 ScalarType diag=currBox.Diag();
00145 currBox.Offset(diag*0.01);
00146 dist=currBox.Diag();
00147 end=!_controlEnd();
00148
00149 while ((!End()) && (!Refresh()))
00150 _NextCell();
00151
00152 fflush(stdout);
00153 }
00154
00155 bool End()
00156 {return end;}
00157
00158
00159 ObjType &operator *(){return *((*CurrentElem).elem);}
00160
00161 CoordType IntPoint()
00162 {return ((*CurrentElem).intersection);}
00163
00164 ScalarType Dist()
00165 {
00166 if (Elems.size()>0)
00167 return ((*CurrentElem).dist);
00168 else
00169 return ((ScalarType)FLT_MAX);
00170 }
00171
00172 void operator ++()
00173 {
00174 if (!Elems.empty()) Elems.pop_back();
00175
00176 CurrentElem = Elems.rbegin();
00177
00178 if (Dist()>dist)
00179 {
00180 if (!End())
00181 {
00182 _NextCell();
00183 while ((!End()) && (!Refresh()))
00184 _NextCell();
00185 }
00186 }
00187 }
00188
00189 protected:
00190
00192 struct Entry_Type
00193 {
00194 public:
00195
00196 Entry_Type(ObjType* _elem,ScalarType _dist,CoordType _intersection)
00197 {
00198 elem=_elem;
00199 dist=_dist;
00200 intersection=_intersection;
00201 }
00202
00203 Entry_Type(const Entry_Type &e)
00204 {
00205 elem=e.elem;
00206 dist=e.dist;
00207 intersection=e.intersection;
00208 }
00209
00210 inline bool operator < ( const Entry_Type & l ) const{return (dist > l.dist); }
00211 ObjType* elem;
00212 ScalarType dist;
00213 CoordType intersection;
00214 };
00215
00216 RayType r;
00217 Spatial_Idexing &Si;
00218 bool end;
00219 INTFUNCTOR &int_funct;
00220 TMARKER &tm;
00221
00222 std::vector<Entry_Type> Elems;
00223 typedef typename std::vector<Entry_Type>::reverse_iterator ElemIterator;
00224 ElemIterator CurrentElem;
00225
00226 vcg::Box2<ScalarType> currBox;
00227 CoordType step;
00228 ScalarType stepsize;
00229 ScalarType dist;
00230
00231 };
00232
00233 }
00234
00235 #endif