source: trunk/Mars/msimreflector/MMirrorHex.cc@ 18519

Last change on this file since 18519 was 14150, checked in by tbretz, 12 years ago
Addeda hexagonal mirror rotated by 15deg
File size: 9.5 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of CheObs, the Modular 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 appears 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, 1/2009 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: CheObs Software Development, 2000-2009
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MMirrorHex
28//
29// A hexagonal spherical mirror
30//
31//////////////////////////////////////////////////////////////////////////////
32#include "MMirrorHex.h"
33
34#include <stdlib.h> // atof (Ubuntu 8.10)
35
36#include <TMath.h>
37#include <TObjArray.h>
38
39#include <TEllipse.h>
40#include <TVirtualPad.h>
41
42#include "MLog.h"
43
44#include "MHexagon.h"
45#include "MQuaternion.h"
46
47ClassImp(MMirrorHex);
48
49using namespace std;
50
51const Double_t MMirrorHex::fgCos30 = TMath::Cos(30*TMath::DegToRad());
52const Double_t MMirrorHex::fgCos60 = TMath::Cos(60*TMath::DegToRad());
53const Double_t MMirrorHex::fgSin60 = TMath::Sin(60*TMath::DegToRad());
54
55// --------------------------------------------------------------------------
56//
57// Return the aread of the hexagon: d^2*sin(60)
58//
59Double_t MMirrorHex::GetA() const
60{
61 return fD*fD*fgSin60*4;
62}
63
64// ------------------------------------------------------------------------
65//
66// This is a very rough estimate of whether a photon at a position p
67// can hit a mirror. The position might be off in z and the photon
68// still has to follow its trajectory. Nevertheless we can fairly assume
69// the the way to travel in x/y is pretty small so we can give a rather
70// good estimate of whether the photon can hit.
71//
72// never throw away a photon whihc can hit the mirror!
73//
74Bool_t MMirrorHex::CanHit(const MQuaternion &p) const
75{
76 // p is given in the reflectors coordinate frame. This is meant
77 // to be a fast check to sort out all mirrors which we can omit
78 // without time consuming calculations.
79
80 return TMath::Hypot(p.X()-X(), p.Y()-Y())<1.05*fMaxR;
81}
82
83// ------------------------------------------------------------------------
84//
85// Check if the given position coincides with the mirror. The position
86// is assumed to be the incident point on the mirror's surface.
87//
88// The coordinates are in the mirrors coordinate frame.
89//
90// The action should coincide with what is painted in Paint()
91//
92Bool_t MMirrorHex::HasHit(const MQuaternion &p) const
93{
94 // p is the incident point in the mirror in the mirror's
95 // coordinate frame
96
97 // Black spot in the mirror center (here we can fairly ignore
98 // the distance from the plane to the mirror surface, as long
99 // as the black spot does not become too large)
100 if (p.R2()<0.5*0.5)
101 return kFALSE;
102
103 //
104 // Now check if point is outside of hexagon; just check x coordinate
105 // in three coordinate systems: the default one, in which two sides of
106 // the hexagon are paralel to the y axis (see camera displays) and two
107 // more, rotated with respect to that one by +- 60 degrees.
108 //
109 if (TMath::Abs(p.X())>fD)
110 return kFALSE;
111
112 const Double_t dxc = p.X()*fgCos60;
113 const Double_t dys = p.Y()*fgSin60;
114
115 if (TMath::Abs(dxc+dys)>fD)
116 return kFALSE;
117
118 if (TMath::Abs(dxc-dys)>fD)
119 return kFALSE;
120
121 return kTRUE;
122}
123
124// ------------------------------------------------------------------------
125//
126// Paint the mirror in x/y.
127//
128// The graphic should coincide with the action in HasHit
129//
130void MMirrorHex::Paint(Option_t *opt)
131{
132 MHexagon h;
133 TEllipse e;
134 h.SetFillColor(18);
135 if (!TString(opt).Contains("line", TString::kIgnoreCase))
136 {
137 h.SetFillColor(17);
138 h.SetLineStyle(0);
139 e.SetLineStyle(0);
140 e.SetFillColor(gPad->GetFillColor());
141 }
142
143 if (TString(opt).Contains("same", TString::kIgnoreCase))
144 {
145 h.SetFillStyle(0);
146 e.SetFillStyle(0);
147 }
148
149 h.PaintHexagon(X(), Y(), fD*2);
150
151 if (!TString(opt).Contains("border", TString::kIgnoreCase))
152 e.PaintEllipse(X(), Y(), 0.5, 0.5, 0, 360, 0);
153}
154
155// ------------------------------------------------------------------------
156//
157// Print the contents of the mirror
158//
159void MMirrorHex::Print(Option_t *o) const
160{
161 MMirror::Print(o);
162 gLog << " " << fD*2 << endl;
163}
164
165// ------------------------------------------------------------------------
166//
167// Read the mirror's setup from a file. The first eight tokens should be
168// ignored. (This could be fixed!)
169//
170// Here we read: D
171//
172Int_t MMirrorHex::ReadM(const TObjArray &tok)
173{
174 if (tok.GetEntries()!=1)
175 return -1;
176
177 const Double_t d = atof(tok[0]->GetName());
178
179 if (d<=0)
180 return -1;
181
182 SetD(d);
183
184 return 1;
185}
186
187// ------------------------------------------------------------------------
188//
189void MMirrorHex::WriteM(ostream &out) const
190{
191 out << fD*2;
192}
193
194// ------------------------------------------------------------------------
195//
196// Check if the given position coincides with the mirror. The position
197// is assumed to be the incident point on the mirror's surface.
198//
199// The coordinates are in the mirrors coordinate frame.
200//
201// The action should coincide with what is painted in Paint()
202//
203Bool_t MMirrorHex15::HasHit(const MQuaternion &p) const
204{
205 // p is the incident point in the mirror in the mirror's
206 // coordinate frame
207
208 // Black spot in the mirror center (here we can fairly ignore
209 // the distance from the plane to the mirror surface, as long
210 // as the black spot does not become too large)
211// if (p.R2()<0.5*0.5)
212// return kFALSE;
213
214 static const TVector2 rot(cos(-15*TMath::DegToRad()), sin(-15*TMath::DegToRad()));
215
216 const TVector2 &v = p.XYvector();
217
218 const Double_t x = v^rot;
219 const Double_t y = v*rot;
220
221 //
222 // Now check if point is outside of hexagon; just check x coordinate
223 // in three coordinate systems: the default one, in which two sides of
224 // the hexagon are paralel to the y axis (see camera displays) and two
225 // more, rotated with respect to that one by +- 60 degrees.
226 //
227 if (TMath::Abs(x)>fD)
228 return kFALSE;
229
230 const Double_t dxc = x*fgCos60;
231 const Double_t dys = y*fgSin60;
232
233 if (TMath::Abs(dxc+dys)>fD)
234 return kFALSE;
235
236 if (TMath::Abs(dxc-dys)>fD)
237 return kFALSE;
238
239 return kTRUE;
240}
241
242// ------------------------------------------------------------------------
243//
244// Paint the mirror in x/y.
245//
246// The graphic should coincide with the action in HasHit
247//
248void MMirrorHex15::Paint(Option_t *opt)
249{
250 MHexagon h;
251 TEllipse e;
252 h.SetFillColor(18);
253 if (!TString(opt).Contains("line", TString::kIgnoreCase))
254 {
255 h.SetFillColor(17);
256 h.SetLineStyle(0);
257 e.SetLineStyle(0);
258 e.SetFillColor(gPad->GetFillColor());
259 }
260
261 if (TString(opt).Contains("same", TString::kIgnoreCase))
262 {
263 h.SetFillStyle(0);
264 e.SetFillStyle(0);
265 }
266
267 h.PaintHexagon(X(), Y(), fD*2, 15*TMath::DegToRad());
268
269 if (!TString(opt).Contains("border", TString::kIgnoreCase))
270 e.PaintEllipse(X(), Y(), 0.5, 0.5, 0, 360, 0);
271}
272
273// ------------------------------------------------------------------------
274//
275// Check if the given position coincides with the mirror. The position
276// is assumed to be the incident point on the mirror's surface.
277//
278// The coordinates are in the mirrors coordinate frame.
279//
280// The action should coincide with what is painted in Paint()
281//
282Bool_t MMirrorHex90::HasHit(const MQuaternion &p) const
283{
284 // p is the incident point in the mirror in the mirror's
285 // coordinate frame
286
287 // Black spot in the mirror center (here we can fairly ignore
288 // the distance from the plane to the mirror surface, as long
289 // as the black spot does not become too large)
290 if (p.R2()<0.5*0.5)
291 return kFALSE;
292
293 //
294 // Now check if point is outside of hexagon; just check x coordinate
295 // in three coordinate systems: the default one, in which two sides of
296 // the hexagon are parallel to the y axis (see camera displays) and two
297 // more, rotated with respect to that one by +- 60 degrees.
298 //
299 if (TMath::Abs(p.Y())>fD)
300 return kFALSE;
301
302 const Double_t dxs = p.X()*fgSin60;
303 const Double_t dyc = p.Y()*fgCos60;
304
305 if (TMath::Abs(dxs+dyc)>fD)
306 return kFALSE;
307
308 if (TMath::Abs(dxs-dyc)>fD)
309 return kFALSE;
310
311 return kTRUE;
312}
313
314// ------------------------------------------------------------------------
315//
316// Paint the mirror in x/y.
317//
318// The graphic should coincide with the action in HasHit
319//
320void MMirrorHex90::Paint(Option_t *opt)
321{
322 MHexagon h;
323 TEllipse e;
324 h.SetFillColor(18);
325 if (!TString(opt).Contains("line", TString::kIgnoreCase))
326 {
327 h.SetFillColor(17);
328 h.SetLineStyle(0);
329 e.SetLineStyle(0);
330 e.SetFillColor(gPad->GetFillColor());
331 }
332
333 if (TString(opt).Contains("same", TString::kIgnoreCase))
334 {
335 h.SetFillStyle(0);
336 e.SetFillStyle(0);
337 }
338
339 h.PaintHexagon(X(), Y(), fD*2, TMath::Pi()/2);
340
341 if (!TString(opt).Contains("border", TString::kIgnoreCase))
342 e.PaintEllipse(X(), Y(), 0.5, 0.5, 0, 360, 0);
343}
344
Note: See TracBrowser for help on using the repository browser.