Ignore:
Timestamp:
10/30/06 12:46:13 (18 years ago)
Author:
tbretz
Message:
*** empty log message ***
Location:
trunk/MagicSoft/Mars/mgui
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Mars/mgui/MHexagon.cc

    r7824 r8178  
    11/* ======================================================================== *\
     2! $Name: not supported by cvs2svn $:$Id: MHexagon.cc,v 1.30 2006-10-30 12:46:13 tbretz Exp $
     3! --------------------------------------------------------------------------
    24!
    35! *
     
    1921!   Author(s): Harald Kornmayer 1/2001
    2022!
    21 !   Copyright: MAGIC Software Development, 2000-2002
     23!   Copyright: MAGIC Software Development, 2000-2006
    2224!
    2325!
     
    2527
    2628//////////////////////////////////////////////////////////////////////////////
    27 //                                                                          //
    28 // MHexagon                                                                 //
    29 //                                                                          //
     29//
     30// MHexagon
     31//
    3032//////////////////////////////////////////////////////////////////////////////
    3133
     
    3537#include <iostream>
    3638
    37 #include <TVirtualPad.h>  // gPad
    38 
    39 #include "MGeomPix.h"     // GetX
     39#include <TVector2.h>       // TVector2
     40#include <TVirtualPad.h>    // gPad
     41#include <TOrdCollection.h> // TOrdCollection
     42
     43#include "MMath.h"
     44#include "MGeomPix.h"       // GetX
    4045
    4146ClassImp(MHexagon);
    4247
    4348using namespace std;
     49
     50const Double_t MHexagon::fgCos60 = 0.5;        // TMath::Cos(60/TMath::RadToDeg());
     51const Double_t MHexagon::fgSin60 = sqrt(3.)/2; // TMath::Sin(60/TMath::RadToDeg());
     52
     53const Double_t MHexagon::fgDx[6] = { fgCos60,   0.,          -fgCos60,  -fgCos60,   0.,            fgCos60 };
     54const Double_t MHexagon::fgDy[6] = { fgSin60/3, fgSin60*2/3, fgSin60/3, -fgSin60/3, -fgSin60*2/3, -fgSin60/3 };
    4455
    4556// ------------------------------------------------------------------------
     
    157168// coordinates. Return -1 if inside.
    158169//
    159 Float_t MHexagon::DistanceToPrimitive(Float_t px, Float_t py)
     170Float_t MHexagon::DistanceToPrimitive(Float_t px, Float_t py) const
    160171{
    161172    //
     
    176187      return disthex;
    177188
    178     const static Double_t cos60 = TMath::Cos(60/kRad2Deg);
    179     const static Double_t sin60 = TMath::Sin(60/kRad2Deg);
    180 
    181     const Double_t dx2 = dx*cos60 + dy*sin60;
     189    const Double_t dx2 = dx*fgCos60 + dy*fgSin60;
    182190
    183191    if  (TMath::Abs(dx2) > fD/2.)
    184192      return disthex;
    185193
    186     const Double_t dx3 = dx*cos60 - dy*sin60;
     194    const Double_t dx3 = dx*fgCos60 - dy*fgSin60;
    187195
    188196    if  (TMath::Abs(dx3) > fD/2.)
     
    282290void MHexagon::PaintHexagon(Float_t inX, Float_t inY, Float_t inD)
    283291{
    284     const Int_t np = 6;
    285 
    286     const Double_t dx[np+1] = { .5   , 0.    , -.5   , -.5   , 0.    ,  .5   , .5    };
    287     const Double_t dy[np+1] = { .2886,  .5772,  .2886, -.2886, -.5772, -.2886, .2886 };
    288 
    289292    //
    290293    //  calculate the positions of the pixel corners
    291294    //
    292     Double_t x[np+1], y[np+1];
    293     for (Int_t i=0; i<np+1; i++)
    294     {
    295         x[i] = inX + dx[i]*inD;
    296         y[i] = inY + dy[i]*inD;
     295    Double_t x[7], y[7];
     296    for (Int_t i=0; i<7; i++)
     297    {
     298        x[i] = inX + fgDx[i%6]*inD;
     299        y[i] = inY + fgDy[i%6]*inD;
    297300    }
    298301
     
    304307    //
    305308    if (GetFillColor())
    306         gPad->PaintFillArea(np, x, y);
     309        gPad->PaintFillArea(6, x, y);
    307310
    308311    if (GetLineStyle())
    309         gPad->PaintPolyLine(np+1, x, y);
     312        gPad->PaintPolyLine(7, x, y);
    310313}
    311314
     
    367370#endif
    368371}
     372
     373// ------------------------------------------------------------------------
     374//
     375// Small helper class to allow fast sorting of TVector2 by angle
     376//
     377class HVector2 : public TVector2
     378{
     379    Double_t fAngle;
     380public:
     381    HVector2() : TVector2()  { }
     382    HVector2(const TVector2 &v) : TVector2(v)  { }
     383    HVector2(Double_t x, Double_t y) : TVector2 (x, y) { }
     384    void CalcAngle() { fAngle = Phi(); }
     385    Bool_t IsSortable() const { return kTRUE; }
     386    Int_t Compare(const TObject *obj) const { return ((HVector2*)obj)->fAngle>fAngle ? 1 : -1; }
     387    Double_t GetAngle() const { return fAngle; }
     388};
     389
     390// ------------------------------------------------------------------------
     391//
     392// Calculate the edge points of the intersection area of two hexagons.
     393// The points are added as TVector2 to the TOrdCollection.
     394// The user is responsible of delete the objects.
     395//
     396void MHexagon::GetIntersectionBorder(TOrdCollection &col, const MHexagon &hex) const
     397{
     398    Bool_t inside0[6], inside1[6];
     399
     400    HVector2 v0[6];
     401    HVector2 v1[6];
     402
     403    Int_t cnt0=0;
     404    Int_t cnt1=0;
     405
     406    // Calculate teh edges of each hexagon and whether this edge
     407    // is inside the other hexgon or not
     408    for (int i=0; i<6; i++)
     409    {
     410        const Double_t x0 = fX+fgDx[i]*fD;
     411        const Double_t y0 = fY+fgDy[i]*fD;
     412
     413        const Double_t x1 = hex.fX+fgDx[i]*hex.fD;
     414        const Double_t y1 = hex.fY+fgDy[i]*hex.fD;
     415
     416        v0[i].Set(x0, y0);
     417        v1[i].Set(x1, y1);
     418
     419        inside0[i] = hex.DistanceToPrimitive(x0, y0) < 0;
     420        inside1[i] = DistanceToPrimitive(x1, y1)     < 0;
     421
     422        if (inside0[i])
     423        {
     424            col.Add(new HVector2(v0[i]));
     425            cnt0++;
     426        }
     427        if (inside1[i])
     428        {
     429            col.Add(new HVector2(v1[i]));
     430            cnt1++;
     431        }
     432    }
     433
     434    if (cnt0==0 || cnt1==0)
     435        return;
     436
     437    // No calculate which vorder lines intersect
     438    Bool_t iscross0[6], iscross1[6];
     439    for (int i=0; i<6; i++)
     440    {
     441        iscross0[i] = (inside0[i] && !inside0[(i+1)%6]) || (!inside0[i] && inside0[(i+1)%6]);
     442        iscross1[i] = (inside1[i] && !inside1[(i+1)%6]) || (!inside1[i] && inside1[(i+1)%6]);
     443    }
     444
     445    // Calculate the border points of our intersection area
     446    for (int i=0; i<6; i++)
     447    {
     448        // Skip non intersecting lines
     449        if (!iscross0[i])
     450            continue;
     451
     452        for (int j=0; j<6; j++)
     453        {
     454            // Skip non intersecting lines
     455            if (!iscross1[j])
     456                continue;
     457
     458            const TVector2 p = MMath::GetIntersectionPoint(v0[i], v0[(i+1)%6], v1[j], v1[(j+1)%6]);
     459            if (hex.DistanceToPrimitive(p.X(), p.Y())<1e-9)
     460                col.Add(new HVector2(p));
     461        }
     462    }
     463}
     464
     465// ------------------------------------------------------------------------
     466//
     467// Calculate the overlapping area of the two hexagons.
     468//
     469Double_t MHexagon::CalcOverlapArea(const MHexagon &cam) const
     470{
     471    TOrdCollection col;
     472    col.SetOwner();
     473
     474    GetIntersectionBorder(col, cam);
     475
     476    // Check if there is an intersection to proceed with
     477    const Int_t n = col.GetEntries();
     478    if (n==0)
     479        return 0;
     480
     481    // Calculate the center of gravity
     482    TVector2 cog;
     483
     484    TIter Next(&col);
     485    HVector2 *v=0;
     486    while ((v=(HVector2*)Next()))
     487        cog += *v;
     488    cog /= n;
     489
     490    // Shift the figure to its center-og-gravity and
     491    // calculate the angle of the connection line between the
     492    // border points of our intersesction area and its cog
     493    Next.Reset();
     494    while ((v=(HVector2*)Next()))
     495    {
     496        *v -= cog;
     497        v->CalcAngle();
     498    }
     499
     500    // Sort these points by this angle
     501    col.Sort();
     502
     503    // Now sum up the area of all the triangles between two
     504    // following points and the cog.
     505    Double_t A = 0;
     506    for (int i=0; i<n; i++)
     507    {
     508        // Vectors from cog to two nearby border points
     509        const HVector2 *v1 = (HVector2*)col.At(i);
     510        const HVector2 *v2 = (HVector2*)col.At((i+1)%n);
     511
     512        // Angle between both vectors
     513        const Double_t a = fmod(v1->GetAngle()-v2->GetAngle()+TMath::TwoPi(), TMath::TwoPi());
     514
     515        // Length of both vectors
     516        const Double_t d1 = v1->Mod();
     517        const Double_t d2 = v2->Mod();
     518
     519        A += d1*d2/2*sin(a);
     520    }
     521    return A;
     522}
  • trunk/MagicSoft/Mars/mgui/MHexagon.h

    r7823 r8178  
    2727
    2828class MGeomPix;
     29class TOrdCollection;
    2930
    3031class MHexagon : public TObject, public TAttLine, public TAttFill
    3132{
     33private:
     34    static const Double_t fgCos60;
     35    static const Double_t fgSin60;
     36
     37    static const Double_t fgDx[6];   // X coordinate of the six edges
     38    static const Double_t fgDy[6];   // Y coordinate of the six edges
     39
    3240protected:
    3341
     
    5462        return DistancetoPrimitive(px, py, 1);
    5563    }
    56     virtual Float_t DistanceToPrimitive(Float_t px, Float_t py);
     64    virtual Float_t DistanceToPrimitive(Float_t px, Float_t py) const;
    5765    virtual void  DrawHexagon(Float_t x, Float_t y, Float_t d);
    5866
     
    7078    Float_t GetD() const { return fD; }
    7179
     80    void GetIntersectionBorder(TOrdCollection &col, const MHexagon &hex) const;
     81    Double_t CalcOverlapArea(const MHexagon &cam) const;
     82
    7283    ClassDef(MHexagon, 1)    // A hexagon for MAGIC
    7384};
Note: See TracChangeset for help on using the changeset viewer.