source: trunk/src/PixelMap/Scan.cc @ 505

Last change on this file since 505 was 505, checked in by MatthewWhiting, 16 years ago

Fixing bug in merging for the case of non-adjacent merging. Required a new minSep function for the Scan class.

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