#include "AliMUONContour.h"
#include "AliLog.h"
#include "AliMUONPolygon.h"
#include "AliMpArea.h"
#include <Riostream.h>
#include <TGeoMatrix.h>
#include <TMath.h>
#include <TObjArray.h>
#include <TPolyLine.h>
#include <TString.h>
#include <TVector2.h>
#include <float.h>
using std::cout;
using std::endl;
ClassImp(AliMUONContour)
AliMUONContour::AliMUONContour(const char* name) : TNamed(name,""),
fPolygons(new TObjArray),
fXmin(FLT_MAX),
fXmax(-FLT_MAX),
fYmin(FLT_MAX),
fYmax(-FLT_MAX),
fNofVertices(0)
{
fPolygons->SetOwner(kTRUE);
}
AliMUONContour::AliMUONContour(const char* name, const AliMpArea& area)
: TNamed(name,""),
fPolygons(new TObjArray),
fXmin(area.LeftBorder()),
fXmax(area.RightBorder()),
fYmin(area.DownBorder()),
fYmax(area.UpBorder()),
fNofVertices(0)
{
fPolygons->SetOwner(kTRUE);
AliMUONPolygon* pol = new AliMUONPolygon(area.GetPositionX(),
area.GetPositionY(),
area.GetDimensionX(),
area.GetDimensionY());
fPolygons->AddLast(pol);
fNofVertices = pol->NumberOfVertices();
}
AliMUONContour::AliMUONContour(const AliMUONContour& rhs)
: TNamed(rhs),
fPolygons(0x0),
fXmin(FLT_MAX),
fXmax(-FLT_MAX),
fYmin(FLT_MAX),
fYmax(-FLT_MAX),
fNofVertices(0)
{
((AliMUONContour&)rhs).Copy(*this);
}
AliMUONContour&
AliMUONContour::operator=(const AliMUONContour& rhs)
{
if ( this != &rhs )
{
delete fPolygons;
fPolygons = 0;
rhs.Copy(*this);
}
return *this;
}
AliMUONContour::~AliMUONContour()
{
delete fPolygons;
}
void
AliMUONContour::Add(const AliMUONPolygon& polygon)
{
for ( Int_t i = 0; i < polygon.NumberOfVertices(); ++i )
{
Double_t x = polygon.X(i);
Double_t y = polygon.Y(i);
fXmin = TMath::Min(fXmin,x);
fXmax = TMath::Max(fXmax,x);
fYmin = TMath::Min(fYmin,y);
fYmax = TMath::Max(fYmax,y);
}
fPolygons->AddLast(new AliMUONPolygon(polygon));
fNofVertices += polygon.NumberOfVertices();
}
AliMpArea
AliMUONContour::Area() const
{
return AliMpArea( (fXmax+fXmin)/2.0, (fYmax+fYmin)/2.0 ,
TMath::Abs(fXmax-fXmin)/2.0, TMath::Abs(fYmax-fYmin)/2.0 );
}
void
AliMUONContour::AssertOrientation(Bool_t autoCorrect)
{
for ( Int_t i = 0; i <= fPolygons->GetLast(); ++i )
{
AliMUONPolygon* pol = static_cast<AliMUONPolygon*>(fPolygons->UncheckedAt(i));
if ( !pol->IsCounterClockwiseOriented() )
{
if ( autoCorrect )
{
pol->ReverseOrientation();
}
else
{
AliError("Got a polygon oriented the wrong way");
StdoutToAliError(Print(););
return;
}
}
}
}
void AliMUONContour::Copy(TObject& obj) const
{
AliMUONContour& rhs = static_cast<AliMUONContour&>(obj);
TNamed::Copy(rhs);
delete rhs.fPolygons;
rhs.fPolygons = new TObjArray(fPolygons->GetLast()+1);
rhs.fPolygons->SetOwner(kTRUE);
TIter next(fPolygons);
AliMUONPolygon* pol;
while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
{
rhs.fPolygons->AddLast(pol->Clone());
}
rhs.fXmin = fXmin;
rhs.fXmax = fXmax;
rhs.fYmin = fYmin;
rhs.fYmax = fYmax;
rhs.fNofVertices = fNofVertices;
}
Bool_t
AliMUONContour::IsInside(Double_t x, Double_t y) const
{
if ( x >= fXmin && x <= fXmax && y >= fYmin && y <= fYmax )
{
TIter next(fPolygons);
AliMUONPolygon* pol;
while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
{
if ( pol->Contains(x,y) )
{
return kTRUE;
}
}
}
return kFALSE;
}
void
AliMUONContour::Offset(Double_t x, Double_t y)
{
TIter next(fPolygons);
AliMUONPolygon* pol;
while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
{
for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i )
{
pol->SetVertex(i,pol->X(i)+x,pol->Y(i)+y);
}
}
fXmin += x;
fXmax += x;
fYmin += y;
fYmax += y;
}
void
AliMUONContour::Print(Option_t* opt) const
{
cout << GetName() << " NofVertices=" << NumberOfVertices() << " Ngroups=" << fPolygons->GetLast()+1 << endl;
TString sopt(opt);
sopt.ToUpper();
if (sopt.Contains("B"))
{
Area().Print("B");
}
TIter next(fPolygons);
AliMUONPolygon* pol;
while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
{
pol->Print(opt);
}
cout << endl;
}
void
AliMUONContour::Transform(const TGeoHMatrix& matrix)
{
TIter next(fPolygons);
AliMUONPolygon* pol;
fXmin = fYmin = FLT_MAX;
fXmax = fYmax = -FLT_MAX;
while ( ( pol = static_cast<AliMUONPolygon*>(next()) ) )
{
for ( Int_t i = 0; i < pol->NumberOfVertices(); ++i )
{
Double_t pl[3] = { pol->X(i), pol->Y(i), 0 };
Double_t pg[3] = { 0., 0., 0. };
matrix.LocalToMaster(pl, pg);
pol->SetVertex(i,pg[0],pg[1]);
fXmin = TMath::Min(fXmin,pg[0]);
fYmin = TMath::Min(fYmin,pg[1]);
fXmax = TMath::Max(fXmax,pg[0]);
fYmax = TMath::Max(fYmax,pg[1]);
}
}
AssertOrientation(kTRUE);
}
Bool_t
AliMUONContour::IsValid() const
{
return fNofVertices >= 3 && Area().IsValid();
}