[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; |
---|
[1132] | 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; |
---|
| 61 | this->majorAxis = o.majorAxis; |
---|
| 62 | this->minorAxis = o.minorAxis; |
---|
| 63 | this->posAngle = o.posAngle; |
---|
[270] | 64 | return *this; |
---|
[252] | 65 | } |
---|
| 66 | //------------------------------------------------------ |
---|
[238] | 67 | |
---|
[577] | 68 | Object2D operator+ (Object2D lhs, Object2D rhs) |
---|
| 69 | { |
---|
| 70 | Object2D output = lhs; |
---|
[773] | 71 | for(std::vector<Scan>::iterator s=rhs.scanlist.begin();s!=rhs.scanlist.end();s++) |
---|
| 72 | output.addScan(*s); |
---|
[577] | 73 | return output; |
---|
| 74 | } |
---|
| 75 | |
---|
| 76 | //------------------------------------------------------ |
---|
[1008] | 77 | void Object2D::addPixel(long x, long y) |
---|
[252] | 78 | { |
---|
[528] | 79 | /// This function has three parts to it: |
---|
| 80 | /// <ul><li> First, it searches through the existing scans to see if |
---|
| 81 | /// a) there is a scan of the same y-value present, and |
---|
| 82 | /// b) whether the (x,y) pixel lies in or next to an existing |
---|
| 83 | /// Scan. If so, it is added and the Scan is grown if need be. |
---|
| 84 | /// If this isn't the case, a new Scan of length 1 is added to |
---|
| 85 | /// the list. |
---|
| 86 | /// <li> If the Scan list was altered, all are checked to see whether |
---|
| 87 | /// there is now a case of Scans touching. If so, they are |
---|
| 88 | /// combined and added to the end of the list. |
---|
| 89 | /// <li> If the pixel was added, the parameters are updated and the |
---|
| 90 | /// pixel counter incremented. |
---|
| 91 | /// </ul> |
---|
[238] | 92 | |
---|
| 93 | |
---|
[252] | 94 | bool flagDone=false,flagChanged=false, isNew=false; |
---|
| 95 | |
---|
[773] | 96 | for (std::vector<Scan>::iterator scan=this->scanlist.begin(); !flagDone && scan!=this->scanlist.end(); scan++){ |
---|
| 97 | if(y == scan->itsY){ // if the y value is already in the list |
---|
| 98 | if(scan->isInScan(x,y)) flagDone = true; // pixel already here. |
---|
[252] | 99 | else{ // it's a new pixel! |
---|
[776] | 100 | if((x==(scan->itsX-1)) || (x == (scan->itsX+scan->itsXLen)) ){ |
---|
[252] | 101 | // if it is adjacent to the existing range, add to that range |
---|
[773] | 102 | if(x==(scan->itsX-1)) scan->growLeft(); |
---|
| 103 | else scan->growRight(); |
---|
[252] | 104 | flagDone = true; |
---|
| 105 | flagChanged = true; |
---|
| 106 | isNew = true; |
---|
[238] | 107 | } |
---|
[252] | 108 | } |
---|
[239] | 109 | } |
---|
[238] | 110 | } |
---|
| 111 | |
---|
[744] | 112 | if(!flagDone){ |
---|
| 113 | // we got to the end of the scanlist, so there is no pre-existing scan with this y value |
---|
| 114 | // add a new scan consisting of just this pixel |
---|
[252] | 115 | Scan newOne(y,x,1); |
---|
| 116 | this->scanlist.push_back(newOne); |
---|
| 117 | isNew = true; |
---|
| 118 | } |
---|
[744] | 119 | else if(flagChanged){ |
---|
[252] | 120 | // this is true only if one of the pre-existing scans has changed |
---|
| 121 | // |
---|
| 122 | // need to clean up, to see if there is a case of two scans when |
---|
[744] | 123 | // there should be one. Only need to look at scans with matching |
---|
| 124 | // y-value |
---|
[252] | 125 | // |
---|
| 126 | // because there has been only one pixel added, only 2 AT MOST |
---|
| 127 | // scans will need to be combined, so once we meet a pair that |
---|
| 128 | // overlap, we can finish. |
---|
[238] | 129 | |
---|
[252] | 130 | bool combined = false; |
---|
[773] | 131 | std::vector<Scan>::iterator scan1=this->scanlist.begin(),scan2; |
---|
| 132 | for (; !combined && scan1!=this->scanlist.end(); scan1++){ |
---|
| 133 | if(scan1->itsY==y){ |
---|
| 134 | scan2=scan1; |
---|
| 135 | scan2++; |
---|
| 136 | for(; !combined && scan2!=this->scanlist.end(); scan2++){ |
---|
| 137 | if(scan2->itsY==y){ |
---|
[776] | 138 | combined = scan1->addScan(*scan2); |
---|
[744] | 139 | if(combined){ |
---|
[773] | 140 | this->scanlist.erase(scan2); |
---|
[744] | 141 | } |
---|
| 142 | } |
---|
| 143 | } |
---|
[252] | 144 | } |
---|
| 145 | } |
---|
| 146 | |
---|
[246] | 147 | } |
---|
[252] | 148 | |
---|
| 149 | if(isNew){ |
---|
| 150 | // update the centres, mins, maxs and increment the pixel counter |
---|
| 151 | if(this->numPix==0){ |
---|
| 152 | this->xSum = this->xmin = this->xmax = x; |
---|
| 153 | this->ySum = this->ymin = this->ymax = y; |
---|
| 154 | } |
---|
| 155 | else{ |
---|
| 156 | this->xSum += x; |
---|
| 157 | this->ySum += y; |
---|
| 158 | if(x<this->xmin) this->xmin = x; |
---|
| 159 | if(x>this->xmax) this->xmax = x; |
---|
| 160 | if(y<this->ymin) this->ymin = y; |
---|
| 161 | if(y>this->ymax) this->ymax = y; |
---|
| 162 | } |
---|
| 163 | this->numPix++; |
---|
[246] | 164 | } |
---|
[252] | 165 | |
---|
[246] | 166 | } |
---|
[252] | 167 | //------------------------------------------------------ |
---|
[246] | 168 | |
---|
[773] | 169 | void Object2D::addScan(Scan &scan) |
---|
[252] | 170 | { |
---|
[770] | 171 | long y=scan.getY(); |
---|
| 172 | for(long x=scan.getX();x<=scan.getXmax();x++) this->addPixel(x,y); |
---|
[238] | 173 | |
---|
[577] | 174 | } |
---|
[252] | 175 | //------------------------------------------------------ |
---|
[238] | 176 | |
---|
[252] | 177 | bool Object2D::isInObject(long x, long y) |
---|
| 178 | { |
---|
[371] | 179 | |
---|
[667] | 180 | std::vector<Scan>::iterator scn; |
---|
| 181 | bool returnval=false; |
---|
[773] | 182 | for(scn=this->scanlist.begin();scn!=this->scanlist.end()&&!returnval;scn++){ |
---|
[238] | 183 | |
---|
[667] | 184 | returnval = ((y == scn->itsY) && (x>= scn->itsX) && (x<=scn->getXmax())); |
---|
[238] | 185 | |
---|
[667] | 186 | } |
---|
| 187 | |
---|
| 188 | return returnval; |
---|
[238] | 189 | |
---|
[252] | 190 | } |
---|
| 191 | //------------------------------------------------------ |
---|
[238] | 192 | |
---|
[252] | 193 | std::ostream& operator<< ( std::ostream& theStream, Object2D& obj) |
---|
| 194 | { |
---|
[773] | 195 | if(obj.scanlist.size()>1) obj.order(); |
---|
| 196 | for(std::vector<Scan>::iterator s=obj.scanlist.begin();s!=obj.scanlist.end();s++) |
---|
| 197 | theStream << *s << "\n"; |
---|
[252] | 198 | theStream<<"---\n"; |
---|
[270] | 199 | return theStream; |
---|
[238] | 200 | |
---|
[252] | 201 | } |
---|
| 202 | //------------------------------------------------------ |
---|
[238] | 203 | |
---|
[252] | 204 | void Object2D::calcParams() |
---|
| 205 | { |
---|
| 206 | this->xSum = 0; |
---|
| 207 | this->ySum = 0; |
---|
[623] | 208 | std::vector<Scan>::iterator s; |
---|
[773] | 209 | for(s=this->scanlist.begin();s!=this->scanlist.end();s++){ |
---|
[238] | 210 | |
---|
[623] | 211 | if(s==this->scanlist.begin()){ |
---|
| 212 | this->ymin = this->ymax = s->itsY; |
---|
| 213 | this->xmin = s->itsX; |
---|
| 214 | this->xmax = s->getXmax(); |
---|
[252] | 215 | } |
---|
| 216 | else{ |
---|
[623] | 217 | if(this->ymin>s->itsY) this->ymin = s->itsY; |
---|
| 218 | if(this->xmin>s->itsX) this->xmin = s->itsX; |
---|
| 219 | if(this->ymax<s->itsY) this->ymax = s->itsY; |
---|
| 220 | if(this->xmax<s->getXmax()) this->xmax = s->getXmax(); |
---|
[252] | 221 | } |
---|
[238] | 222 | |
---|
[623] | 223 | this->ySum += s->itsY*s->getXlen(); |
---|
| 224 | for(int x=s->itsX;x<=s->getXmax();x++) |
---|
[252] | 225 | this->xSum += x; |
---|
| 226 | |
---|
[238] | 227 | } |
---|
| 228 | |
---|
| 229 | } |
---|
[252] | 230 | //------------------------------------------------------ |
---|
[238] | 231 | |
---|
[252] | 232 | void Object2D::cleanup() |
---|
| 233 | { |
---|
[773] | 234 | std::vector<Scan>::iterator s1=this->scanlist.begin(),s2; |
---|
| 235 | for (; s1!=this->scanlist.end(); s1++){ |
---|
| 236 | s2=s1; s2++; |
---|
| 237 | for (; s2!=this->scanlist.end(); s2++){ |
---|
[238] | 238 | |
---|
[773] | 239 | if(overlap(*s1,*s2)){ |
---|
| 240 | s1->addScan(*s2); |
---|
| 241 | this->scanlist.erase(s2); |
---|
| 242 | } |
---|
| 243 | } |
---|
| 244 | } |
---|
| 245 | |
---|
[238] | 246 | } |
---|
[252] | 247 | //------------------------------------------------------ |
---|
[238] | 248 | |
---|
[252] | 249 | long Object2D::getNumDistinctY() |
---|
| 250 | { |
---|
| 251 | std::vector<long> ylist; |
---|
| 252 | if(this->scanlist.size()==0) return 0; |
---|
| 253 | if(this->scanlist.size()==1) return 1; |
---|
[623] | 254 | std::vector<Scan>::iterator scn; |
---|
[773] | 255 | for(scn=this->scanlist.begin();scn!=this->scanlist.end();scn++){ |
---|
[238] | 256 | bool inList = false; |
---|
[541] | 257 | unsigned int j=0; |
---|
[623] | 258 | long y = scn->itsY; |
---|
[252] | 259 | while(!inList && j<ylist.size()){ |
---|
| 260 | if(y==ylist[j]) inList=true; |
---|
[238] | 261 | j++; |
---|
| 262 | }; |
---|
[252] | 263 | if(!inList) ylist.push_back(y); |
---|
[238] | 264 | } |
---|
[252] | 265 | return ylist.size(); |
---|
[238] | 266 | } |
---|
[252] | 267 | //------------------------------------------------------ |
---|
[238] | 268 | |
---|
[252] | 269 | long Object2D::getNumDistinctX() |
---|
| 270 | { |
---|
| 271 | std::vector<long> xlist; |
---|
| 272 | if(this->scanlist.size()==0) return 0; |
---|
| 273 | if(this->scanlist.size()==1) return 1; |
---|
[623] | 274 | std::vector<Scan>::iterator scn; |
---|
[773] | 275 | for(scn=this->scanlist.begin();scn!=this->scanlist.end();scn++){ |
---|
[623] | 276 | for(int x=scn->itsX;x<scn->getXmax();x++){ |
---|
[252] | 277 | bool inList = false; |
---|
[541] | 278 | unsigned int j=0; |
---|
[252] | 279 | while(!inList && j<xlist.size()){ |
---|
| 280 | if(x==xlist[j]) inList=true; |
---|
| 281 | j++; |
---|
| 282 | }; |
---|
| 283 | if(!inList) xlist.push_back(x); |
---|
| 284 | } |
---|
| 285 | } |
---|
| 286 | return xlist.size(); |
---|
[238] | 287 | } |
---|
[252] | 288 | //------------------------------------------------------ |
---|
| 289 | |
---|
[773] | 290 | bool Object2D::scanOverlaps(Scan &scan) |
---|
[252] | 291 | { |
---|
| 292 | bool returnval = false; |
---|
[773] | 293 | for(std::vector<Scan>::iterator s=this->scanlist.begin();!returnval&&s!=this->scanlist.end();s++){ |
---|
| 294 | returnval = returnval || s->overlaps(scan); |
---|
[252] | 295 | } |
---|
| 296 | return returnval; |
---|
| 297 | } |
---|
| 298 | |
---|
[399] | 299 | //------------------------------------------------------ |
---|
| 300 | |
---|
| 301 | void Object2D::addOffsets(long xoff, long yoff) |
---|
| 302 | { |
---|
[623] | 303 | std::vector<Scan>::iterator scn; |
---|
[773] | 304 | for(scn=this->scanlist.begin();scn!=this->scanlist.end();scn++) |
---|
[623] | 305 | scn->addOffsets(xoff,yoff); |
---|
[399] | 306 | this->xSum += xoff*numPix; |
---|
| 307 | this->xmin += xoff; xmax += xoff; |
---|
| 308 | this->ySum += yoff*numPix; |
---|
| 309 | this->ymin += yoff; ymax += yoff; |
---|
| 310 | } |
---|
| 311 | |
---|
[469] | 312 | //------------------------------------------------------ |
---|
| 313 | |
---|
[1133] | 314 | bool Object2D::findEllipse(bool weightByFlux, float *array, size_t xdim, size_t ydim, int xzero, int yzero, float x0, float y0) |
---|
[1130] | 315 | { |
---|
| 316 | bool result=true; |
---|
| 317 | double sumxx=0.,sumyy=0.,sumxy=0.,sumflux=0.; |
---|
[1211] | 318 | int ct=0; |
---|
[1130] | 319 | std::vector<Scan>::iterator scn=this->scanlist.begin(); |
---|
| 320 | for(;scn!=this->scanlist.end();scn++){ |
---|
| 321 | int y = scn->itsY; |
---|
[1133] | 322 | float yoff=scn->itsY - y0; |
---|
[1130] | 323 | for(int x=scn->itsX;x<=scn->getXmax();x++){ |
---|
[1211] | 324 | ct++; |
---|
[1133] | 325 | float xoff=x-x0; |
---|
[1130] | 326 | float flux = weightByFlux ? array[(x-xzero)+xdim*(y-yzero)] : 1; |
---|
| 327 | sumxx += (xoff*xoff*flux); |
---|
| 328 | sumyy += (yoff*yoff*flux); |
---|
| 329 | sumxy += (xoff*yoff*flux); |
---|
| 330 | sumflux += flux; |
---|
| 331 | } |
---|
| 332 | } |
---|
[1211] | 333 | |
---|
| 334 | if(ct>0){ |
---|
| 335 | sumxx /= sumflux; |
---|
| 336 | sumxy /= sumflux; |
---|
| 337 | sumyy /= sumflux; |
---|
| 338 | } |
---|
[1130] | 339 | |
---|
[1131] | 340 | this->posAngle = 0.5 * atan2( 2*sumxy , (sumxx-sumyy) ) + M_PI/2.; |
---|
| 341 | this->posAngle = fmod(this->posAngle, 2.*M_PI); |
---|
| 342 | if(this->posAngle > M_PI) this->posAngle -= 2.*M_PI; |
---|
[1155] | 343 | double plusroot = sumxx + sumyy + sqrt((sumxx-sumyy)*(sumxx-sumyy) + 4.*sumxy*sumxy); |
---|
| 344 | result = ( plusroot > 0 ); |
---|
| 345 | double minusroot = sumxx + sumyy - sqrt((sumxx-sumyy)*(sumxx-sumyy) + 4.*sumxy*sumxy); |
---|
| 346 | result = result && ( minusroot > 0 ); |
---|
[1130] | 347 | if(result){ |
---|
[1155] | 348 | this->majorAxis = sqrt( 2. * plusroot ); |
---|
| 349 | this->minorAxis = sqrt( 2. * minusroot ); |
---|
[1130] | 350 | this->minorAxis = std::max(this->minorAxis,0.1); |
---|
| 351 | } |
---|
| 352 | else this->majorAxis = this->minorAxis = 0.; |
---|
| 353 | return result; |
---|
| 354 | } |
---|
| 355 | |
---|
| 356 | |
---|
| 357 | //------------------------------------------------------ |
---|
| 358 | |
---|
[469] | 359 | double Object2D::getPositionAngle() |
---|
| 360 | { |
---|
| 361 | |
---|
| 362 | int sumxx=0; |
---|
| 363 | int sumyy=0; |
---|
| 364 | int sumxy=0; |
---|
| 365 | std::vector<Scan>::iterator scn=this->scanlist.begin(); |
---|
[773] | 366 | for(;scn!=this->scanlist.end();scn++){ |
---|
[469] | 367 | sumyy += (scn->itsY*scn->itsY)*scn->itsXLen; |
---|
| 368 | for(int x=scn->itsX;x<=scn->getXmax();x++){ |
---|
| 369 | sumxx += x*x; |
---|
| 370 | sumxy += x*scn->itsY; |
---|
| 371 | } |
---|
| 372 | } |
---|
| 373 | |
---|
| 374 | // Calculate net moments |
---|
| 375 | double mxx = sumxx - this->xSum*this->xSum / double(this->numPix); |
---|
| 376 | double myy = sumyy - this->ySum*this->ySum / double(this->numPix); |
---|
| 377 | double mxy = sumxy - this->xSum*this->ySum / double(this->numPix); |
---|
| 378 | |
---|
[472] | 379 | if(mxy==0){ |
---|
| 380 | if(mxx>myy) return M_PI/2.; |
---|
| 381 | else return 0.; |
---|
| 382 | } |
---|
[469] | 383 | |
---|
| 384 | // Angle of the minimum moment |
---|
| 385 | double tantheta = (mxx - myy + sqrt( (mxx-myy)*(mxx-myy) + 4.*mxy*mxy))/(2.*mxy); |
---|
| 386 | |
---|
| 387 | return atan(tantheta); |
---|
| 388 | } |
---|
| 389 | |
---|
| 390 | //------------------------------------------------------ |
---|
| 391 | |
---|
[1183] | 392 | std::pair<double,double> Object2D::getPrincipalAxes() |
---|
[469] | 393 | { |
---|
| 394 | |
---|
[470] | 395 | double theta = this->getPositionAngle(); |
---|
[570] | 396 | double x0 = this->getXaverage(); |
---|
| 397 | double y0 = this->getYaverage(); |
---|
[469] | 398 | std::vector<Scan>::iterator scn=this->scanlist.begin(); |
---|
[1212] | 399 | double maj,min,majMax=0.,majMin=0.,minMax=0.,minMin=0.; |
---|
[773] | 400 | for(;scn!=this->scanlist.end();scn++){ |
---|
[469] | 401 | for(int x=scn->itsX;x<=scn->getXmax();x++){ |
---|
[1212] | 402 | maj = (x-x0+0.5)*cos(theta) + (scn->itsY-y0+0.5)*sin(theta); |
---|
| 403 | min = (x-x0+0.5)*sin(theta) + (scn->itsY-y0+0.5)*cos(theta); |
---|
| 404 | majMax=std::max(maj,majMax); |
---|
| 405 | majMin=std::min(maj,majMin); |
---|
| 406 | minMax=std::max(min,minMax); |
---|
| 407 | minMin=std::min(min,minMin); |
---|
[469] | 408 | } |
---|
| 409 | } |
---|
| 410 | |
---|
| 411 | std::pair<double,double> axes; |
---|
[1212] | 412 | axes.first=std::max(majMax-majMin,1.); |
---|
| 413 | axes.second=std::max(minMax-minMin,1.); |
---|
[469] | 414 | return axes; |
---|
| 415 | |
---|
| 416 | } |
---|
| 417 | |
---|
[770] | 418 | |
---|
| 419 | //------------------------------------------------------ |
---|
| 420 | |
---|
| 421 | |
---|
| 422 | bool Object2D::canMerge(Object2D &other, float threshS, bool flagAdj) |
---|
| 423 | { |
---|
| 424 | long gap; |
---|
| 425 | if(flagAdj) gap = 1; |
---|
| 426 | else gap = long( ceil(threshS) ); |
---|
| 427 | bool near = this->isNear(other,gap); |
---|
| 428 | if(near) return this->isClose(other,threshS,flagAdj); |
---|
| 429 | else return near; |
---|
| 430 | } |
---|
| 431 | |
---|
| 432 | //------------------------------------------------------ |
---|
| 433 | |
---|
| 434 | bool Object2D::isNear(Object2D &other, long gap) |
---|
| 435 | { |
---|
| 436 | bool areNear; |
---|
| 437 | // Test X ranges |
---|
| 438 | if((this->xmin-gap)<other.xmin) areNear=((this->xmax+gap)>=other.xmin); |
---|
| 439 | else areNear=(other.xmax>=(this->xmin-gap)); |
---|
| 440 | // Test Y ranges |
---|
| 441 | if(areNear){ |
---|
| 442 | if((this->ymin-gap)<other.ymin) areNear=areNear&&((this->ymax+gap)>=other.ymin); |
---|
| 443 | else areNear=areNear&&(other.ymax>=(this->ymin-gap)); |
---|
| 444 | } |
---|
| 445 | return areNear; |
---|
| 446 | } |
---|
| 447 | |
---|
| 448 | //------------------------------------------------------ |
---|
| 449 | |
---|
| 450 | bool Object2D::isClose(Object2D &other, float threshS, bool flagAdj) |
---|
| 451 | { |
---|
| 452 | |
---|
| 453 | long gap = long(ceil(threshS)); |
---|
| 454 | if(flagAdj) gap=1; |
---|
| 455 | |
---|
| 456 | bool close = false; |
---|
| 457 | |
---|
| 458 | long ycommonMin=std::max(this->ymin-gap,other.ymin)-gap; |
---|
| 459 | long ycommonMax=std::min(this->ymax+gap,other.ymax)+gap; |
---|
| 460 | |
---|
| 461 | std::vector<Scan>::iterator iter1,iter2; |
---|
[773] | 462 | for(iter1=this->scanlist.begin();!close && iter1!=this->scanlist.end();iter1++){ |
---|
[770] | 463 | if(iter1->itsY >= ycommonMin && iter1->itsY<=ycommonMax){ |
---|
[773] | 464 | for(iter2=other.scanlist.begin();!close && iter2!=other.scanlist.end();iter2++){ |
---|
[770] | 465 | if(iter2->itsY >= ycommonMin && iter2->itsY<=ycommonMax){ |
---|
| 466 | |
---|
[1443] | 467 | if(abs(iter1->itsY-iter2->itsY)<=gap){ |
---|
[770] | 468 | if(flagAdj) { |
---|
[771] | 469 | if((iter1->itsX-gap)>iter2->itsX) close=((iter2->itsX+iter2->itsXLen-1)>=(iter1->itsX-gap)); |
---|
| 470 | else close = ( (iter1->itsX+iter1->itsXLen+gap-1)>=iter2->itsX); |
---|
[770] | 471 | } |
---|
[874] | 472 | else close = (minSep(*iter1,*iter2) <= threshS); |
---|
[770] | 473 | } |
---|
| 474 | |
---|
| 475 | } |
---|
| 476 | } |
---|
| 477 | } |
---|
| 478 | } |
---|
| 479 | |
---|
| 480 | return close; |
---|
| 481 | |
---|
| 482 | } |
---|
| 483 | |
---|
| 484 | |
---|
| 485 | |
---|
[238] | 486 | } |
---|