/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz, 12/2000 ! Author(s): Harald Kornmayer 1/2001 ! ! Copyright: MAGIC Software Development, 2000-2008 ! ! \* ======================================================================== */ ////////////////////////////////////////////////////////////////////////////// // // MGeomPix // // This container stores the geometry (position) information of // a single pixel together with the information about next neighbors. // // // Version 1: // ---------- // - first implementation // // Version 2: // ---------- // - added fA // // Version 3: // ---------- // - added fAidx // // Version 4: // ---------- // - added fUserBits // // // FIXME: According to an agreement we have to change the name 'Id' to 'idx' // //////////////////////////////////////////////////////////////////////////// #include "MGeomPix.h" #include #include #include "MLog.h" #include "MLogManip.h" #include "MGeomCam.h" ClassImp(MGeomPix); using namespace std; const Float_t MGeomPix::gsTan30 = TMath::Tan(30/kRad2Deg); // sqrt(3)/3 const Float_t MGeomPix::gsTan60 = TMath::Tan(60/kRad2Deg); // sqrt(3) // -------------------------------------------------------------------------- // // Initializes one pixel // MGeomPix::MGeomPix(Float_t x, Float_t y, Float_t r, UInt_t s, UInt_t a) : fUserBits(0) { // default constructor Set(x, y, r, s, a); SetNeighbors(); } // -------------------------------------------------------------------------- // // Return position as TVector2(fX, fY) // TVector2 MGeomPix::GetP() const { return TVector2(fX, fY); } // -------------------------------------------------------------------------- // // Initializes Next Neighbors. // // WARNING: This function is public, but it is not meant for user access. // It should only be used from geometry classes (like MGeomCam) // void MGeomPix::SetNeighbors(Short_t i0, Short_t i1, Short_t i2, Short_t i3, Short_t i4, Short_t i5) { fNeighbors[0] = i0; fNeighbors[1] = i1; fNeighbors[2] = i2; fNeighbors[3] = i3; fNeighbors[4] = i4; fNeighbors[5] = i5; int i; for (i=0; i<6; i++) if (fNeighbors[i]<0) break; fNumNeighbors = i; fNumNeighbors<5 ? SETBIT(fUserBits, kIsInOutermostRing) : CLRBIT(fUserBits, kIsInOutermostRing); } // -------------------------------------------------------------------------- // // Set the kIsOuterRing flag if this pixel has a outermost pixel // as Next Neighbor and don't have the kIsOutermostRing flag itself. // void MGeomPix::CheckOuterRing(const MGeomCam &cam) { if (IsInOutermostRing()) return; CLRBIT(fUserBits, kIsInOuterRing); for (int i=0; ifD/2) return kFALSE; const Double_t dy = py-fY; const static Double_t cos60 = TMath::Cos(60/kRad2Deg); const static Double_t sin60 = TMath::Sin(60/kRad2Deg); const Double_t dxc = dx*cos60; const Double_t dys = dy*sin60; if (TMath::Abs(dxc + dys)>fD/2) return kFALSE; if (TMath::Abs(dxc - dys)>fD/2) return kFALSE; return kTRUE; } // ------------------------------------------------------------------------ // // Return the direction of the pixel pix w.r.t. this pixel. // Remark: This function assumes a simple geometry. // Int_t MGeomPix::GetDirection(const MGeomPix &pix) const { const Double_t x1 = GetX(); const Double_t y1 = GetY(); const Double_t x2 = pix.GetX(); const Double_t y2 = pix.GetY(); if (x1<=x2 && y1y2) return kRightBottom; if (x1>=x2 && y1=x2 && y1>y2) return kLeftBottom; if (x1x2) return kLeft; cout << -1 << endl; return -1; } // ------------------------------------------------------------------------ // // compute the distance of a point (px,py) to the Hexagon center in world // coordinates. Return -1 if inside. // Float_t MGeomPix::DistanceToPrimitive(Float_t px, Float_t py) const { //FIXME: Rotation phi missing! static Double_t fgCos60 = 0.5; //TMath::Cos(TMath::DegToRad()*60); static Double_t fgSin60 = TMath::Sqrt(3.)/2; //TMath::Sin(TMath::DegToRad()*60); // // compute the distance of the Point to the center of the Hexagon // //const Double_t dx = px-fX; //const Double_t dy = py-fY; TVector2 v(px-fX, py-fY); // FIXME: fPhi or -fPhi? // v = v.Rotate(-fPhi); // FIXME: Replace with a precalculates sin/cos vector const Double_t dx = v.X(); const Double_t dy = v.Y(); const Double_t disthex = TMath::Sqrt(dx*dx + dy*dy); // // Now check if point is outside of hexagon; just check x coordinate // in three coordinate systems: the default one, in which two sides of // the hexagon are paralel to the y axis (see camera displays) and two // more, rotated with respect to that one by +- 60 degrees. // if (TMath::Abs(dx) > fD/2.) return disthex; const Double_t dx2 = dx*fgCos60 + dy*fgSin60; if (TMath::Abs(dx2) > fD/2.) return disthex; const Double_t dx3 = dx*fgCos60 - dy*fgSin60; if (TMath::Abs(dx3) > fD/2.) return disthex; return -1; } // ============================================================================== /* #include #include "MMath.h" #include "../mgui/MHexagon.h" // MHexagon::fgDx // ------------------------------------------------------------------------ // // Small helper class to allow fast sorting of TVector2 by angle // class HVector2 : public TVector2 { Double_t fAngle; public: HVector2() : TVector2() { } HVector2(const TVector2 &v) : TVector2(v) { } HVector2(Double_t x, Double_t y) : TVector2 (x, y) { } void CalcAngle() { fAngle = Phi(); } Bool_t IsSortable() const { return kTRUE; } Int_t Compare(const TObject *obj) const { return ((HVector2*)obj)->fAngle>fAngle ? 1 : -1; } Double_t GetAngle() const { return fAngle; } }; // ------------------------------------------------------------------------ // // Calculate the edge points of the intersection area of two hexagons. // The points are added as TVector2 to the TOrdCollection. // The user is responsible of delete the objects. // void MGeomPix::GetIntersectionBorder(TOrdCollection &col, const MGeomPix &hex) const { // if (fPhi!=0) // { // gLog << warn << "MGeomPix::GetIntersectionBorder: Only phi=0 supported yet." << endl; // return; // } Bool_t inside0[6], inside1[6]; HVector2 v0[6]; HVector2 v1[6]; Int_t cnt0=0; Int_t cnt1=0; // Calculate teh edges of each hexagon and whether this edge // is inside the other hexgon or not for (int i=0; i<6; i++) { const Double_t x0 = fX+MHexagon::fgDx[i]*fD; const Double_t y0 = fY+MHexagon::fgDy[i]*fD; const Double_t x1 = hex.fX+MHexagon::fgDx[i]*hex.fD; const Double_t y1 = hex.fY+MHexagon::fgDy[i]*hex.fD; v0[i].Set(x0, y0); v1[i].Set(x1, y1); inside0[i] = hex.DistanceToPrimitive(x0, y0) < 0; inside1[i] = DistanceToPrimitive(x1, y1) < 0; if (inside0[i]) { col.Add(new HVector2(v0[i])); cnt0++; } if (inside1[i]) { col.Add(new HVector2(v1[i])); cnt1++; } } if (cnt0==0 || cnt1==0) return; // No calculate which vorder lines intersect Bool_t iscross0[6], iscross1[6]; for (int i=0; i<6; i++) { iscross0[i] = (inside0[i] && !inside0[(i+1)%6]) || (!inside0[i] && inside0[(i+1)%6]); iscross1[i] = (inside1[i] && !inside1[(i+1)%6]) || (!inside1[i] && inside1[(i+1)%6]); } // Calculate the border points of our intersection area for (int i=0; i<6; i++) { // Skip non intersecting lines if (!iscross0[i]) continue; for (int j=0; j<6; j++) { // Skip non intersecting lines if (!iscross1[j]) continue; const TVector2 p = MMath::GetIntersectionPoint(v0[i], v0[(i+1)%6], v1[j], v1[(j+1)%6]); if (hex.DistanceToPrimitive(p.X(), p.Y())<1e-9) col.Add(new HVector2(p)); } } } // ------------------------------------------------------------------------ // // Calculate the overlapping area of the two hexagons. // Double_t MGeomPix::CalcOverlapArea(const MGeomPix &cam) const { // if (fPhi!=0) // { // gLog << warn << "MGeomPix::CalcOverlapArea: Only phi=0 supported yet." << endl; // return -1; // } TOrdCollection col; col.SetOwner(); GetIntersectionBorder(col, cam); // Check if there is an intersection to proceed with const Int_t n = col.GetEntries(); if (n==0) return 0; // Calculate the center of gravity TVector2 cog; TIter Next(&col); HVector2 *v=0; while ((v=(HVector2*)Next())) cog += *v; cog /= n; // Shift the figure to its center-og-gravity and // calculate the angle of the connection line between the // border points of our intersesction area and its cog Next.Reset(); while ((v=(HVector2*)Next())) { *v -= cog; v->CalcAngle(); } // Sort these points by this angle col.Sort(); // Now sum up the area of all the triangles between two // following points and the cog. Double_t A = 0; for (int i=0; iGetAngle()-v2->GetAngle()+TMath::TwoPi(), TMath::TwoPi()); // Length of both vectors const Double_t d1 = v1->Mod(); const Double_t d2 = v2->Mod(); A += d1*d2/2*sin(a); } return A; } */