00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <PrCellStructure.h>
00034 #include <queue>
00035 using std::cout;
00036 using std::endl;
00037
00038
00039 class HeapNode {
00040
00041 public:
00042 int idx_;
00043 double key_;
00044
00045 HeapNode( int idx, double key) { idx_ = idx; key_ = key;}
00046 ~HeapNode(){}
00047
00048 bool operator > ( const HeapNode& x) const { return (this->key_
00049 > x.key_);}
00050 bool operator >= ( const HeapNode& x) const { return (this->key_
00051 >= x.key_);}
00052 };
00053 typedef std::priority_queue< HeapNode, vector<HeapNode>, std::greater<HeapNode> > HeapType;
00054
00055
00056
00057
00058 void PrCellStructure::makeCellStructure()
00059
00060 {
00061
00062 double maxarr[3];
00063 min_[0] = xyz_[0].x();
00064 maxarr[0] = xyz_[0].x();
00065 min_[1] = xyz_[0].y();
00066 maxarr[1] = xyz_[0].y();
00067 min_[2] = xyz_[0].z();
00068 maxarr[2] = xyz_[0].z();
00069 int i;
00070 int xyz_size = xyz_.size();
00071 for(i=1; i< xyz_size; i++)
00072 {
00073 if(xyz_[i].x() < min_[0]) min_[0] = xyz_[i].x();
00074 else if(xyz_[i].x() > maxarr[0]) maxarr[0] = xyz_[i].x();
00075
00076 if(xyz_[i].y() < min_[1]) min_[1] = xyz_[i].y();
00077 else if(xyz_[i].y() > maxarr[1]) maxarr[1] = xyz_[i].y();
00078
00079 if(xyz_[i].z() < min_[2]) min_[2] = xyz_[i].z();
00080 else if(xyz_[i].z() > maxarr[2]) maxarr[2] = xyz_[i].z();
00081 }
00082
00083
00084
00085 cell_size_ = std::max( (maxarr[0] - min_[0]) / (double)max_no_cells_,
00086 (maxarr[1] - min_[1]) / (double)max_no_cells_ );
00087 cell_size_ = std::max( cell_size_,
00088 (maxarr[2] - min_[2]) / (double)max_no_cells_ );
00089
00090
00091
00092 ncells_[0] = (int)((maxarr[0] - min_[0]) / cell_size_) + 1;
00093 ncells_[1] = (int)((maxarr[1] - min_[1]) / cell_size_) + 1;
00094 ncells_[2] = (int)((maxarr[2] - min_[2]) / cell_size_) + 1;
00095
00096
00097
00098 ind_.resize(ncells_[0]*ncells_[1]*ncells_[2]);
00099
00100
00101 int ii,i1,j1,k1;
00102 for(i=0; i< xyz_size; i++)
00103 {
00104
00105 whichCell(xyz_[i],i1,j1,k1);
00106
00107 ii = getI(i1,j1,k1);
00108
00109 ind_[ii].push_back(i);
00110 }
00111
00112 size_t min_num = xyz_.size();
00113 int ind_size = ind_.size();
00114 size_t max_num = 0;
00115 for (i=0; i<ind_size; i++ )
00116 {
00117 if(ind_[i].size() > max_num) max_num = ind_[i].size();
00118 else if(ind_[i].size() < min_num) min_num = ind_[i].size();
00119 }
00120
00121
00122 }
00123
00124
00125
00126
00127 PrCellStructure::PrCellStructure(int n, double* xyz_points, int max_no_cells)
00128
00129 {
00130 xyz_.resize(n);
00131 int j;
00132 for(j=0; j< n; j++)
00133 {
00134 xyz_[j].x() = xyz_points[3*j];
00135 xyz_[j].y() = xyz_points[3*j+1];
00136 xyz_[j].z() = xyz_points[3*j+2];
00137 }
00138 max_no_cells_ = max_no_cells;
00139 makeCellStructure();
00140 }
00141
00142
00143 void PrCellStructure::attach(int n, const double* xyz_points)
00144
00145 {
00146 xyz_.resize(n);
00147 int j;
00148 for(j=0; j< n; j++)
00149 {
00150 xyz_[j].x() = xyz_points[3*j];
00151 xyz_[j].y() = xyz_points[3*j+1];
00152 xyz_[j].z() = xyz_points[3*j+2];
00153 }
00154 makeCellStructure();
00155 }
00156
00157
00158 void
00159 PrCellStructure::getBall(const Vector3D& p, double radius,
00160 vector<int>& neighbours, int notP) const
00161
00162
00163
00164 {
00165 neighbours.clear();
00166 double r2 = radius * radius, dist2;
00167
00168 int i1,j1,k1;
00169 whichCell(p,i1,j1,k1);
00170 int imin[3],imax[3];
00171 int diff = (int)(radius/cell_size_) + 1;
00172 imin[0] = std::max(i1-diff,0);
00173 imax[0] = std::min(i1+diff,ncells_[0]-1);
00174 imin[1] = std::max(j1-diff,0);
00175 imax[1] = std::min(j1+diff,ncells_[1]-1);
00176 imin[2] = std::max(k1-diff,0);
00177 imax[2] = std::min(k1+diff,ncells_[2]-1);
00178
00179 int iq,ii;
00180 for(int k=imin[2]; k<=imax[2]; k++)
00181 for(int j=imin[1]; j<=imax[1]; j++)
00182 for(int i=imin[0]; i<=imax[0]; i++)
00183 {
00184 ii = getI(i,j,k);
00185 for(size_t ell=0; ell<ind_[ii].size(); ell++)
00186 {
00187 iq = ind_[ii][ell];
00188 dist2 = xyz_[iq].dist2(p);
00189 if(dist2 <= r2)
00190 {
00191 if(notP == 0 || dist2 > 0) neighbours.push_back(iq);
00192 }
00193 }
00194 }
00195 }
00196
00197
00198
00199 void
00200 PrCellStructure::getKNearest(const Vector3D& p, int k,
00201 vector<int>& neighbours, int notP) const
00202
00203
00204
00205 {
00206 neighbours.clear();
00207 if(k > int(xyz_.size()) - 1) return;
00208
00209
00210
00211
00212
00213 double r = cell_size_;
00214
00215 vector<int> current_nghrs;
00216 getBall(p,r,current_nghrs,notP);
00217
00218 while(int(current_nghrs.size()) < k)
00219 {
00220 r *= 2.0;
00221 getBall(p,r,current_nghrs,notP);
00222 }
00223
00224
00225
00226
00227
00228
00229 int n = current_nghrs.size();
00230 double dist2;
00231
00232
00233 HeapType heap;
00234 int i;
00235 for(i = 0; i < n; i++)
00236 {
00237 dist2 = xyz_[current_nghrs[i]].dist2(p);
00238 heap.push(HeapNode(i,dist2));
00239 }
00240
00241 int index;
00242 for(i = 0; i < k; i++)
00243 {
00244 index = heap.top().idx_;
00245 heap.pop();
00246
00247
00248
00249 neighbours.push_back(current_nghrs[index]);
00250 }
00251 }
00252
00253
00254
00255 void
00256 PrCellStructure::getIJK(int ii, int& i, int& j, int& k) const
00257
00258 {
00259 k = ii / (ncells_[0] * ncells_[1]);
00260 int jj = ii - k * (ncells_[0] * ncells_[1]);
00261 j = jj / ncells_[0];
00262 i = jj - j * ncells_[0];
00263 }
00264
00265
00266 void
00267 PrCellStructure::whichCell(const Vector3D& xyz, int& i, int& j, int& k) const
00268
00269 {
00270 i = (int)((xyz.x() - min_[0]) / cell_size_);
00271 j = (int)((xyz.y() - min_[1]) / cell_size_);
00272 k = (int)((xyz.z() - min_[2]) / cell_size_);
00273 }
00274
00275
00276 void PrCellStructure::print(ostream& os)
00277
00278 {
00279 os << xyz_.size() << endl;
00280 size_t i;
00281 for(i=0; i<xyz_.size(); i++)
00282 {
00283 os << xyz_[i].x() << " " << xyz_[i].y() << " " << xyz_[i].z() << "\n";
00284 }
00285 }
00286
00287
00288 void PrCellStructure::scan(istream& is)
00289
00290 {
00291 int numpnts;
00292 is >> numpnts;
00293 xyz_.resize(numpnts);
00294 int i;
00295 for(i=0; i<numpnts; i++)
00296 {
00297 is >> xyz_[i].x() >> xyz_[i].y() >> xyz_[i].z();
00298 }
00299 makeCellStructure();
00300 }
00301