Line data Source code
1 : /**************************************************************************
2 : * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 : * *
4 : * Author: The ALICE Off-line Project. *
5 : * Contributors are mentioned in the code where appropriate. *
6 : * *
7 : * Permission to use, copy, modify and distribute this software and its *
8 : * documentation strictly for non-commercial purposes is hereby granted *
9 : * without fee, provided that the above copyright notice appears in all *
10 : * copies and that both the copyright notice and this permission notice *
11 : * appear in the supporting documentation. The authors make no claims *
12 : * about the suitability of this software for any purpose. It is *
13 : * provided "as is" without express or implied warranty. *
14 : **************************************************************************/
15 :
16 : // $Id$
17 :
18 : ///\class AliMUONContour
19 : ///
20 : /// A contour is a set of (closed and counter-clockwise-oriented) polygons
21 : ///
22 : /// \author Laurent Aphecetche, Subatech
23 :
24 : #include "AliMUONContour.h"
25 :
26 : #include "AliLog.h"
27 : #include "AliMUONPolygon.h"
28 : #include "AliMpArea.h"
29 : #include <Riostream.h>
30 : #include <TGeoMatrix.h>
31 : #include <TMath.h>
32 : #include <TObjArray.h>
33 : #include <TPolyLine.h>
34 : #include <TString.h>
35 : #include <TVector2.h>
36 : #include <float.h>
37 :
38 : using std::cout;
39 : using std::endl;
40 : ///\cond CLASSIMP
41 12 : ClassImp(AliMUONContour)
42 : ///\endcond
43 :
44 : //_____________________________________________________________________________
45 0 : AliMUONContour::AliMUONContour(const char* name) : TNamed(name,""),
46 0 : fPolygons(new TObjArray),
47 0 : fXmin(FLT_MAX),
48 0 : fXmax(-FLT_MAX),
49 0 : fYmin(FLT_MAX),
50 0 : fYmax(-FLT_MAX),
51 0 : fNofVertices(0)
52 0 : {
53 : /// ctor
54 0 : fPolygons->SetOwner(kTRUE);
55 0 : }
56 :
57 : //_____________________________________________________________________________
58 : AliMUONContour::AliMUONContour(const char* name, const AliMpArea& area)
59 0 : : TNamed(name,""),
60 0 : fPolygons(new TObjArray),
61 0 : fXmin(area.LeftBorder()),
62 0 : fXmax(area.RightBorder()),
63 0 : fYmin(area.DownBorder()),
64 0 : fYmax(area.UpBorder()),
65 0 : fNofVertices(0)
66 0 : {
67 : /// ctor
68 0 : fPolygons->SetOwner(kTRUE);
69 :
70 0 : AliMUONPolygon* pol = new AliMUONPolygon(area.GetPositionX(),
71 0 : area.GetPositionY(),
72 0 : area.GetDimensionX(),
73 0 : area.GetDimensionY());
74 :
75 0 : fPolygons->AddLast(pol);
76 :
77 0 : fNofVertices = pol->NumberOfVertices();
78 0 : }
79 :
80 : //______________________________________________________________________________
81 : AliMUONContour::AliMUONContour(const AliMUONContour& rhs)
82 0 : : TNamed(rhs),
83 0 : fPolygons(0x0),
84 0 : fXmin(FLT_MAX),
85 0 : fXmax(-FLT_MAX),
86 0 : fYmin(FLT_MAX),
87 0 : fYmax(-FLT_MAX),
88 0 : fNofVertices(0)
89 0 : {
90 : /// Copy constructor.
91 :
92 0 : ((AliMUONContour&)rhs).Copy(*this);
93 0 : }
94 :
95 : //______________________________________________________________________________
96 : AliMUONContour&
97 : AliMUONContour::operator=(const AliMUONContour& rhs)
98 : {
99 : /// Assignment operator
100 0 : if ( this != &rhs )
101 : {
102 0 : delete fPolygons;
103 0 : fPolygons = 0;
104 0 : rhs.Copy(*this);
105 0 : }
106 0 : return *this;
107 : }
108 :
109 : //_____________________________________________________________________________
110 : AliMUONContour::~AliMUONContour()
111 0 : {
112 : /// dtor
113 0 : delete fPolygons;
114 0 : }
115 :
116 : //_____________________________________________________________________________
117 : void
118 : AliMUONContour::Add(const AliMUONPolygon& polygon)
119 : {
120 : /// Add points from the polygon
121 :
122 0 : for ( Int_t i = 0; i < polygon.NumberOfVertices(); ++i )
123 : {
124 0 : Double_t x = polygon.X(i);
125 0 : Double_t y = polygon.Y(i);
126 0 : fXmin = TMath::Min(fXmin,x);
127 0 : fXmax = TMath::Max(fXmax,x);
128 0 : fYmin = TMath::Min(fYmin,y);
129 0 : fYmax = TMath::Max(fYmax,y);
130 : }
131 :
132 0 : fPolygons->AddLast(new AliMUONPolygon(polygon));
133 :
134 0 : fNofVertices += polygon.NumberOfVertices();
135 0 : }
136 :
137 : //_____________________________________________________________________________
138 : AliMpArea
139 : AliMUONContour::Area() const
140 : {
141 : /// Return the area covered by this contour (i.e. the area that
142 : /// contains all the poylines)
143 :
144 0 : return AliMpArea( (fXmax+fXmin)/2.0, (fYmax+fYmin)/2.0 ,
145 0 : TMath::Abs(fXmax-fXmin)/2.0, TMath::Abs(fYmax-fYmin)/2.0 );
146 : }
147 :
148 : //______________________________________________________________________________
149 : void
150 : AliMUONContour::AssertOrientation(Bool_t autoCorrect)
151 : {
152 : /// Insure that all our polygons are counter-clockwise oriented
153 : /// If autoCorrect==kTRUE, we change the orientation if it is not
154 : /// already correct.
155 : /// If autoCorrect==kFALSE and the orientation is not correct, we
156 : /// just issue an error message.
157 :
158 0 : for ( Int_t i = 0; i <= fPolygons->GetLast(); ++i )
159 : {
160 0 : AliMUONPolygon* pol = static_cast<AliMUONPolygon*>(fPolygons->UncheckedAt(i));
161 0 : if ( !pol->IsCounterClockwiseOriented() )
162 : {
163 0 : if ( autoCorrect )
164 : {
165 0 : pol->ReverseOrientation();
166 : }
167 : else
168 : {
169 0 : AliError("Got a polygon oriented the wrong way");
170 0 : StdoutToAliError(Print(););
171 0 : return;
172 : }
173 0 : }
174 0 : }
175 0 : }
176 :
177 : //______________________________________________________________________________
178 : void AliMUONContour::Copy(TObject& obj) const
179 : {
180 : /// Copy this to obj
181 :
182 0 : AliMUONContour& rhs = static_cast<AliMUONContour&>(obj);
183 0 : TNamed::Copy(rhs);
184 0 : delete rhs.fPolygons;
185 0 : rhs.fPolygons = new TObjArray(fPolygons->GetLast()+1);
186 0 : rhs.fPolygons->SetOwner(kTRUE);
187 0 : TIter next(fPolygons);
188 : AliMUONPolygon* pol;
189 0 : while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
190 : {
191 0 : rhs.fPolygons->AddLast(pol->Clone());
192 : }
193 0 : rhs.fXmin = fXmin;
194 0 : rhs.fXmax = fXmax;
195 0 : rhs.fYmin = fYmin;
196 0 : rhs.fYmax = fYmax;
197 0 : rhs.fNofVertices = fNofVertices;
198 0 : }
199 :
200 : //_____________________________________________________________________________
201 : Bool_t
202 : AliMUONContour::IsInside(Double_t x, Double_t y) const
203 : {
204 : /// Whether the point (x,y) is inside one of ours polylines
205 :
206 0 : if ( x >= fXmin && x <= fXmax && y >= fYmin && y <= fYmax )
207 : {
208 0 : TIter next(fPolygons);
209 : AliMUONPolygon* pol;
210 0 : while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
211 : {
212 0 : if ( pol->Contains(x,y) )
213 : {
214 0 : return kTRUE;
215 : }
216 : }
217 0 : }
218 :
219 0 : return kFALSE;
220 0 : }
221 :
222 : //_____________________________________________________________________________
223 : void
224 : AliMUONContour::Offset(Double_t x, Double_t y)
225 : {
226 : /// Offset all lines by a given offset
227 :
228 0 : TIter next(fPolygons);
229 : AliMUONPolygon* pol;
230 :
231 0 : while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
232 : {
233 0 : for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i )
234 : {
235 0 : pol->SetVertex(i,pol->X(i)+x,pol->Y(i)+y);
236 : }
237 : }
238 :
239 0 : fXmin += x;
240 0 : fXmax += x;
241 0 : fYmin += y;
242 0 : fYmax += y;
243 0 : }
244 :
245 : //_____________________________________________________________________________
246 : void
247 : AliMUONContour::Print(Option_t* opt) const
248 : {
249 : /// Printout
250 :
251 0 : cout << GetName() << " NofVertices=" << NumberOfVertices() << " Ngroups=" << fPolygons->GetLast()+1 << endl;
252 0 : TString sopt(opt);
253 0 : sopt.ToUpper();
254 0 : if (sopt.Contains("B"))
255 : {
256 0 : Area().Print("B");
257 0 : }
258 :
259 0 : TIter next(fPolygons);
260 : AliMUONPolygon* pol;
261 0 : while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
262 : {
263 0 : pol->Print(opt);
264 : }
265 :
266 :
267 0 : cout << endl;
268 0 : }
269 :
270 : //_____________________________________________________________________________
271 : void
272 : AliMUONContour::Transform(const TGeoHMatrix& matrix)
273 : {
274 : /// Transform the polygons using the given transformation
275 :
276 0 : TIter next(fPolygons);
277 : AliMUONPolygon* pol;
278 :
279 0 : fXmin = fYmin = FLT_MAX;
280 0 : fXmax = fYmax = -FLT_MAX;
281 :
282 0 : while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
283 : {
284 0 : for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i )
285 : {
286 0 : Double_t pl[3] = { pol->X(i), pol->Y(i), 0 };
287 0 : Double_t pg[3] = { 0., 0., 0. };
288 0 : matrix.LocalToMaster(pl, pg);
289 0 : pol->SetVertex(i,pg[0],pg[1]);
290 0 : fXmin = TMath::Min(fXmin,pg[0]);
291 0 : fYmin = TMath::Min(fYmin,pg[1]);
292 0 : fXmax = TMath::Max(fXmax,pg[0]);
293 0 : fYmax = TMath::Max(fYmax,pg[1]);
294 0 : }
295 : }
296 :
297 0 : AssertOrientation(kTRUE);
298 0 : }
299 :
300 : //_____________________________________________________________________________
301 : Bool_t
302 : AliMUONContour::IsValid() const
303 : {
304 : /// A valid contour is one with a valid area and at least 3 vertices.
305 0 : return fNofVertices >= 3 && Area().IsValid();
306 : }
|