source: trunk/MagicSoft/Mars/mgeom/MGeomPix.cc@ 9330

Last change on this file since 9330 was 9259, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 12.6 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 12/2000 <mailto:tbretz@astro.uni-wuerzburg.de>
19! Author(s): Harald Kornmayer 1/2001
20!
21! Copyright: MAGIC Software Development, 2000-2008
22!
23!
24\* ======================================================================== */
25
26//////////////////////////////////////////////////////////////////////////////
27//
28// MGeomPix
29//
30// This container stores the geometry (position) information of
31// a single pixel together with the information about next neighbors.
32//
33//
34// Version 1:
35// ----------
36// - first implementation
37//
38// Version 2:
39// ----------
40// - added fA
41//
42// Version 3:
43// ----------
44// - added fAidx
45//
46// Version 4:
47// ----------
48// - added fUserBits
49//
50//
51// FIXME: According to an agreement we have to change the name 'Id' to 'idx'
52//
53////////////////////////////////////////////////////////////////////////////
54#include "MGeomPix.h"
55
56#include <TMath.h>
57#include <TVector2.h>
58
59#include "MLog.h"
60#include "MLogManip.h"
61
62#include "MGeomCam.h"
63
64ClassImp(MGeomPix);
65
66using namespace std;
67
68const Float_t MGeomPix::gsTan30 = TMath::Tan(30/kRad2Deg); // sqrt(3)/3
69const Float_t MGeomPix::gsTan60 = TMath::Tan(60/kRad2Deg); // sqrt(3)
70
71// --------------------------------------------------------------------------
72//
73// Initializes one pixel
74//
75MGeomPix::MGeomPix(Float_t x, Float_t y, Float_t r, UInt_t s, UInt_t a) : fUserBits(0)
76{
77 // default constructor
78 Set(x, y, r, s, a);
79 SetNeighbors();
80}
81
82// --------------------------------------------------------------------------
83//
84// Return position as TVector2(fX, fY)
85//
86TVector2 MGeomPix::GetP() const
87{
88 return TVector2(fX, fY);
89}
90
91// --------------------------------------------------------------------------
92//
93// Initializes Next Neighbors.
94//
95// WARNING: This function is public, but it is not meant for user access.
96// It should only be used from geometry classes (like MGeomCam)
97//
98void MGeomPix::SetNeighbors(Short_t i0, Short_t i1, Short_t i2,
99 Short_t i3, Short_t i4, Short_t i5)
100{
101 fNeighbors[0] = i0;
102 fNeighbors[1] = i1;
103 fNeighbors[2] = i2;
104 fNeighbors[3] = i3;
105 fNeighbors[4] = i4;
106 fNeighbors[5] = i5;
107
108 int i;
109 for (i=0; i<6; i++)
110 if (fNeighbors[i]<0)
111 break;
112
113 fNumNeighbors = i;
114
115 fNumNeighbors<5 ? SETBIT(fUserBits, kIsInOutermostRing) : CLRBIT(fUserBits, kIsInOutermostRing);
116}
117
118// --------------------------------------------------------------------------
119//
120// Set the kIsOuterRing flag if this pixel has a outermost pixel
121// as Next Neighbor and don't have the kIsOutermostRing flag itself.
122//
123void MGeomPix::CheckOuterRing(const MGeomCam &cam)
124{
125 if (IsInOutermostRing())
126 return;
127
128 CLRBIT(fUserBits, kIsInOuterRing);
129
130 for (int i=0; i<fNumNeighbors; i++)
131 if (cam[fNeighbors[i]].IsInOutermostRing())
132 {
133 SETBIT(fUserBits, kIsInOuterRing);
134 return;
135 }
136}
137
138// --------------------------------------------------------------------------
139//
140// Print the geometry information of one pixel.
141//
142void MGeomPix::Print(Option_t *opt) const
143{
144 // information about a pixel
145 *fLog << all << "MPixGeom: x/y=" << fX << "/" << fY << "mm ";
146 *fLog << "d= " << fD << "mm A= " << fA << "mm² (";
147 for (int i=0; i<fNumNeighbors; i++)
148 *fLog << fNeighbors[i] << (i<fNumNeighbors-1?",":"");
149 *fLog << ")" << endl;
150}
151
152// ------------------------------------------------------------------------
153//
154// Return distance of center to coordinate origin: hypot(fX,fY)
155//
156Float_t MGeomPix::GetDist() const
157{
158 return TMath::Hypot(fX, fY);
159}
160
161// ------------------------------------------------------------------------
162//
163// Return distance of center to center of pix: hypot(fX-pix.fX,fY-pix.fY)
164//
165Float_t MGeomPix::GetDist(const MGeomPix &pix) const
166{
167 return TMath::Hypot(fX-pix.fX, fY-pix.fY);
168}
169
170// ------------------------------------------------------------------------
171//
172// Return angle defined by the center and the center of pix:
173// atan2(fX-pix.fX,fY-pix.fY)
174//
175Float_t MGeomPix::GetAngle(const MGeomPix &pix) const
176{
177 return TMath::ATan2(fX - pix.GetX(), fY - pix.GetY());
178}
179
180// ------------------------------------------------------------------------
181//
182// compute the distance of a point (px,py) to the Hexagon center in
183// MGeomPix coordinates. Return kTRUE if inside.
184//
185Bool_t MGeomPix::IsInside(Float_t px, Float_t py) const
186{
187 //
188 // compute the distance of the Point to the center of the Hexagon
189 //
190 const Double_t dx = px-fX;
191
192 //
193 // Now check if point is outside of hexagon; just check x coordinate
194 // in three coordinate systems: the default one, in which two sides of
195 // the hexagon are paralel to the y axis (see camera displays) and two
196 // more, rotated with respect to that one by +- 60 degrees.
197 //
198 if (TMath::Abs(dx)>fD/2)
199 return kFALSE;
200
201 const Double_t dy = py-fY;
202
203 const static Double_t cos60 = TMath::Cos(60/kRad2Deg);
204 const static Double_t sin60 = TMath::Sin(60/kRad2Deg);
205
206 const Double_t dxc = dx*cos60;
207 const Double_t dys = dy*sin60;
208
209 if (TMath::Abs(dxc + dys)>fD/2)
210 return kFALSE;
211
212 if (TMath::Abs(dxc - dys)>fD/2)
213 return kFALSE;
214
215 return kTRUE;
216}
217
218// ------------------------------------------------------------------------
219//
220// Return the direction of the pixel pix w.r.t. this pixel.
221// Remark: This function assumes a simple geometry.
222//
223Int_t MGeomPix::GetDirection(const MGeomPix &pix) const
224{
225 const Double_t x1 = GetX();
226 const Double_t y1 = GetY();
227
228 const Double_t x2 = pix.GetX();
229 const Double_t y2 = pix.GetY();
230
231 if (x1<=x2 && y1<y2) return kRightTop;
232 if (x1<=x2 && y1>y2) return kRightBottom;
233 if (x1>=x2 && y1<y2) return kLeftTop;
234 if (x1>=x2 && y1>y2) return kLeftBottom;
235 if (x1<x2) return kRight;
236 if (x1>x2) return kLeft;
237
238 cout << -1 << endl;
239
240 return -1;
241}
242
243// ------------------------------------------------------------------------
244//
245// compute the distance of a point (px,py) to the Hexagon center in world
246// coordinates. Return -1 if inside.
247//
248Float_t MGeomPix::DistanceToPrimitive(Float_t px, Float_t py) const
249{
250 //FIXME: Rotation phi missing!
251
252 static Double_t fgCos60 = 0.5; //TMath::Cos(TMath::DegToRad()*60);
253 static Double_t fgSin60 = TMath::Sqrt(3.)/2; //TMath::Sin(TMath::DegToRad()*60);
254
255 //
256 // compute the distance of the Point to the center of the Hexagon
257 //
258 //const Double_t dx = px-fX;
259 //const Double_t dy = py-fY;
260
261 TVector2 v(px-fX, py-fY);
262 // FIXME: fPhi or -fPhi?
263 // v = v.Rotate(-fPhi); // FIXME: Replace with a precalculates sin/cos vector
264
265 const Double_t dx = v.X();
266 const Double_t dy = v.Y();
267
268 const Double_t disthex = TMath::Sqrt(dx*dx + dy*dy);
269
270 //
271 // Now check if point is outside of hexagon; just check x coordinate
272 // in three coordinate systems: the default one, in which two sides of
273 // the hexagon are paralel to the y axis (see camera displays) and two
274 // more, rotated with respect to that one by +- 60 degrees.
275 //
276
277 if (TMath::Abs(dx) > fD/2.)
278 return disthex;
279
280 const Double_t dx2 = dx*fgCos60 + dy*fgSin60;
281
282 if (TMath::Abs(dx2) > fD/2.)
283 return disthex;
284
285 const Double_t dx3 = dx*fgCos60 - dy*fgSin60;
286
287 if (TMath::Abs(dx3) > fD/2.)
288 return disthex;
289
290 return -1;
291}
292
293// ==============================================================================
294/*
295#include <TOrdCollection.h>
296#include "MMath.h"
297#include "../mgui/MHexagon.h" // MHexagon::fgDx
298
299// ------------------------------------------------------------------------
300//
301// Small helper class to allow fast sorting of TVector2 by angle
302//
303class HVector2 : public TVector2
304{
305 Double_t fAngle;
306public:
307 HVector2() : TVector2() { }
308 HVector2(const TVector2 &v) : TVector2(v) { }
309 HVector2(Double_t x, Double_t y) : TVector2 (x, y) { }
310 void CalcAngle() { fAngle = Phi(); }
311 Bool_t IsSortable() const { return kTRUE; }
312 Int_t Compare(const TObject *obj) const { return ((HVector2*)obj)->fAngle>fAngle ? 1 : -1; }
313 Double_t GetAngle() const { return fAngle; }
314};
315
316// ------------------------------------------------------------------------
317//
318// Calculate the edge points of the intersection area of two hexagons.
319// The points are added as TVector2 to the TOrdCollection.
320// The user is responsible of delete the objects.
321//
322void MGeomPix::GetIntersectionBorder(TOrdCollection &col, const MGeomPix &hex) const
323{
324// if (fPhi!=0)
325// {
326// gLog << warn << "MGeomPix::GetIntersectionBorder: Only phi=0 supported yet." << endl;
327// return;
328// }
329
330 Bool_t inside0[6], inside1[6];
331
332 HVector2 v0[6];
333 HVector2 v1[6];
334
335 Int_t cnt0=0;
336 Int_t cnt1=0;
337
338 // Calculate teh edges of each hexagon and whether this edge
339 // is inside the other hexgon or not
340 for (int i=0; i<6; i++)
341 {
342 const Double_t x0 = fX+MHexagon::fgDx[i]*fD;
343 const Double_t y0 = fY+MHexagon::fgDy[i]*fD;
344
345 const Double_t x1 = hex.fX+MHexagon::fgDx[i]*hex.fD;
346 const Double_t y1 = hex.fY+MHexagon::fgDy[i]*hex.fD;
347
348 v0[i].Set(x0, y0);
349 v1[i].Set(x1, y1);
350
351 inside0[i] = hex.DistanceToPrimitive(x0, y0) < 0;
352 inside1[i] = DistanceToPrimitive(x1, y1) < 0;
353
354 if (inside0[i])
355 {
356 col.Add(new HVector2(v0[i]));
357 cnt0++;
358 }
359 if (inside1[i])
360 {
361 col.Add(new HVector2(v1[i]));
362 cnt1++;
363 }
364 }
365
366 if (cnt0==0 || cnt1==0)
367 return;
368
369 // No calculate which vorder lines intersect
370 Bool_t iscross0[6], iscross1[6];
371 for (int i=0; i<6; i++)
372 {
373 iscross0[i] = (inside0[i] && !inside0[(i+1)%6]) || (!inside0[i] && inside0[(i+1)%6]);
374 iscross1[i] = (inside1[i] && !inside1[(i+1)%6]) || (!inside1[i] && inside1[(i+1)%6]);
375 }
376
377 // Calculate the border points of our intersection area
378 for (int i=0; i<6; i++)
379 {
380 // Skip non intersecting lines
381 if (!iscross0[i])
382 continue;
383
384 for (int j=0; j<6; j++)
385 {
386 // Skip non intersecting lines
387 if (!iscross1[j])
388 continue;
389
390 const TVector2 p = MMath::GetIntersectionPoint(v0[i], v0[(i+1)%6], v1[j], v1[(j+1)%6]);
391 if (hex.DistanceToPrimitive(p.X(), p.Y())<1e-9)
392 col.Add(new HVector2(p));
393 }
394 }
395}
396
397// ------------------------------------------------------------------------
398//
399// Calculate the overlapping area of the two hexagons.
400//
401Double_t MGeomPix::CalcOverlapArea(const MGeomPix &cam) const
402{
403// if (fPhi!=0)
404// {
405// gLog << warn << "MGeomPix::CalcOverlapArea: Only phi=0 supported yet." << endl;
406// return -1;
407// }
408
409 TOrdCollection col;
410 col.SetOwner();
411
412 GetIntersectionBorder(col, cam);
413
414 // Check if there is an intersection to proceed with
415 const Int_t n = col.GetEntries();
416 if (n==0)
417 return 0;
418
419 // Calculate the center of gravity
420 TVector2 cog;
421
422 TIter Next(&col);
423 HVector2 *v=0;
424 while ((v=(HVector2*)Next()))
425 cog += *v;
426 cog /= n;
427
428 // Shift the figure to its center-og-gravity and
429 // calculate the angle of the connection line between the
430 // border points of our intersesction area and its cog
431 Next.Reset();
432 while ((v=(HVector2*)Next()))
433 {
434 *v -= cog;
435 v->CalcAngle();
436 }
437
438 // Sort these points by this angle
439 col.Sort();
440
441 // Now sum up the area of all the triangles between two
442 // following points and the cog.
443 Double_t A = 0;
444 for (int i=0; i<n; i++)
445 {
446 // Vectors from cog to two nearby border points
447 const HVector2 *v1 = (HVector2*)col.At(i);
448 const HVector2 *v2 = (HVector2*)col.At((i+1)%n);
449
450 // Angle between both vectors
451 const Double_t a = fmod(v1->GetAngle()-v2->GetAngle()+TMath::TwoPi(), TMath::TwoPi());
452
453 // Length of both vectors
454 const Double_t d1 = v1->Mod();
455 const Double_t d2 = v2->Mod();
456
457 A += d1*d2/2*sin(a);
458 }
459 return A;
460}
461*/
462
Note: See TracBrowser for help on using the repository browser.