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>
41 ClassImp(AliMUONContour)
44 //_____________________________________________________________________________
45 AliMUONContour::AliMUONContour(const char* name) : TNamed(name,""),
46 fPolygons(new TObjArray),
54 fPolygons->SetOwner(kTRUE);
57 //_____________________________________________________________________________
58 AliMUONContour::AliMUONContour(const char* name, const AliMpArea& area)
60 fPolygons(new TObjArray),
61 fXmin(area.LeftBorder()),
62 fXmax(area.RightBorder()),
63 fYmin(area.DownBorder()),
64 fYmax(area.UpBorder()),
68 fPolygons->SetOwner(kTRUE);
70 AliMUONPolygon* pol = new AliMUONPolygon(area.GetPositionX(),
73 area.GetDimensionY());
75 fPolygons->AddLast(pol);
77 fNofVertices = pol->NumberOfVertices();
80 //______________________________________________________________________________
81 AliMUONContour::AliMUONContour(const AliMUONContour& rhs)
92 ((AliMUONContour&)rhs).Copy(*this);
95 //______________________________________________________________________________
97 AliMUONContour::operator=(const AliMUONContour& rhs)
99 /// Assignment operator
109 //_____________________________________________________________________________
110 AliMUONContour::~AliMUONContour()
116 //_____________________________________________________________________________
118 AliMUONContour::Add(const AliMUONPolygon& polygon)
120 /// Add points from the polygon
122 for ( Int_t i = 0; i < polygon.NumberOfVertices(); ++i )
124 Double_t x = polygon.X(i);
125 Double_t y = polygon.Y(i);
126 fXmin = TMath::Min(fXmin,x);
127 fXmax = TMath::Max(fXmax,x);
128 fYmin = TMath::Min(fYmin,y);
129 fYmax = TMath::Max(fYmax,y);
132 fPolygons->AddLast(new AliMUONPolygon(polygon));
134 fNofVertices += polygon.NumberOfVertices();
137 //_____________________________________________________________________________
139 AliMUONContour::Area() const
141 /// Return the area covered by this contour (i.e. the area that
142 /// contains all the poylines)
144 return AliMpArea( (fXmax+fXmin)/2.0, (fYmax+fYmin)/2.0 ,
145 TMath::Abs(fXmax-fXmin)/2.0, TMath::Abs(fYmax-fYmin)/2.0 );
148 //______________________________________________________________________________
150 AliMUONContour::AssertOrientation(Bool_t autoCorrect)
152 /// Insure that all our polygons are counter-clockwise oriented
153 /// If autoCorrect==kTRUE, we change the orientation if it is not
155 /// If autoCorrect==kFALSE and the orientation is not correct, we
156 /// just issue an error message.
158 for ( Int_t i = 0; i <= fPolygons->GetLast(); ++i )
160 AliMUONPolygon* pol = static_cast<AliMUONPolygon*>(fPolygons->UncheckedAt(i));
161 if ( !pol->IsCounterClockwiseOriented() )
165 pol->ReverseOrientation();
169 AliError("Got a polygon oriented the wrong way");
170 StdoutToAliError(Print(););
177 //______________________________________________________________________________
178 void AliMUONContour::Copy(TObject& obj) const
182 AliMUONContour& rhs = static_cast<AliMUONContour&>(obj);
184 delete rhs.fPolygons;
185 rhs.fPolygons = new TObjArray(fPolygons->GetLast()+1);
186 rhs.fPolygons->SetOwner(kTRUE);
187 TIter next(fPolygons);
189 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
191 rhs.fPolygons->AddLast(pol->Clone());
197 rhs.fNofVertices = fNofVertices;
200 //_____________________________________________________________________________
202 AliMUONContour::IsInside(Double_t x, Double_t y) const
204 /// Whether the point (x,y) is inside one of ours polylines
206 if ( x >= fXmin && x <= fXmax && y >= fYmin && y <= fYmax )
208 TIter next(fPolygons);
210 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
212 if ( pol->Contains(x,y) )
222 //_____________________________________________________________________________
224 AliMUONContour::Offset(Double_t x, Double_t y)
226 /// Offset all lines by a given offset
228 TIter next(fPolygons);
231 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
233 for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i )
235 pol->SetVertex(i,pol->X(i)+x,pol->Y(i)+y);
245 //_____________________________________________________________________________
247 AliMUONContour::Print(Option_t* opt) const
251 cout << GetName() << " NofVertices=" << NumberOfVertices() << " Ngroups=" << fPolygons->GetLast()+1 << endl;
254 if (sopt.Contains("B"))
259 TIter next(fPolygons);
261 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
270 //_____________________________________________________________________________
272 AliMUONContour::Transform(const TGeoHMatrix& matrix)
274 /// Transform the polygons using the given transformation
276 TIter next(fPolygons);
279 fXmin = fYmin = FLT_MAX;
280 fXmax = fYmax = -FLT_MAX;
282 while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
284 for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i )
286 Double_t pl[3] = { pol->X(i), pol->Y(i), 0 };
287 Double_t pg[3] = { 0., 0., 0. };
288 matrix.LocalToMaster(pl, pg);
289 pol->SetVertex(i,pg[0],pg[1]);
290 fXmin = TMath::Min(fXmin,pg[0]);
291 fYmin = TMath::Min(fYmin,pg[1]);
292 fXmax = TMath::Max(fXmax,pg[0]);
293 fYmax = TMath::Max(fYmax,pg[1]);
297 AssertOrientation(kTRUE);
300 //_____________________________________________________________________________
302 AliMUONContour::IsValid() const
304 /// A valid contour is one with a valid area and at least 3 vertices.
305 return fNofVertices >= 3 && Area().IsValid();