source: trunk/MagicSoft/Mars/mtools/MagicCivilization.cc@ 3627

Last change on this file since 3627 was 2173, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 9.4 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 07/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2002
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MagicCivilization
28// ---------
29//
30// Tool to visualize Next Neighbours.
31//
32// Start the show by:
33// MagicCivilization show;
34//
35// Use the following keys:
36// -----------------------
37//
38// * Space:
39// Toggle between auto increment and manual increment
40//
41// * Right/Left:
42// Increment/Decrement pixel number by 1
43//
44// * Right/Left:
45// Increment/Decrement pixel number by 1
46//
47// * Up/Down:
48// Increment/Decrement pixel number by 10
49//
50// * PageUp/PageDown:
51// Increment/Decrement pixel number by 100
52//
53// * Home/End:
54// Jump to first/last pixel
55//
56////////////////////////////////////////////////////////////////////////////
57#include "MagicCivilization.h"
58
59#include <iostream>
60
61#include <KeySymbols.h>
62
63#include <TCanvas.h>
64#include <TRandom.h>
65#include <TInterpreter.h>
66
67#include "MHexagon.h"
68
69#include "MGeomPix.h"
70#include "MGeomCamCT1.h"
71#include "MGeomCamMagic.h"
72
73ClassImp(MagicCivilization);
74
75using namespace std;
76
77void MagicCivilization::Free()
78{
79 if (!fGeomCam)
80 return;
81
82 fPixels->Delete();
83
84 delete fPixels;
85
86 delete fGeomCam;
87}
88
89// ------------------------------------------------------------------------
90//
91// Draw all pixels of the camera
92// (means apend all pixelobjects to the current pad)
93//
94void MagicCivilization::DrawHexagons()
95{
96 for (UInt_t i=0; i<fNumPixels; i++)
97 (*this)[i].Draw();
98}
99
100void MagicCivilization::ChangeCamera()
101{
102 static Bool_t ct1=kFALSE;
103
104 cout << "Change to " << (ct1?"Magic":"CT1") << endl;
105
106 if (ct1)
107 SetNewCamera(new MGeomCamMagic);
108 else
109 SetNewCamera(new MGeomCamCT1);
110
111 ct1 = !ct1;
112
113 DrawHexagons();
114}
115
116void MagicCivilization::SetNewCamera(MGeomCam *geom)
117{
118 Free();
119
120 //
121 // Reset the display geometry
122 //
123 fW=0;
124 fH=0;
125
126 //
127 // Set new camera
128 //
129 fGeomCam = geom;
130
131 //
132 // create the hexagons of the display
133 //
134 fNumPixels = fGeomCam->GetNumPixels();
135 fRange = fGeomCam->GetMaxRadius();
136
137 //
138 // Construct all hexagons. Use new-operator with placement
139 //
140 fPixels = new TClonesArray("MHexagon", fNumPixels);
141
142 for (UInt_t i=0; i<fNumPixels; i++)
143 {
144 MHexagon &h = *new ((*fPixels)[i]) MHexagon((*fGeomCam)[i]);
145#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
146 h.SetBit(kNoContextMenu|kCannotPick);
147#endif
148 }
149}
150
151// ------------------------------------------------------------------------
152//
153// default constructor
154//
155MagicCivilization::MagicCivilization(Byte_t lim, UShort_t init)
156 : fTimer(this, 500, kTRUE), fGeomCam(NULL), fNumInit(init), fLimit(lim), fW(0), fH(0)
157{
158 SetNewCamera(new MGeomCamMagic);
159
160 //
161 // Make sure, that the object is destroyed when the canvas/pad is
162 // destroyed. Make also sure, that the interpreter doesn't try to
163 // delete it a second time.
164 //
165 SetBit(kCanDelete);
166 gInterpreter->DeleteGlobal(this);
167
168 Draw();
169
170 fTimer.TurnOn();
171}
172
173// ------------------------------------------------------------------------
174//
175// Destructor. Deletes TClonesArrays for hexagons and legend elements.
176//
177MagicCivilization::~MagicCivilization()
178{
179 fTimer.TurnOff();
180 Free();
181
182 if (fDrawingPad->GetListOfPrimitives()->FindObject(this)==this)
183 {
184 fDrawingPad->RecursiveRemove(this);
185 delete fDrawingPad;
186 }
187}
188
189// ------------------------------------------------------------------------
190//
191// This is called at any time the canvas should get repainted.
192// Here we maintain an aspect ratio of 5/4=1.15. This makes sure,
193// that the camera image doesn't get distorted by resizing the canvas.
194//
195void MagicCivilization::Paint(Option_t *opt)
196{
197 const UInt_t w = (UInt_t)(gPad->GetWw()*gPad->GetAbsWNDC());
198 const UInt_t h = (UInt_t)(gPad->GetWh()*gPad->GetAbsHNDC());
199
200 //
201 // Check for a change in width or height, and make sure, that the
202 // first call also sets the range
203 //
204 if (w*fH == h*fW && fW && fH)
205 return;
206
207 //
208 // Calculate aspect ratio (5/4=1.25 recommended)
209 //
210 const Double_t ratio = (Double_t)w/h;
211
212 Float_t x;
213 Float_t y;
214
215 if (ratio>1.0)
216 {
217 x = fRange*(ratio*2-1);
218 y = fRange;
219 }
220 else
221 {
222 x = fRange;
223 y = fRange/ratio;
224 }
225
226 fH = h;
227 fW = w;
228
229 //
230 // Set new range
231 //
232 fDrawingPad->Range(-fRange, -y, x, y);
233}
234
235void MagicCivilization::Reset()
236{
237 if (fNumInit>=fNumPixels)
238 fNumInit = fNumPixels-1;
239 if (fNumInit<0)
240 fNumInit = 0;
241
242 if (fLimit<0)
243 fLimit=6;
244 if (fLimit>6)
245 fLimit=0;
246
247
248 TRandom rnd(0);
249 for (int i=0; i<fNumPixels; i++)
250 (*fGeomCam)[i].ResetBit(kUserBits);
251
252 for (int i=0; i<fNumInit; i++)
253 {
254 Int_t idx;
255
256 do idx = (Int_t)rnd.Uniform(fNumPixels);
257 while ((*fGeomCam)[idx].TestBit(kHasFlag));
258
259 if (idx>=fNumPixels)
260 cout << "!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
261
262 (*fGeomCam)[idx].SetBit(kHasFlag);
263 }
264
265 fAuto = kFALSE;
266 fStep = 0;
267
268 Update();
269
270 fDrawingPad->Modified();
271 fDrawingPad->Update();
272}
273
274// ------------------------------------------------------------------------
275//
276// Call this function to draw the camera layout into your canvas.
277// Setup a drawing canvas. Add this object and all child objects
278// (hexagons, etc) to the current pad. If no pad exists a new one is
279// created.
280//
281void MagicCivilization::Draw(Option_t *option)
282{
283 //
284 // if no canvas is yet existing to draw into, create a new one
285 //
286 /*TCanvas *c =*/ new TCanvas("MagicCivilization", "Magic Civilization", 0, 0, 800, 800);
287 //c->ToggleEventStatus();
288
289 fDrawingPad = gPad;
290 fDrawingPad->SetBorderMode(0);
291 fDrawingPad->SetFillColor(22);
292
293 //
294 // Append this object, so that the aspect ratio is maintained
295 // (Paint-function is called)
296 //
297 AppendPad(option);
298
299 //
300 // Reset the game pad
301 //
302 DrawHexagons();
303
304 fCivilization.SetTextAlign(23); // centered/bottom
305#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
306 fCivilization.SetBit(kNoContextMenu|kCannotPick);
307#endif
308 fCivilization.Draw();
309
310 Reset();
311}
312
313void MagicCivilization::Update()
314{
315 TString txt = "Lim: ";
316 txt += (int)fLimit;
317 txt += " Init: ";
318 txt += fNumInit;
319 txt += " On: ";
320 txt += fNumCivilizations;
321 txt += " Step: ";
322 txt += fStep;
323
324 if (!fAuto)
325 txt += " (paused)";
326
327 fCivilization.SetText(0, fRange, txt);
328}
329
330
331
332// ------------------------------------------------------------------------
333//
334// Execute a mouse event on the camera
335//
336void MagicCivilization::ExecuteEvent(Int_t event, Int_t keycode, Int_t keysym)
337{
338 if (event!=kKeyPress)
339 return;
340
341 switch (keysym)
342 {
343 default:
344 return;
345
346 case kKey_Space:
347 if ((fNumCivilizations==0 || fNumCivilizations==fNumPixels) && !fAuto)
348 Reset();
349 fAuto = !fAuto;
350 Update();
351 fDrawingPad->Update();
352 return;
353
354 case kKey_Right:
355 fNumInit += 1;;
356 break;
357
358 case kKey_Left:
359 fNumInit -= 1;
360 break;
361
362 case kKey_Up:
363 fNumInit += 10;
364 break;
365
366 case kKey_Down:
367 fNumInit -= 10;
368 break;
369
370 case kKey_PageUp:
371 fNumInit += 100;
372 break;
373
374 case kKey_PageDown:
375 fNumInit -= 100;
376 break;
377
378 case kKey_Plus:
379 fLimit++;
380 break;
381
382 case kKey_Minus:
383 fLimit--;
384 break;
385 }
386
387 Reset();
388}
389
390Bool_t MagicCivilization::HandleTimer(TTimer *timer)
391{
392 if (!fAuto)
393 return kTRUE;
394
395 for (int i=0; i<fNumPixels; i++)
396 {
397 MGeomPix &pix = (*fGeomCam)[i];
398
399 Byte_t cnt=0;
400 for (int j=0; j<pix.GetNumNeighbors(); j++)
401 if ((*fGeomCam)[pix.GetNeighbor(j)].TestBit(kHasFlag))
402 cnt++;
403
404 cnt += (6-pix.GetNumNeighbors())*cnt/6;
405
406 if (cnt>fLimit)
407 pix.SetBit(kHasCreation);
408 }
409
410 fNumCivilizations = 0;
411 for (int i=0; i<fNumPixels; i++)
412 {
413 MGeomPix &pix = (*fGeomCam)[i];
414 MHexagon &hex = (*this)[i];
415
416 if (pix.TestBit(kHasCreation))
417 {
418 pix.SetBit(kHasFlag);
419 hex.SetFillColor(kBlack);
420 fNumCivilizations++;
421 }
422 else
423 {
424 pix.ResetBit(kHasFlag);
425 hex.SetFillColor(kBackground);
426 }
427 pix.ResetBit(kHasCreation);
428 }
429
430 if (fNumCivilizations==0 || fNumCivilizations==fNumPixels)
431 fAuto = kFALSE;
432
433 fStep++;
434
435 Update();
436
437 fDrawingPad->Update();
438
439 return kTRUE;
440}
441
Note: See TracBrowser for help on using the repository browser.