1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///\class AliMUONContour
20 /// A contour is a set of (closed and counter-clockwise-oriented) polygons
22 /// \author Laurent Aphecetche, Subatech
24 #include "AliMUONContour.h"
27 #include "AliMUONPolygon.h"
28 #include "AliMpArea.h"
29 #include <Riostream.h>
30 #include <TGeoMatrix.h>
32 #include <TObjArray.h>
33 #include <TPolyLine.h>
39 ClassImp(AliMUONContour)
42 //_____________________________________________________________________________
43 AliMUONContour::AliMUONContour(const char* name) : TNamed(name,""),
44 fPolygons(new TObjArray),
52 fPolygons->SetOwner(kTRUE);
55 //_____________________________________________________________________________
56 AliMUONContour::AliMUONContour(const char* name, const AliMpArea& area)
58 fPolygons(new TObjArray),
59 fXmin(area.LeftBorder()),
60 fXmax(area.RightBorder()),
61 fYmin(area.DownBorder()),
62 fYmax(area.UpBorder()),
66 fPolygons->SetOwner(kTRUE);
68 AliMUONPolygon* pol = new AliMUONPolygon(area.GetPositionX(),
71 area.GetDimensionY());
73 fPolygons->AddLast(pol);
75 fNofVertices = pol->NumberOfVertices();
78 //______________________________________________________________________________
79 AliMUONContour::AliMUONContour(const AliMUONContour& rhs)
90 ((AliMUONContour&)rhs).Copy(*this);
93 //______________________________________________________________________________
95 AliMUONContour::operator=(const AliMUONContour& rhs)
97 /// Assignment operator
107 //_____________________________________________________________________________
108 AliMUONContour::~AliMUONContour()
114 //_____________________________________________________________________________
116 AliMUONContour::Add(const AliMUONPolygon& polygon)
118 /// Add points from the polygon
120 for ( Int_t i = 0; i < polygon.NumberOfVertices(); ++i )
122 Double_t x = polygon.X(i);
123 Double_t y = polygon.Y(i);
124 fXmin = TMath::Min(fXmin,x);
125 fXmax = TMath::Max(fXmax,x);
126 fYmin = TMath::Min(fYmin,y);
127 fYmax = TMath::Max(fYmax,y);
130 fPolygons->AddLast(new AliMUONPolygon(polygon));
132 fNofVertices += polygon.NumberOfVertices();
135 //_____________________________________________________________________________
137 AliMUONContour::Area() const
139 /// Return the area covered by this contour (i.e. the area that
140 /// contains all the poylines)
142 return AliMpArea( (fXmax+fXmin)/2.0, (fYmax+fYmin)/2.0 ,
143 TMath::Abs(fXmax-fXmin)/2.0, TMath::Abs(fYmax-fYmin)/2.0 );
146 //______________________________________________________________________________
148 AliMUONContour::AssertOrientation(Bool_t autoCorrect)
150 /// Insure that all our polygons are counter-clockwise oriented
151 /// If autoCorrect==kTRUE, we change the orientation if it is not
153 /// If autoCorrect==kFALSE and the orientation is not correct, we
154 /// just issue an error message.
156 for ( Int_t i = 0; i <= fPolygons->GetLast(); ++i )
158 AliMUONPolygon* pol = static_cast<AliMUONPolygon*>(fPolygons->UncheckedAt(i));
159 if ( !pol->IsCounterClockwiseOriented() )
163 pol->ReverseOrientation();
167 AliError("Got a polygon oriented the wrong way");
168 StdoutToAliError(Print(););
175 //______________________________________________________________________________
176 void AliMUONContour::Copy(TObject& obj) const
180 AliMUONContour& rhs = static_cast<AliMUONContour&>(obj);
182 delete rhs.fPolygons;
183 rhs.fPolygons = new TObjArray(fPolygons->GetLast()+1);
184 rhs.fPolygons->SetOwner(kTRUE);
185 TIter next(fPolygons);
187 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
189 rhs.fPolygons->AddLast(pol->Clone());
195 rhs.fNofVertices = fNofVertices;
198 //_____________________________________________________________________________
200 AliMUONContour::IsInside(Double_t x, Double_t y) const
202 /// Whether the point (x,y) is inside one of ours polylines
204 if ( x >= fXmin && x <= fXmax && y >= fYmin && y <= fYmax )
206 TIter next(fPolygons);
208 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
210 if ( pol->Contains(x,y) )
220 //_____________________________________________________________________________
222 AliMUONContour::Offset(Double_t x, Double_t y)
224 /// Offset all lines by a given offset
226 TIter next(fPolygons);
229 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
231 for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i )
233 pol->SetVertex(i,pol->X(i)+x,pol->Y(i)+y);
243 //_____________________________________________________________________________
245 AliMUONContour::Print(Option_t* opt) const
249 cout << GetName() << " NofVertices=" << NumberOfVertices() << " Ngroups=" << fPolygons->GetLast()+1 << endl;
252 if (sopt.Contains("B"))
257 TIter next(fPolygons);
259 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
268 //_____________________________________________________________________________
270 AliMUONContour::Transform(const TGeoHMatrix& matrix)
272 /// Transform the polygons using the given transformation
274 TIter next(fPolygons);
277 fXmin = fYmin = FLT_MAX;
278 fXmax = fYmax = -FLT_MAX;
280 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
282 for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i )
284 Double_t pl[3] = { pol->X(i), pol->Y(i), 0 };
285 Double_t pg[3] = { 0., 0., 0. };
286 matrix.LocalToMaster(pl, pg);
287 pol->SetVertex(i,pg[0],pg[1]);
288 fXmin = TMath::Min(fXmin,pg[0]);
289 fYmin = TMath::Min(fYmin,pg[1]);
290 fXmax = TMath::Max(fXmax,pg[0]);
291 fYmax = TMath::Max(fYmax,pg[1]);
295 AssertOrientation(kTRUE);
298 //_____________________________________________________________________________
300 AliMUONContour::IsValid() const
302 /// A valid contour is one with a valid area and at least 3 vertices.
303 return fNofVertices >= 3 && Area().IsValid();