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

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