[301] | 1 | // ----------------------------------------------------------------------- |
---|
| 2 | // Object2D.cc: Member functions for the Object2D class. |
---|
| 3 | // ----------------------------------------------------------------------- |
---|
| 4 | // Copyright (C) 2006, Matthew Whiting, ATNF |
---|
| 5 | // |
---|
| 6 | // This program is free software; you can redistribute it and/or modify it |
---|
| 7 | // under the terms of the GNU General Public License as published by the |
---|
| 8 | // Free Software Foundation; either version 2 of the License, or (at your |
---|
| 9 | // option) any later version. |
---|
| 10 | // |
---|
| 11 | // Duchamp is distributed in the hope that it will be useful, but WITHOUT |
---|
| 12 | // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
| 13 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
---|
| 14 | // for more details. |
---|
| 15 | // |
---|
| 16 | // You should have received a copy of the GNU General Public License |
---|
| 17 | // along with Duchamp; if not, write to the Free Software Foundation, |
---|
| 18 | // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA |
---|
| 19 | // |
---|
| 20 | // Correspondence concerning Duchamp may be directed to: |
---|
| 21 | // Internet email: Matthew.Whiting [at] atnf.csiro.au |
---|
| 22 | // Postal address: Dr. Matthew Whiting |
---|
| 23 | // Australia Telescope National Facility, CSIRO |
---|
| 24 | // PO Box 76 |
---|
| 25 | // Epping NSW 1710 |
---|
| 26 | // AUSTRALIA |
---|
| 27 | // ----------------------------------------------------------------------- |
---|
[619] | 28 | #include <duchamp/PixelMap/Object2D.hh> |
---|
[393] | 29 | #include <duchamp/PixelMap/Scan.hh> |
---|
| 30 | #include <duchamp/PixelMap/Voxel.hh> |
---|
[238] | 31 | #include <iostream> |
---|
| 32 | #include <vector> |
---|
[773] | 33 | #include <list> |
---|
[469] | 34 | #include <algorithm> |
---|
| 35 | #include <math.h> |
---|
[238] | 36 | |
---|
[252] | 37 | namespace PixelInfo |
---|
| 38 | { |
---|
[243] | 39 | |
---|
[365] | 40 | Object2D::Object2D() |
---|
| 41 | { |
---|
| 42 | this->numPix = 0; |
---|
| 43 | } |
---|
| 44 | |
---|
[252] | 45 | Object2D::Object2D(const Object2D& o) |
---|
| 46 | { |
---|
[365] | 47 | operator=(o); |
---|
[252] | 48 | } |
---|
[243] | 49 | |
---|
[252] | 50 | Object2D& Object2D::operator= (const Object2D& o) |
---|
| 51 | { |
---|
[270] | 52 | if(this == &o) return *this; |
---|
[252] | 53 | this->scanlist = o.scanlist; |
---|
| 54 | this->numPix = o.numPix; |
---|
| 55 | this->xSum = o.xSum; |
---|
| 56 | this->ySum = o.ySum; |
---|
| 57 | this->xmin = o.xmin; |
---|
| 58 | this->ymin = o.ymin; |
---|
| 59 | this->xmax = o.xmax; |
---|
| 60 | this->ymax = o.ymax; |
---|
[270] | 61 | return *this; |
---|
[252] | 62 | } |
---|
| 63 | //------------------------------------------------------ |
---|
[238] | 64 | |
---|
[577] | 65 | Object2D operator+ (Object2D lhs, Object2D rhs) |
---|
| 66 | { |
---|
| 67 | Object2D output = lhs; |
---|
[773] | 68 | for(std::vector<Scan>::iterator s=rhs.scanlist.begin();s!=rhs.scanlist.end();s++) |
---|
| 69 | output.addScan(*s); |
---|
[577] | 70 | return output; |
---|
| 71 | } |
---|
| 72 | |
---|
| 73 | //------------------------------------------------------ |
---|
[1008] | 74 | void Object2D::addPixel(long x, long y) |
---|
[252] | 75 | { |
---|
[528] | 76 | /// This function has three parts to it: |
---|
| 77 | /// <ul><li> First, it searches through the existing scans to see if |
---|
| 78 | /// a) there is a scan of the same y-value present, and |
---|
| 79 | /// b) whether the (x,y) pixel lies in or next to an existing |
---|
| 80 | /// Scan. If so, it is added and the Scan is grown if need be. |
---|
| 81 | /// If this isn't the case, a new Scan of length 1 is added to |
---|
| 82 | /// the list. |
---|
| 83 | /// <li> If the Scan list was altered, all are checked to see whether |
---|
| 84 | /// there is now a case of Scans touching. If so, they are |
---|
| 85 | /// combined and added to the end of the list. |
---|
| 86 | /// <li> If the pixel was added, the parameters are updated and the |
---|
| 87 | /// pixel counter incremented. |
---|
| 88 | /// </ul> |
---|
[238] | 89 | |
---|
| 90 | |
---|
[252] | 91 | bool flagDone=false,flagChanged=false, isNew=false; |
---|
| 92 | |
---|
[773] | 93 | for (std::vector<Scan>::iterator scan=this->scanlist.begin(); !flagDone && scan!=this->scanlist.end(); scan++){ |
---|
| 94 | if(y == scan->itsY){ // if the y value is already in the list |
---|
| 95 | if(scan->isInScan(x,y)) flagDone = true; // pixel already here. |
---|
[252] | 96 | else{ // it's a new pixel! |
---|
[776] | 97 | if((x==(scan->itsX-1)) || (x == (scan->itsX+scan->itsXLen)) ){ |
---|
[252] | 98 | // if it is adjacent to the existing range, add to that range |
---|
[773] | 99 | if(x==(scan->itsX-1)) scan->growLeft(); |
---|
| 100 | else scan->growRight(); |
---|
[252] | 101 | flagDone = true; |
---|
| 102 | flagChanged = true; |
---|
| 103 | isNew = true; |
---|
[238] | 104 | } |
---|
[252] | 105 | } |
---|
[239] | 106 | } |
---|
[238] | 107 | } |
---|
| 108 | |
---|
[744] | 109 | if(!flagDone){ |
---|
| 110 | // we got to the end of the scanlist, so there is no pre-existing scan with this y value |
---|
| 111 | // add a new scan consisting of just this pixel |
---|
[252] | 112 | Scan newOne(y,x,1); |
---|
| 113 | this->scanlist.push_back(newOne); |
---|
| 114 | isNew = true; |
---|
| 115 | } |
---|
[744] | 116 | else if(flagChanged){ |
---|
[252] | 117 | // this is true only if one of the pre-existing scans has changed |
---|
| 118 | // |
---|
| 119 | // need to clean up, to see if there is a case of two scans when |
---|
[744] | 120 | // there should be one. Only need to look at scans with matching |
---|
| 121 | // y-value |
---|
[252] | 122 | // |
---|
| 123 | // because there has been only one pixel added, only 2 AT MOST |
---|
| 124 | // scans will need to be combined, so once we meet a pair that |
---|
| 125 | // overlap, we can finish. |
---|
[238] | 126 | |
---|
[252] | 127 | bool combined = false; |
---|
[773] | 128 | std::vector<Scan>::iterator scan1=this->scanlist.begin(),scan2; |
---|
| 129 | for (; !combined && scan1!=this->scanlist.end(); scan1++){ |
---|
| 130 | if(scan1->itsY==y){ |
---|
| 131 | scan2=scan1; |
---|
| 132 | scan2++; |
---|
| 133 | for(; !combined && scan2!=this->scanlist.end(); scan2++){ |
---|
| 134 | if(scan2->itsY==y){ |
---|
[776] | 135 | combined = scan1->addScan(*scan2); |
---|
[744] | 136 | if(combined){ |
---|
[773] | 137 | this->scanlist.erase(scan2); |
---|
[744] | 138 | } |
---|
| 139 | } |
---|
| 140 | } |
---|
[252] | 141 | } |
---|
| 142 | } |
---|
| 143 | |
---|
[246] | 144 | } |
---|
[252] | 145 | |
---|
| 146 | if(isNew){ |
---|
| 147 | // update the centres, mins, maxs and increment the pixel counter |
---|
| 148 | if(this->numPix==0){ |
---|
| 149 | this->xSum = this->xmin = this->xmax = x; |
---|
| 150 | this->ySum = this->ymin = this->ymax = y; |
---|
| 151 | } |
---|
| 152 | else{ |
---|
| 153 | this->xSum += x; |
---|
| 154 | this->ySum += y; |
---|
| 155 | if(x<this->xmin) this->xmin = x; |
---|
| 156 | if(x>this->xmax) this->xmax = x; |
---|
| 157 | if(y<this->ymin) this->ymin = y; |
---|
| 158 | if(y>this->ymax) this->ymax = y; |
---|
| 159 | } |
---|
| 160 | this->numPix++; |
---|
[246] | 161 | } |
---|
[252] | 162 | |
---|
[246] | 163 | } |
---|
[252] | 164 | //------------------------------------------------------ |
---|
[246] | 165 | |
---|
[773] | 166 | void Object2D::addScan(Scan &scan) |
---|
[252] | 167 | { |
---|
[770] | 168 | long y=scan.getY(); |
---|
| 169 | for(long x=scan.getX();x<=scan.getXmax();x++) this->addPixel(x,y); |
---|
[238] | 170 | |
---|
[577] | 171 | } |
---|
[252] | 172 | //------------------------------------------------------ |
---|
[238] | 173 | |
---|
[252] | 174 | bool Object2D::isInObject(long x, long y) |
---|
| 175 | { |
---|
[371] | 176 | |
---|
[667] | 177 | std::vector<Scan>::iterator scn; |
---|
| 178 | bool returnval=false; |
---|
[773] | 179 | for(scn=this->scanlist.begin();scn!=this->scanlist.end()&&!returnval;scn++){ |
---|
[238] | 180 | |
---|
[667] | 181 | returnval = ((y == scn->itsY) && (x>= scn->itsX) && (x<=scn->getXmax())); |
---|
[238] | 182 | |
---|
[667] | 183 | } |
---|
| 184 | |
---|
| 185 | return returnval; |
---|
[238] | 186 | |
---|
[252] | 187 | } |
---|
| 188 | //------------------------------------------------------ |
---|
[238] | 189 | |
---|
[252] | 190 | std::ostream& operator<< ( std::ostream& theStream, Object2D& obj) |
---|
| 191 | { |
---|
[773] | 192 | if(obj.scanlist.size()>1) obj.order(); |
---|
| 193 | for(std::vector<Scan>::iterator s=obj.scanlist.begin();s!=obj.scanlist.end();s++) |
---|
| 194 | theStream << *s << "\n"; |
---|
[252] | 195 | theStream<<"---\n"; |
---|
[270] | 196 | return theStream; |
---|
[238] | 197 | |
---|
[252] | 198 | } |
---|
| 199 | //------------------------------------------------------ |
---|
[238] | 200 | |
---|
[252] | 201 | void Object2D::calcParams() |
---|
| 202 | { |
---|
| 203 | this->xSum = 0; |
---|
| 204 | this->ySum = 0; |
---|
[623] | 205 | std::vector<Scan>::iterator s; |
---|
[773] | 206 | for(s=this->scanlist.begin();s!=this->scanlist.end();s++){ |
---|
[238] | 207 | |
---|
[623] | 208 | if(s==this->scanlist.begin()){ |
---|
| 209 | this->ymin = this->ymax = s->itsY; |
---|
| 210 | this->xmin = s->itsX; |
---|
| 211 | this->xmax = s->getXmax(); |
---|
[252] | 212 | } |
---|
| 213 | else{ |
---|
[623] | 214 | if(this->ymin>s->itsY) this->ymin = s->itsY; |
---|
| 215 | if(this->xmin>s->itsX) this->xmin = s->itsX; |
---|
| 216 | if(this->ymax<s->itsY) this->ymax = s->itsY; |
---|
| 217 | if(this->xmax<s->getXmax()) this->xmax = s->getXmax(); |
---|
[252] | 218 | } |
---|
[238] | 219 | |
---|
[623] | 220 | this->ySum += s->itsY*s->getXlen(); |
---|
| 221 | for(int x=s->itsX;x<=s->getXmax();x++) |
---|
[252] | 222 | this->xSum += x; |
---|
| 223 | |
---|
[238] | 224 | } |
---|
| 225 | |
---|
| 226 | } |
---|
[252] | 227 | //------------------------------------------------------ |
---|
[238] | 228 | |
---|
[252] | 229 | void Object2D::cleanup() |
---|
| 230 | { |
---|
[773] | 231 | std::vector<Scan>::iterator s1=this->scanlist.begin(),s2; |
---|
| 232 | for (; s1!=this->scanlist.end(); s1++){ |
---|
| 233 | s2=s1; s2++; |
---|
| 234 | for (; s2!=this->scanlist.end(); s2++){ |
---|
[238] | 235 | |
---|
[773] | 236 | if(overlap(*s1,*s2)){ |
---|
| 237 | s1->addScan(*s2); |
---|
| 238 | this->scanlist.erase(s2); |
---|
| 239 | } |
---|
| 240 | } |
---|
| 241 | } |
---|
| 242 | |
---|
[238] | 243 | } |
---|
[252] | 244 | //------------------------------------------------------ |
---|
[238] | 245 | |
---|
[252] | 246 | long Object2D::getNumDistinctY() |
---|
| 247 | { |
---|
| 248 | std::vector<long> ylist; |
---|
| 249 | if(this->scanlist.size()==0) return 0; |
---|
| 250 | if(this->scanlist.size()==1) return 1; |
---|
[623] | 251 | std::vector<Scan>::iterator scn; |
---|
[773] | 252 | for(scn=this->scanlist.begin();scn!=this->scanlist.end();scn++){ |
---|
[238] | 253 | bool inList = false; |
---|
[541] | 254 | unsigned int j=0; |
---|
[623] | 255 | long y = scn->itsY; |
---|
[252] | 256 | while(!inList && j<ylist.size()){ |
---|
| 257 | if(y==ylist[j]) inList=true; |
---|
[238] | 258 | j++; |
---|
| 259 | }; |
---|
[252] | 260 | if(!inList) ylist.push_back(y); |
---|
[238] | 261 | } |
---|
[252] | 262 | return ylist.size(); |
---|
[238] | 263 | } |
---|
[252] | 264 | //------------------------------------------------------ |
---|
[238] | 265 | |
---|
[252] | 266 | long Object2D::getNumDistinctX() |
---|
| 267 | { |
---|
| 268 | std::vector<long> xlist; |
---|
| 269 | if(this->scanlist.size()==0) return 0; |
---|
| 270 | if(this->scanlist.size()==1) return 1; |
---|
[623] | 271 | std::vector<Scan>::iterator scn; |
---|
[773] | 272 | for(scn=this->scanlist.begin();scn!=this->scanlist.end();scn++){ |
---|
[623] | 273 | for(int x=scn->itsX;x<scn->getXmax();x++){ |
---|
[252] | 274 | bool inList = false; |
---|
[541] | 275 | unsigned int j=0; |
---|
[252] | 276 | while(!inList && j<xlist.size()){ |
---|
| 277 | if(x==xlist[j]) inList=true; |
---|
| 278 | j++; |
---|
| 279 | }; |
---|
| 280 | if(!inList) xlist.push_back(x); |
---|
| 281 | } |
---|
| 282 | } |
---|
| 283 | return xlist.size(); |
---|
[238] | 284 | } |
---|
[252] | 285 | //------------------------------------------------------ |
---|
| 286 | |
---|
[773] | 287 | bool Object2D::scanOverlaps(Scan &scan) |
---|
[252] | 288 | { |
---|
| 289 | bool returnval = false; |
---|
[773] | 290 | for(std::vector<Scan>::iterator s=this->scanlist.begin();!returnval&&s!=this->scanlist.end();s++){ |
---|
| 291 | returnval = returnval || s->overlaps(scan); |
---|
[252] | 292 | } |
---|
| 293 | return returnval; |
---|
| 294 | } |
---|
| 295 | |
---|
[399] | 296 | //------------------------------------------------------ |
---|
| 297 | |
---|
| 298 | void Object2D::addOffsets(long xoff, long yoff) |
---|
| 299 | { |
---|
[623] | 300 | std::vector<Scan>::iterator scn; |
---|
[773] | 301 | for(scn=this->scanlist.begin();scn!=this->scanlist.end();scn++) |
---|
[623] | 302 | scn->addOffsets(xoff,yoff); |
---|
[399] | 303 | this->xSum += xoff*numPix; |
---|
| 304 | this->xmin += xoff; xmax += xoff; |
---|
| 305 | this->ySum += yoff*numPix; |
---|
| 306 | this->ymin += yoff; ymax += yoff; |
---|
| 307 | } |
---|
| 308 | |
---|
[469] | 309 | //------------------------------------------------------ |
---|
| 310 | |
---|
[1130] | 311 | bool Object2D::findEllipse(bool weightByFlux, float *array, size_t xdim, size_t ydim, int xzero, int yzero) |
---|
| 312 | { |
---|
| 313 | bool result=true; |
---|
| 314 | double sumxx=0.,sumyy=0.,sumxy=0.,sumflux=0.; |
---|
| 315 | std::vector<Scan>::iterator scn=this->scanlist.begin(); |
---|
| 316 | for(;scn!=this->scanlist.end();scn++){ |
---|
| 317 | int y = scn->itsY; |
---|
| 318 | float yoff=scn->itsY - this->getYaverage(); |
---|
| 319 | for(int x=scn->itsX;x<=scn->getXmax();x++){ |
---|
| 320 | float xoff=x-this->getXaverage(); |
---|
| 321 | float flux = weightByFlux ? array[(x-xzero)+xdim*(y-yzero)] : 1; |
---|
| 322 | sumxx += (xoff*xoff*flux); |
---|
| 323 | sumyy += (yoff*yoff*flux); |
---|
| 324 | sumxy += (xoff*yoff*flux); |
---|
| 325 | sumflux += flux; |
---|
| 326 | } |
---|
| 327 | } |
---|
| 328 | |
---|
| 329 | sumxx /= sumflux; |
---|
| 330 | sumxy /= sumflux; |
---|
| 331 | sumyy /= sumflux; |
---|
| 332 | |
---|
| 333 | this->posAngle = 0.5 * atan2( 2*sumxy , (sumxx-sumyy) ); |
---|
| 334 | result = ( (sumxx + sumyy + sqrt((sumxx-sumyy)*(sumxx-sumyy) + 4.*sumxy*sumxy)) > 0 ); |
---|
| 335 | if(result){ |
---|
| 336 | this->majorAxis = sqrt( 2. * (sumxx + sumyy + sqrt((sumxx-sumyy)*(sumxx-sumyy) + 4.*sumxy*sumxy)) ); |
---|
| 337 | this->minorAxis = sqrt( 2. * (sumxx + sumyy - sqrt((sumxx-sumyy)*(sumxx-sumyy) + 4.*sumxy*sumxy)) ); |
---|
| 338 | this->minorAxis = std::max(this->minorAxis,0.1); |
---|
| 339 | } |
---|
| 340 | else this->majorAxis = this->minorAxis = 0.; |
---|
| 341 | // std::cerr << sumxx << " " << sumxy << " " << sumyy << " " << posAngle << " " << majorAxis << " " << minorAxis << " " << ((sumxx-sumyy)*(sumxx-sumyy) + 4.*sumxy*sumxy) << "\n"; |
---|
| 342 | return result; |
---|
| 343 | } |
---|
| 344 | |
---|
| 345 | |
---|
| 346 | //------------------------------------------------------ |
---|
| 347 | |
---|
[469] | 348 | double Object2D::getPositionAngle() |
---|
| 349 | { |
---|
| 350 | |
---|
| 351 | int sumxx=0; |
---|
| 352 | int sumyy=0; |
---|
| 353 | int sumxy=0; |
---|
| 354 | std::vector<Scan>::iterator scn=this->scanlist.begin(); |
---|
[773] | 355 | for(;scn!=this->scanlist.end();scn++){ |
---|
[469] | 356 | sumyy += (scn->itsY*scn->itsY)*scn->itsXLen; |
---|
| 357 | for(int x=scn->itsX;x<=scn->getXmax();x++){ |
---|
| 358 | sumxx += x*x; |
---|
| 359 | sumxy += x*scn->itsY; |
---|
| 360 | } |
---|
| 361 | } |
---|
| 362 | |
---|
| 363 | // Calculate net moments |
---|
| 364 | double mxx = sumxx - this->xSum*this->xSum / double(this->numPix); |
---|
| 365 | double myy = sumyy - this->ySum*this->ySum / double(this->numPix); |
---|
| 366 | double mxy = sumxy - this->xSum*this->ySum / double(this->numPix); |
---|
| 367 | |
---|
[472] | 368 | if(mxy==0){ |
---|
| 369 | if(mxx>myy) return M_PI/2.; |
---|
| 370 | else return 0.; |
---|
| 371 | } |
---|
[469] | 372 | |
---|
| 373 | // Angle of the minimum moment |
---|
| 374 | double tantheta = (mxx - myy + sqrt( (mxx-myy)*(mxx-myy) + 4.*mxy*mxy))/(2.*mxy); |
---|
| 375 | |
---|
| 376 | return atan(tantheta); |
---|
| 377 | } |
---|
| 378 | |
---|
| 379 | //------------------------------------------------------ |
---|
| 380 | |
---|
| 381 | std::pair<double,double> Object2D::getPrincipleAxes() |
---|
| 382 | { |
---|
| 383 | |
---|
[470] | 384 | double theta = this->getPositionAngle(); |
---|
[570] | 385 | double x0 = this->getXaverage(); |
---|
| 386 | double y0 = this->getYaverage(); |
---|
[469] | 387 | std::vector<double> majorAxes, minorAxes; |
---|
| 388 | std::vector<Scan>::iterator scn=this->scanlist.begin(); |
---|
[773] | 389 | for(;scn!=this->scanlist.end();scn++){ |
---|
[469] | 390 | for(int x=scn->itsX;x<=scn->getXmax();x++){ |
---|
[472] | 391 | majorAxes.push_back((x-x0+0.5)*cos(theta) + (scn->itsY-y0+0.5)*sin(theta)); |
---|
| 392 | minorAxes.push_back((x-x0+0.5)*sin(theta) + (scn->itsY-y0+0.5)*cos(theta)); |
---|
[469] | 393 | } |
---|
| 394 | } |
---|
| 395 | |
---|
| 396 | std::sort(majorAxes.begin(),majorAxes.end()); |
---|
| 397 | std::sort(minorAxes.begin(),minorAxes.end()); |
---|
| 398 | int size = majorAxes.size(); |
---|
| 399 | std::pair<double,double> axes; |
---|
| 400 | axes.first = fabs(majorAxes[0]-majorAxes[size-1]); |
---|
| 401 | axes.second = fabs(minorAxes[0]-minorAxes[size-1]); |
---|
[472] | 402 | if(axes.first<0.5) axes.first=0.5; |
---|
| 403 | if(axes.second<0.5) axes.second=0.5; |
---|
[469] | 404 | return axes; |
---|
| 405 | |
---|
| 406 | } |
---|
| 407 | |
---|
[770] | 408 | |
---|
| 409 | //------------------------------------------------------ |
---|
| 410 | |
---|
| 411 | |
---|
| 412 | bool Object2D::canMerge(Object2D &other, float threshS, bool flagAdj) |
---|
| 413 | { |
---|
| 414 | long gap; |
---|
| 415 | if(flagAdj) gap = 1; |
---|
| 416 | else gap = long( ceil(threshS) ); |
---|
| 417 | bool near = this->isNear(other,gap); |
---|
| 418 | if(near) return this->isClose(other,threshS,flagAdj); |
---|
| 419 | else return near; |
---|
| 420 | } |
---|
| 421 | |
---|
| 422 | //------------------------------------------------------ |
---|
| 423 | |
---|
| 424 | bool Object2D::isNear(Object2D &other, long gap) |
---|
| 425 | { |
---|
| 426 | bool areNear; |
---|
| 427 | // Test X ranges |
---|
| 428 | if((this->xmin-gap)<other.xmin) areNear=((this->xmax+gap)>=other.xmin); |
---|
| 429 | else areNear=(other.xmax>=(this->xmin-gap)); |
---|
| 430 | // Test Y ranges |
---|
| 431 | if(areNear){ |
---|
| 432 | if((this->ymin-gap)<other.ymin) areNear=areNear&&((this->ymax+gap)>=other.ymin); |
---|
| 433 | else areNear=areNear&&(other.ymax>=(this->ymin-gap)); |
---|
| 434 | } |
---|
| 435 | return areNear; |
---|
| 436 | } |
---|
| 437 | |
---|
| 438 | //------------------------------------------------------ |
---|
| 439 | |
---|
| 440 | bool Object2D::isClose(Object2D &other, float threshS, bool flagAdj) |
---|
| 441 | { |
---|
| 442 | |
---|
| 443 | long gap = long(ceil(threshS)); |
---|
| 444 | if(flagAdj) gap=1; |
---|
| 445 | |
---|
| 446 | bool close = false; |
---|
| 447 | |
---|
| 448 | long ycommonMin=std::max(this->ymin-gap,other.ymin)-gap; |
---|
| 449 | long ycommonMax=std::min(this->ymax+gap,other.ymax)+gap; |
---|
| 450 | |
---|
| 451 | std::vector<Scan>::iterator iter1,iter2; |
---|
[773] | 452 | for(iter1=this->scanlist.begin();!close && iter1!=this->scanlist.end();iter1++){ |
---|
[770] | 453 | if(iter1->itsY >= ycommonMin && iter1->itsY<=ycommonMax){ |
---|
[773] | 454 | for(iter2=other.scanlist.begin();!close && iter2!=other.scanlist.end();iter2++){ |
---|
[770] | 455 | if(iter2->itsY >= ycommonMin && iter2->itsY<=ycommonMax){ |
---|
| 456 | |
---|
| 457 | if(abs(iter1->itsY-iter2->itsY)<=gap){ |
---|
| 458 | if(flagAdj) { |
---|
[771] | 459 | if((iter1->itsX-gap)>iter2->itsX) close=((iter2->itsX+iter2->itsXLen-1)>=(iter1->itsX-gap)); |
---|
| 460 | else close = ( (iter1->itsX+iter1->itsXLen+gap-1)>=iter2->itsX); |
---|
[770] | 461 | } |
---|
[874] | 462 | else close = (minSep(*iter1,*iter2) <= threshS); |
---|
[770] | 463 | } |
---|
| 464 | |
---|
| 465 | } |
---|
| 466 | } |
---|
| 467 | } |
---|
| 468 | } |
---|
| 469 | |
---|
| 470 | return close; |
---|
| 471 | |
---|
| 472 | } |
---|
| 473 | |
---|
| 474 | |
---|
| 475 | |
---|
[238] | 476 | } |
---|