ROOT logo
/**************************************************************************
* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
*                                                                        *
* Author: The ALICE Off-line Project.                                    *
* Contributors are mentioned in the code where appropriate.              *
*                                                                        *
* Permission to use, copy, modify and distribute this software and its   *
* documentation strictly for non-commercial purposes is hereby granted   *
* without fee, provided that the above copyright notice appears in all   *
* copies and that both the copyright notice and this permission notice   *
* appear in the supporting documentation. The authors make no claims     *
* about the suitability of this software for any purpose. It is          *
* provided "as is" without express or implied warranty.                  *
**************************************************************************/

// $Id$

///\class AliMUONContour
///
/// A contour is a set of (closed and counter-clockwise-oriented) polygons
///
/// \author Laurent Aphecetche, Subatech

#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;
///\cond CLASSIMP
ClassImp(AliMUONContour)
///\endcond

//_____________________________________________________________________________
AliMUONContour::AliMUONContour(const char* name) : TNamed(name,""), 
fPolygons(new TObjArray),
fXmin(FLT_MAX),
fXmax(-FLT_MAX),
fYmin(FLT_MAX),
fYmax(-FLT_MAX),
fNofVertices(0)
{
  /// ctor
  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)
{
  /// ctor
  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)
{
  /// Copy constructor.
  
  ((AliMUONContour&)rhs).Copy(*this);
}

//______________________________________________________________________________
AliMUONContour&
AliMUONContour::operator=(const AliMUONContour& rhs)
{
  /// Assignment operator
  if ( this != &rhs ) 
  {
    delete fPolygons;
    fPolygons = 0;
    rhs.Copy(*this);
  }
  return *this;
}

//_____________________________________________________________________________
AliMUONContour::~AliMUONContour()
{
  /// dtor
  delete fPolygons;
}

//_____________________________________________________________________________
void 
AliMUONContour::Add(const AliMUONPolygon& polygon)
{
  /// Add points from the 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 the area covered by this contour (i.e. the area that
  /// contains all the poylines)
  
  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)
{
  /// Insure that all our polygons are counter-clockwise oriented
  /// If autoCorrect==kTRUE, we change the orientation if it is not 
  /// already correct.
  /// If autoCorrect==kFALSE and the orientation is not correct, we
  /// just issue an error message.
  
  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
{
  /// Copy this to obj
  
  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
{
  /// Whether the point (x,y) is inside one of ours polylines

  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)
{
  /// Offset all lines by a given offset
  
  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
{
  /// Printout
  
  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)
{
  /// Transform the polygons using the given transformation
  
  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
{
  /// A valid contour is one with a valid area and at least 3 vertices.
  return fNofVertices >= 3 && Area().IsValid();
}
 AliMUONContour.cxx:1
 AliMUONContour.cxx:2
 AliMUONContour.cxx:3
 AliMUONContour.cxx:4
 AliMUONContour.cxx:5
 AliMUONContour.cxx:6
 AliMUONContour.cxx:7
 AliMUONContour.cxx:8
 AliMUONContour.cxx:9
 AliMUONContour.cxx:10
 AliMUONContour.cxx:11
 AliMUONContour.cxx:12
 AliMUONContour.cxx:13
 AliMUONContour.cxx:14
 AliMUONContour.cxx:15
 AliMUONContour.cxx:16
 AliMUONContour.cxx:17
 AliMUONContour.cxx:18
 AliMUONContour.cxx:19
 AliMUONContour.cxx:20
 AliMUONContour.cxx:21
 AliMUONContour.cxx:22
 AliMUONContour.cxx:23
 AliMUONContour.cxx:24
 AliMUONContour.cxx:25
 AliMUONContour.cxx:26
 AliMUONContour.cxx:27
 AliMUONContour.cxx:28
 AliMUONContour.cxx:29
 AliMUONContour.cxx:30
 AliMUONContour.cxx:31
 AliMUONContour.cxx:32
 AliMUONContour.cxx:33
 AliMUONContour.cxx:34
 AliMUONContour.cxx:35
 AliMUONContour.cxx:36
 AliMUONContour.cxx:37
 AliMUONContour.cxx:38
 AliMUONContour.cxx:39
 AliMUONContour.cxx:40
 AliMUONContour.cxx:41
 AliMUONContour.cxx:42
 AliMUONContour.cxx:43
 AliMUONContour.cxx:44
 AliMUONContour.cxx:45
 AliMUONContour.cxx:46
 AliMUONContour.cxx:47
 AliMUONContour.cxx:48
 AliMUONContour.cxx:49
 AliMUONContour.cxx:50
 AliMUONContour.cxx:51
 AliMUONContour.cxx:52
 AliMUONContour.cxx:53
 AliMUONContour.cxx:54
 AliMUONContour.cxx:55
 AliMUONContour.cxx:56
 AliMUONContour.cxx:57
 AliMUONContour.cxx:58
 AliMUONContour.cxx:59
 AliMUONContour.cxx:60
 AliMUONContour.cxx:61
 AliMUONContour.cxx:62
 AliMUONContour.cxx:63
 AliMUONContour.cxx:64
 AliMUONContour.cxx:65
 AliMUONContour.cxx:66
 AliMUONContour.cxx:67
 AliMUONContour.cxx:68
 AliMUONContour.cxx:69
 AliMUONContour.cxx:70
 AliMUONContour.cxx:71
 AliMUONContour.cxx:72
 AliMUONContour.cxx:73
 AliMUONContour.cxx:74
 AliMUONContour.cxx:75
 AliMUONContour.cxx:76
 AliMUONContour.cxx:77
 AliMUONContour.cxx:78
 AliMUONContour.cxx:79
 AliMUONContour.cxx:80
 AliMUONContour.cxx:81
 AliMUONContour.cxx:82
 AliMUONContour.cxx:83
 AliMUONContour.cxx:84
 AliMUONContour.cxx:85
 AliMUONContour.cxx:86
 AliMUONContour.cxx:87
 AliMUONContour.cxx:88
 AliMUONContour.cxx:89
 AliMUONContour.cxx:90
 AliMUONContour.cxx:91
 AliMUONContour.cxx:92
 AliMUONContour.cxx:93
 AliMUONContour.cxx:94
 AliMUONContour.cxx:95
 AliMUONContour.cxx:96
 AliMUONContour.cxx:97
 AliMUONContour.cxx:98
 AliMUONContour.cxx:99
 AliMUONContour.cxx:100
 AliMUONContour.cxx:101
 AliMUONContour.cxx:102
 AliMUONContour.cxx:103
 AliMUONContour.cxx:104
 AliMUONContour.cxx:105
 AliMUONContour.cxx:106
 AliMUONContour.cxx:107
 AliMUONContour.cxx:108
 AliMUONContour.cxx:109
 AliMUONContour.cxx:110
 AliMUONContour.cxx:111
 AliMUONContour.cxx:112
 AliMUONContour.cxx:113
 AliMUONContour.cxx:114
 AliMUONContour.cxx:115
 AliMUONContour.cxx:116
 AliMUONContour.cxx:117
 AliMUONContour.cxx:118
 AliMUONContour.cxx:119
 AliMUONContour.cxx:120
 AliMUONContour.cxx:121
 AliMUONContour.cxx:122
 AliMUONContour.cxx:123
 AliMUONContour.cxx:124
 AliMUONContour.cxx:125
 AliMUONContour.cxx:126
 AliMUONContour.cxx:127
 AliMUONContour.cxx:128
 AliMUONContour.cxx:129
 AliMUONContour.cxx:130
 AliMUONContour.cxx:131
 AliMUONContour.cxx:132
 AliMUONContour.cxx:133
 AliMUONContour.cxx:134
 AliMUONContour.cxx:135
 AliMUONContour.cxx:136
 AliMUONContour.cxx:137
 AliMUONContour.cxx:138
 AliMUONContour.cxx:139
 AliMUONContour.cxx:140
 AliMUONContour.cxx:141
 AliMUONContour.cxx:142
 AliMUONContour.cxx:143
 AliMUONContour.cxx:144
 AliMUONContour.cxx:145
 AliMUONContour.cxx:146
 AliMUONContour.cxx:147
 AliMUONContour.cxx:148
 AliMUONContour.cxx:149
 AliMUONContour.cxx:150
 AliMUONContour.cxx:151
 AliMUONContour.cxx:152
 AliMUONContour.cxx:153
 AliMUONContour.cxx:154
 AliMUONContour.cxx:155
 AliMUONContour.cxx:156
 AliMUONContour.cxx:157
 AliMUONContour.cxx:158
 AliMUONContour.cxx:159
 AliMUONContour.cxx:160
 AliMUONContour.cxx:161
 AliMUONContour.cxx:162
 AliMUONContour.cxx:163
 AliMUONContour.cxx:164
 AliMUONContour.cxx:165
 AliMUONContour.cxx:166
 AliMUONContour.cxx:167
 AliMUONContour.cxx:168
 AliMUONContour.cxx:169
 AliMUONContour.cxx:170
 AliMUONContour.cxx:171
 AliMUONContour.cxx:172
 AliMUONContour.cxx:173
 AliMUONContour.cxx:174
 AliMUONContour.cxx:175
 AliMUONContour.cxx:176
 AliMUONContour.cxx:177
 AliMUONContour.cxx:178
 AliMUONContour.cxx:179
 AliMUONContour.cxx:180
 AliMUONContour.cxx:181
 AliMUONContour.cxx:182
 AliMUONContour.cxx:183
 AliMUONContour.cxx:184
 AliMUONContour.cxx:185
 AliMUONContour.cxx:186
 AliMUONContour.cxx:187
 AliMUONContour.cxx:188
 AliMUONContour.cxx:189
 AliMUONContour.cxx:190
 AliMUONContour.cxx:191
 AliMUONContour.cxx:192
 AliMUONContour.cxx:193
 AliMUONContour.cxx:194
 AliMUONContour.cxx:195
 AliMUONContour.cxx:196
 AliMUONContour.cxx:197
 AliMUONContour.cxx:198
 AliMUONContour.cxx:199
 AliMUONContour.cxx:200
 AliMUONContour.cxx:201
 AliMUONContour.cxx:202
 AliMUONContour.cxx:203
 AliMUONContour.cxx:204
 AliMUONContour.cxx:205
 AliMUONContour.cxx:206
 AliMUONContour.cxx:207
 AliMUONContour.cxx:208
 AliMUONContour.cxx:209
 AliMUONContour.cxx:210
 AliMUONContour.cxx:211
 AliMUONContour.cxx:212
 AliMUONContour.cxx:213
 AliMUONContour.cxx:214
 AliMUONContour.cxx:215
 AliMUONContour.cxx:216
 AliMUONContour.cxx:217
 AliMUONContour.cxx:218
 AliMUONContour.cxx:219
 AliMUONContour.cxx:220
 AliMUONContour.cxx:221
 AliMUONContour.cxx:222
 AliMUONContour.cxx:223
 AliMUONContour.cxx:224
 AliMUONContour.cxx:225
 AliMUONContour.cxx:226
 AliMUONContour.cxx:227
 AliMUONContour.cxx:228
 AliMUONContour.cxx:229
 AliMUONContour.cxx:230
 AliMUONContour.cxx:231
 AliMUONContour.cxx:232
 AliMUONContour.cxx:233
 AliMUONContour.cxx:234
 AliMUONContour.cxx:235
 AliMUONContour.cxx:236
 AliMUONContour.cxx:237
 AliMUONContour.cxx:238
 AliMUONContour.cxx:239
 AliMUONContour.cxx:240
 AliMUONContour.cxx:241
 AliMUONContour.cxx:242
 AliMUONContour.cxx:243
 AliMUONContour.cxx:244
 AliMUONContour.cxx:245
 AliMUONContour.cxx:246
 AliMUONContour.cxx:247
 AliMUONContour.cxx:248
 AliMUONContour.cxx:249
 AliMUONContour.cxx:250
 AliMUONContour.cxx:251
 AliMUONContour.cxx:252
 AliMUONContour.cxx:253
 AliMUONContour.cxx:254
 AliMUONContour.cxx:255
 AliMUONContour.cxx:256
 AliMUONContour.cxx:257
 AliMUONContour.cxx:258
 AliMUONContour.cxx:259
 AliMUONContour.cxx:260
 AliMUONContour.cxx:261
 AliMUONContour.cxx:262
 AliMUONContour.cxx:263
 AliMUONContour.cxx:264
 AliMUONContour.cxx:265
 AliMUONContour.cxx:266
 AliMUONContour.cxx:267
 AliMUONContour.cxx:268
 AliMUONContour.cxx:269
 AliMUONContour.cxx:270
 AliMUONContour.cxx:271
 AliMUONContour.cxx:272
 AliMUONContour.cxx:273
 AliMUONContour.cxx:274
 AliMUONContour.cxx:275
 AliMUONContour.cxx:276
 AliMUONContour.cxx:277
 AliMUONContour.cxx:278
 AliMUONContour.cxx:279
 AliMUONContour.cxx:280
 AliMUONContour.cxx:281
 AliMUONContour.cxx:282
 AliMUONContour.cxx:283
 AliMUONContour.cxx:284
 AliMUONContour.cxx:285
 AliMUONContour.cxx:286
 AliMUONContour.cxx:287
 AliMUONContour.cxx:288
 AliMUONContour.cxx:289
 AliMUONContour.cxx:290
 AliMUONContour.cxx:291
 AliMUONContour.cxx:292
 AliMUONContour.cxx:293
 AliMUONContour.cxx:294
 AliMUONContour.cxx:295
 AliMUONContour.cxx:296
 AliMUONContour.cxx:297
 AliMUONContour.cxx:298
 AliMUONContour.cxx:299
 AliMUONContour.cxx:300
 AliMUONContour.cxx:301
 AliMUONContour.cxx:302
 AliMUONContour.cxx:303
 AliMUONContour.cxx:304
 AliMUONContour.cxx:305
 AliMUONContour.cxx:306