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

Last change on this file since 527 was 527, checked in by MatthewWhiting, 15 years ago

Fixing the intersection() and union() calls for Scan, and adding a isNull() function that is used in the printing function.

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