source: tags/release-1.2.2/src/PixelMap/Scan.cc

Last change on this file was 1036, checked in by MatthewWhiting, 12 years ago

Changing a fabsf to fabs -- otherwise have an error compiling on lynx.

File size: 7.8 KB
Line 
1// -----------------------------------------------------------------------
2// Scan.cc: Member functions for the Scan 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// -----------------------------------------------------------------------
28#include <duchamp/PixelMap/Scan.hh>
29#include <iostream>
30#include <math.h>
31
32namespace PixelInfo
33{
34
35  Scan::Scan()
36  {
37    this->itsY=-1;
38    this->itsX=-1;
39    this->itsXLen=0;
40  }
41
42  Scan::Scan(long y, long x, long xl):
43    itsY(y), itsX(x),itsXLen(xl)
44  {
45  }
46
47  Scan::Scan(const Scan& s)
48  {
49    operator=(s);
50  }
51  //------------------------------------------------------
52 
53  Scan& Scan::operator= (const Scan& s)
54  {   
55    if(this == &s) return *this;
56    this->itsY=s.itsY;
57    this->itsX=s.itsX;
58    this->itsXLen=s.itsXLen;
59    return *this;
60  }
61  //------------------------------------------------------
62
63  bool Scan::addScan(const Scan &other)
64  {
65    bool altered=this->touches(other);
66    if(altered){
67      long x = std::min(this->itsX,other.itsX);
68      long xmax = std::max(this->itsX+this->itsXLen-1,other.itsX+other.itsXLen-1);
69      this->itsX=x;
70      this->itsXLen=xmax-x+1;
71    }
72    return altered;
73  }
74
75
76  Scan nullScan()
77  {
78    /// A simple way of returning a scan with zero length.
79    Scan null(-1,-1,0);
80    return null;
81  }
82
83  bool Scan::isNull()
84  {
85    return (itsY==-1 && itsX==-1 && itsXLen==0);
86  }
87
88  //------------------------------------------------------
89
90  Scan unite(Scan &scan1, Scan &scan2)
91  {
92    /// Return a scan that includes all pixels from both scans, but
93    /// only if they overlap. If they do not, return the null scan.
94
95    Scan joined;
96    if(!touching(scan1,scan2)){
97      joined = nullScan();
98    }
99    else{
100      long y = scan1.getY();
101      long x = std::min(scan1.getX(),scan2.getX());
102      long xmax = std::max(scan1.getXmax(),scan2.getXmax());
103      joined.define(y,x,xmax-x+1);
104    }
105    return joined;
106  }
107
108  //------------------------------------------------------
109
110  Scan intersect(Scan &scan1, Scan &scan2)
111  {
112    /// Return a scan that includes all pixels that lie in both scans.
113    ///
114    /// If they do not overlap, return the null scan.
115
116    Scan intersection;
117    if(!scan1.overlaps(scan2)){
118      intersection = nullScan();
119    }
120    else{
121      long y = scan1.getY();
122      long x = std::max(scan1.getX(),scan2.getX());
123      long xmax = std::min(scan1.getXmax(),scan2.getXmax());
124      intersection.define(y,x,xmax-x+1);
125    }
126    return intersection;
127  }
128  //------------------------------------------------------
129
130  bool Scan::touches(const Scan &other)
131  {
132    return this->overlaps(other) || this->isAdjacentTo(other);
133  }
134
135  bool Scan::overlaps(const Scan &other)
136  {
137    if(this->itsY != other.itsY) return false;
138    else if(this->itsX <= other.itsX){
139      return (other.itsX < (this->itsX+this->itsXLen));
140    }
141    else{
142      return (this->itsX < (other.itsX+other.itsXLen));
143    }
144  }
145
146  bool Scan::isAdjacentTo(const Scan &other)
147  {
148    if(this->itsY != other.itsY) return false;
149    else if(this->itsX <= other.itsX){
150      return (other.itsX == (this->itsX+this->itsXLen));
151    }
152    else{
153      return (this->itsX == (other.itsX+other.itsXLen));
154    }
155  }
156  //------------------------------------------------------
157
158  bool touching(Scan &scan1, Scan &scan2)
159  {
160    ///  Test whether two scans either overlap, or lie adjacent
161    ///  (ie. there are no pixels lying between the two scans).
162    /// \return A bool value.
163
164    return overlap(scan1,scan2) || adjacent(scan1,scan2);
165 
166  }
167  //------------------------------------------------------
168
169  bool overlap(Scan &scan1, Scan &scan2)
170  {
171    ///  Test whether two scans overlap, ie. they have pixels in
172    ///  common.
173    /// \return A bool value.
174
175    if(scan1.getY()!=scan2.getY()) return false;
176    else if(scan1.getX() <= scan2.getX())
177      return (scan2.getX() <= scan1.getXmax());
178    else
179      return (scan1.getX() <= scan2.getXmax());
180 
181  }
182  //------------------------------------------------------
183
184  bool adjacent(Scan &scan1, Scan &scan2)
185  {
186     /// Test whether two scans lie adjacent (ie. there are no pixels
187     /// lying between the two scans).  If they overlap, return false.
188     /// \return A bool value.
189
190    if(scan1.getY()!=scan2.getY()) return false;
191    else if(scan1.getX() <= scan2.getX())
192      return (scan2.getX() == scan1.getXmax()+1);
193    else
194      return (scan1.getX() == scan2.getXmax()+1);
195 
196  }
197  //------------------------------------------------------
198
199  std::ostream& operator<< ( std::ostream& theStream, Scan& scan)
200  {
201    ///  Output the three key parameters of the scan.
202
203    if(scan.isNull()) theStream << "NULL";
204    else{
205      theStream << scan.itsX;
206      theStream << "-" << scan.getXmax();
207      theStream << ", " << scan.itsY;
208    }
209    return theStream;
210  }
211  //------------------------------------------------------
212
213  bool operator< (Scan lhs, Scan rhs)
214  {
215    /// Test for less-than first on the y-values, and if they are
216    /// equal, test on the starting x-value, and then finally on the
217    /// length.
218    ///
219    /// This is necessary for sorting functions on lists of Scans (used
220    /// by the Object2D class).
221
222    if(lhs.itsY != rhs.itsY)      return (lhs.itsY    < rhs.itsY);
223    else if(lhs.itsX != rhs.itsX) return (lhs.itsX    < rhs.itsX);
224    else                          return (lhs.itsXLen < rhs.itsXLen);
225  }
226  //------------------------------------------------------
227
228  bool operator== (Scan lhs, Scan rhs)
229  {
230    /// For two scans to be equal, all three parameters must be equal.
231
232    return (lhs.itsY == rhs.itsY) &&
233      (lhs.itsX == rhs.itsX) &&
234      (lhs.itsXLen == rhs.itsXLen);
235  }
236  //------------------------------------------------------
237
238  bool Scan::isInScan(long x, long y)
239  {
240    return (y == this->itsY) &&
241      ( (x>= this->itsX) && (x < (this->itsXLen+this->itsX)) );
242  }
243  //------------------------------------------------------
244
245  float minSep(Scan &s1, Scan &s2)
246  {
247 
248    if(s1.getX() > s2.getXmax()) return hypot(s1.getX()-s2.getXmax(),s1.getY()-s2.getY());
249    else if(s2.getX() > s1.getXmax()) return hypot(s2.getX()-s1.getXmax(),s1.getY()-s2.getY());
250    else return fabs(s1.getY()-s2.getY());
251   
252  }
253  //------------------------------------------------------
254 
255 
256  void mergeList(std::vector<Scan> scanlist)
257  {
258    std::vector<Scan>::iterator iter;
259    unsigned int counter=0,compCounter;
260    while(counter<(scanlist.size()-1)){
261
262     
263      compCounter = counter+1;
264     
265      do{
266       
267        if(touching(scanlist[counter],scanlist[compCounter])){
268          Scan temp = unite(scanlist[counter],scanlist[compCounter]);
269          iter = scanlist.begin()+compCounter;
270          scanlist.erase(iter);
271          iter = scanlist.begin()+counter;
272          scanlist.erase(iter);
273          scanlist.push_back(temp);
274        }
275        else compCounter ++;
276      }while(compCounter < scanlist.size());
277
278      counter++;
279    }
280
281  }
282
283
284}
Note: See TracBrowser for help on using the repository browser.