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

Last change on this file since 12650 was 9947, checked in by tbretz, 14 years ago
Implemented a new mirror type MMirrorHex90 and a possibility to write a file with a relfector definition.
File size: 7.3 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 MMirrorHex90::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 //
215 // Now check if point is outside of hexagon; just check x coordinate
216 // in three coordinate systems: the default one, in which two sides of
217 // the hexagon are paralel to the y axis (see camera displays) and two
218 // more, rotated with respect to that one by +- 60 degrees.
219 //
220 if (TMath::Abs(p.Y())>fD)
221 return kFALSE;
222
223 const Double_t dxs = p.X()*fgSin60;
224 const Double_t dyc = p.Y()*fgCos60;
225
226 if (TMath::Abs(dxs+dyc)>fD)
227 return kFALSE;
228
229 if (TMath::Abs(dxs-dyc)>fD)
230 return kFALSE;
231
232 return kTRUE;
233}
234
235// ------------------------------------------------------------------------
236//
237// Paint the mirror in x/y.
238//
239// The graphic should coincide with the action in HasHit
240//
241void MMirrorHex90::Paint(Option_t *opt)
242{
243 MHexagon h;
244 TEllipse e;
245 h.SetFillColor(18);
246 if (!TString(opt).Contains("line", TString::kIgnoreCase))
247 {
248 h.SetFillColor(17);
249 h.SetLineStyle(0);
250 e.SetLineStyle(0);
251 e.SetFillColor(gPad->GetFillColor());
252 }
253
254 if (TString(opt).Contains("same", TString::kIgnoreCase))
255 {
256 h.SetFillStyle(0);
257 e.SetFillStyle(0);
258 }
259
260 h.PaintHexagon(X(), Y(), fD*2, TMath::Pi()/2);
261
262 if (!TString(opt).Contains("border", TString::kIgnoreCase))
263 e.PaintEllipse(X(), Y(), 0.5, 0.5, 0, 360, 0);
264}
Note: See TracBrowser for help on using the repository browser.