Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TGeometry.cxx
Go to the documentation of this file.
1 // @(#)root/g3d:$Id$
2 // Author: Rene Brun 22/09/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TROOT.h"
13 #include "THashList.h"
14 #include "TObjArray.h"
15 #include "TGeometry.h"
16 #include "TNode.h"
17 #include "TMaterial.h"
18 #include "TBrowser.h"
19 #include "TClass.h"
20 
21 TGeometry *gGeometry = 0;
22 
23 ClassImp(TGeometry);
24 
25 /** \class TGeometry
26 \ingroup g3d
27 TGeometry description.
28 
29 The Geometry class describes the geometry of a detector.
30 The current implementation supports the GEANT3 style description.
31 A special program provided in the ROOT utilities (toroot) can be used
32 to automatically translate a GEANT detector geometry into a ROOT geometry.
33 
34 a Geometry object is entered into the list of geometries into the
35 ROOT main object (see TROOT description) when the TGeometry
36 constructor is invoked.
37 Several geometries may coexist in memory.
38 /
39 A Geometry object consist of the following linked lists:
40 
41  - the TMaterial list (material definition only).
42  - the TRotmatrix list (Rotation matrices definition only).
43  - the TShape list (volume definition only).
44  - the TNode list assembling all detector elements.
45 
46 Only the Build and Draw functions for a geometry are currently supported.
47 
48 The conversion program from Geant to Root has been added in the list
49 of utilities in utils directory.(see g2root)
50 The executable module of g2root can be found in $ROOTSYS/bin/g2root.
51 
52 To use this conversion program, type the shell command:
53 
54 ~~~ {.cpp}
55  g2root geant_rzfile macro_name
56 ~~~
57 
58 for example
59 
60 ~~~ {.cpp}
61  g2root na49.geom na49.C
62 ~~~
63 
64 will convert the GEANT RZ file na49.geom into a ROOT macro na49.C
65 
66 To generate the Geometry structure within Root, do:
67 
68 ~~~ {.cpp}
69  Root > .x na49.C
70  Root > na49.Draw()
71  Root > wh.x3d() (this invokes the 3-d Root viewer)
72  Root > TFile gna49("na49.root","NEW") //open a new root file
73  Root > na49.Write() //Write the na49 geometry structure
74  Root > gna49.Write() //Write all keys (in this case only one)
75 ~~~
76 
77 Note: all keys are also written on closing of the file, gna49.Close or
78 when the program exits, Root closes all open files correctly.
79 Once this file has been written, in a subsequent session, simply do:
80 
81 ~~~ {.cpp}
82  Root > TFile gna49("na49.root")
83  Root > na49.Draw()
84 ~~~
85 
86 The figure below shows the geometry above using the x3d viewer.
87 This x3d viewer is invoked by selecting "View x3d" in the View menu
88 of a canvas (See example of this tool bar in TCanvas).
89 
90 \image html g3d_na49.png
91 */
92 
93 ////////////////////////////////////////////////////////////////////////////////
94 /// Geometry default constructor.
95 
96 TGeometry::TGeometry()
97 {
98  fMaterials = new THashList(100,3);
99  fMatrices = new THashList(100,3);
100  fShapes = new THashList(500,3);
101  fNodes = new TList;
102  fCurrentNode = 0;
103  fMaterialPointer = 0;
104  fMatrixPointer = 0;
105  fShapePointer = 0;
106  gGeometry = this;
107  fBomb = 1;
108  fMatrix = 0;
109  fX=fY=fZ =0.0;
110  fGeomLevel =0;
111  fIsReflection[fGeomLevel] = kFALSE;
112 }
113 
114 ////////////////////////////////////////////////////////////////////////////////
115 /// Geometry normal constructor.
116 
117 TGeometry::TGeometry(const char *name,const char *title ) : TNamed (name, title)
118 {
119  fMaterials = new THashList(1000,3);
120  fMatrices = new THashList(1000,3);
121  fShapes = new THashList(5000,3);
122  fNodes = new TList;
123  fCurrentNode = 0;
124  fMaterialPointer = 0;
125  fMatrixPointer = 0;
126  fShapePointer = 0;
127  gGeometry = this;
128  fBomb = 1;
129  fMatrix = 0;
130  fX=fY=fZ =0.0;
131  gROOT->GetListOfGeometries()->Add(this);
132  fGeomLevel =0;
133  fIsReflection[fGeomLevel] = kFALSE;
134 }
135 
136 ////////////////////////////////////////////////////////////////////////////////
137 /// copy constructor
138 
139 TGeometry::TGeometry(const TGeometry& geo) :
140  TNamed(geo),
141  fMaterials(geo.fMaterials),
142  fMatrices(geo.fMatrices),
143  fShapes(geo.fShapes),
144  fNodes(geo.fNodes),
145  fMatrix(geo.fMatrix),
146  fCurrentNode(geo.fCurrentNode),
147  fMaterialPointer(geo.fMaterialPointer),
148  fMatrixPointer(geo.fMatrixPointer),
149  fShapePointer(geo.fShapePointer),
150  fBomb(geo.fBomb),
151  fGeomLevel(geo.fGeomLevel),
152  fX(geo.fX),
153  fY(geo.fY),
154  fZ(geo.fZ)
155 {
156  for(Int_t i=0; i<kMAXLEVELS; i++) {
157  for(Int_t j=0; j<kVectorSize; j++)
158  fTranslation[i][j]=geo.fTranslation[i][j];
159  for(Int_t j=0; j<kMatrixSize; j++)
160  fRotMatrix[i][j]=geo.fRotMatrix[i][j];
161  fIsReflection[i]=geo.fIsReflection[i];
162  }
163 }
164 
165 ////////////////////////////////////////////////////////////////////////////////
166 /// assignment operator
167 
168 TGeometry& TGeometry::operator=(const TGeometry& geo)
169 {
170  if(this!=&geo) {
171  TNamed::operator=(geo);
172  fMaterials=geo.fMaterials;
173  fMatrices=geo.fMatrices;
174  fShapes=geo.fShapes;
175  fNodes=geo.fNodes;
176  fMatrix=geo.fMatrix;
177  fCurrentNode=geo.fCurrentNode;
178  fMaterialPointer=geo.fMaterialPointer;
179  fMatrixPointer=geo.fMatrixPointer;
180  fShapePointer=geo.fShapePointer;
181  fBomb=geo.fBomb;
182  fGeomLevel=geo.fGeomLevel;
183  fX=geo.fX;
184  fY=geo.fY;
185  fZ=geo.fZ;
186  for(Int_t i=0; i<kMAXLEVELS; i++) {
187  for(Int_t j=0; j<kVectorSize; j++)
188  fTranslation[i][j]=geo.fTranslation[i][j];
189  for(Int_t j=0; j<kMatrixSize; j++)
190  fRotMatrix[i][j]=geo.fRotMatrix[i][j];
191  fIsReflection[i]=geo.fIsReflection[i];
192  }
193  }
194  return *this;
195 }
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// Geometry default destructor.
199 
200 TGeometry::~TGeometry()
201 {
202  if (!fMaterials) return;
203  fMaterials->Delete();
204  fMatrices->Delete();
205  fShapes->Delete();
206  fNodes->Delete();
207  delete fMaterials;
208  delete fMatrices;
209  delete fShapes;
210  delete fNodes;
211  delete [] fMaterialPointer;
212  delete [] fMatrixPointer;
213  delete [] fShapePointer;
214  fMaterials = 0;
215  fMatrices = 0;
216  fShapes = 0;
217  fNodes = 0;
218  fMaterialPointer = 0;
219  fMatrixPointer = 0;
220  fShapePointer = 0;
221 
222  if (gGeometry == this) {
223  gGeometry = (TGeometry*) gROOT->GetListOfGeometries()->First();
224  if (gGeometry == this)
225  gGeometry = (TGeometry*) gROOT->GetListOfGeometries()->After(gGeometry);
226  }
227  gROOT->GetListOfGeometries()->Remove(this);
228 }
229 
230 ////////////////////////////////////////////////////////////////////////////////
231 /// Browse.
232 
233 void TGeometry::Browse(TBrowser *b)
234 {
235  if( b ) {
236  b->Add( fMaterials, "Materials" );
237  b->Add( fMatrices, "Rotation Matrices" );
238  b->Add( fShapes, "Shapes" );
239  b->Add( fNodes, "Nodes" );
240  }
241 }
242 
243 ////////////////////////////////////////////////////////////////////////////////
244 /// Change Current Geometry to this.
245 
246 void TGeometry::cd(const char *)
247 {
248  gGeometry = this;
249 }
250 
251 ////////////////////////////////////////////////////////////////////////////////
252 /// Draw this Geometry.
253 
254 void TGeometry::Draw(Option_t *option)
255 {
256  TNode *node1 = (TNode*)fNodes->First();
257  if (node1) node1->Draw(option);
258 
259 }
260 
261 ////////////////////////////////////////////////////////////////////////////////
262 /// Find object in a geometry node, material, etc
263 
264 TObject *TGeometry::FindObject(const TObject *) const
265 {
266  Error("FindObject","Not yet implemented");
267  return 0;
268 }
269 
270 ////////////////////////////////////////////////////////////////////////////////
271 /// Search object identified by name in the geometry tree
272 
273 TObject *TGeometry::FindObject(const char *name) const
274 {
275  TObjArray *loc = TGeometry::Get(name);
276  if (loc) return loc->At(0);
277  return 0;
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// Static function called by TROOT to search name in the geometry.
282 /// Returns a TObjArray containing a pointer to the found object
283 /// and a pointer to the container where the object was found.
284 
285 TObjArray *TGeometry::Get(const char *name)
286 {
287  static TObjArray *locs = 0;
288  if (!locs) locs = new TObjArray(2);
289  TObjArray &loc = *locs;
290  loc[0] = 0;
291  loc[1] = 0;
292 
293  if (!gGeometry) return &loc;
294 
295  TObject *temp;
296  TObject *where;
297 
298  temp = gGeometry->GetListOfMaterials()->FindObject(name);
299  where = gGeometry->GetListOfMaterials();
300 
301  if (!temp) {
302  temp = gGeometry->GetListOfShapes()->FindObject(name);
303  where = gGeometry->GetListOfShapes();
304  }
305  if (!temp) {
306  temp = gGeometry->GetListOfMatrices()->FindObject(name);
307  where = gGeometry->GetListOfMatrices();
308  }
309  if (!temp) {
310  temp = gGeometry->GetNode(name);
311  where = gGeometry;
312  }
313  loc[0] = temp;
314  loc[1] = where;
315 
316  return &loc;
317 }
318 
319 ////////////////////////////////////////////////////////////////////////////////
320 /// Return pointer to Material with name.
321 
322 TMaterial *TGeometry::GetMaterial(const char *name) const
323 {
324  return (TMaterial*)fMaterials->FindObject(name);
325 }
326 
327 ////////////////////////////////////////////////////////////////////////////////
328 /// Return pointer to Material with number.
329 
330 TMaterial *TGeometry::GetMaterialByNumber(Int_t number) const
331 {
332  TMaterial *mat;
333  if (number < 0 || number >= fMaterials->GetSize()) return 0;
334  if (fMaterialPointer) return fMaterialPointer[number];
335  TIter next(fMaterials);
336  while ((mat = (TMaterial*) next())) {
337  if (mat->GetNumber() == number) return mat;
338  }
339  return 0;
340 }
341 
342 ////////////////////////////////////////////////////////////////////////////////
343 /// Return pointer to node with name in the geometry tree.
344 
345 TNode *TGeometry::GetNode(const char *name) const
346 {
347  TNode *node= (TNode*)GetListOfNodes()->First();
348  if (!node) return 0;
349  if (node->TestBit(kNotDeleted)) return node->GetNode(name);
350  return 0;
351 }
352 
353 ////////////////////////////////////////////////////////////////////////////////
354 /// Return pointer to RotMatrix with name.
355 
356 TRotMatrix *TGeometry::GetRotMatrix(const char *name) const
357 {
358  return (TRotMatrix*)fMatrices->FindObject(name);
359 }
360 
361 ////////////////////////////////////////////////////////////////////////////////
362 /// Return pointer to RotMatrix with number.
363 
364 TRotMatrix *TGeometry::GetRotMatrixByNumber(Int_t number) const
365 {
366  TRotMatrix *matrix;
367  if (number < 0 || number >= fMatrices->GetSize()) return 0;
368  if (fMatrixPointer) return fMatrixPointer[number];
369  TIter next(fMatrices);
370  while ((matrix = (TRotMatrix*) next())) {
371  if (matrix->GetNumber() == number) return matrix;
372  }
373  return 0;
374 }
375 
376 ////////////////////////////////////////////////////////////////////////////////
377 /// Return pointer to Shape with name.
378 
379 TShape *TGeometry::GetShape(const char *name) const
380 {
381  return (TShape*)fShapes->FindObject(name);
382 }
383 
384 ////////////////////////////////////////////////////////////////////////////////
385 /// Return pointer to Shape with number.
386 
387 TShape *TGeometry::GetShapeByNumber(Int_t number) const
388 {
389  TShape *shape;
390  if (number < 0 || number >= fShapes->GetSize()) return 0;
391  if (fShapePointer) return fShapePointer[number];
392  TIter next(fShapes);
393  while ((shape = (TShape*) next())) {
394  if (shape->GetNumber() == number) return shape;
395  }
396  return 0;
397 }
398 
399 ////////////////////////////////////////////////////////////////////////////////
400 /// Convert one point from local system to master reference system.
401 ///
402 /// Note that before invoking this function, the global rotation matrix
403 /// and translation vector for this node must have been computed.
404 /// This is automatically done by the Paint functions.
405 /// Otherwise TNode::UpdateMatrix should be called before.
406 
407 void TGeometry::Local2Master(Double_t *local, Double_t *master)
408 {
409  if (GeomLevel()) {
410  Double_t x,y,z;
411  Double_t bomb = GetBomb();
412  Double_t *matrix = &fRotMatrix[GeomLevel()][0];
413  x = bomb*fX
414  + local[0]*matrix[0]
415  + local[1]*matrix[3]
416  + local[2]*matrix[6];
417 
418  y = bomb*fY
419  + local[0]*matrix[1]
420  + local[1]*matrix[4]
421  + local[2]*matrix[7];
422 
423  z = bomb*fZ
424  + local[0]*matrix[2]
425  + local[1]*matrix[5]
426  + local[2]*matrix[8];
427  master[0] = x; master[1] = y; master[2] = z;
428  }
429  else
430  for (Int_t i=0;i<3;i++) master[i] = local[i];
431 }
432 
433 ////////////////////////////////////////////////////////////////////////////////
434 /// Convert one point from local system to master reference system.
435 ///
436 /// Note that before invoking this function, the global rotation matrix
437 /// and translation vector for this node must have been computed.
438 /// This is automatically done by the Paint functions.
439 /// Otherwise TNode::UpdateMatrix should be called before.
440 
441 void TGeometry::Local2Master(Float_t *local, Float_t *master)
442 {
443  if (GeomLevel()) {
444  Float_t x,y,z;
445  Float_t bomb = GetBomb();
446 
447  Double_t *matrix = &fRotMatrix[GeomLevel()][0];
448 
449  x = bomb*fX
450  + local[0]*matrix[0]
451  + local[1]*matrix[3]
452  + local[2]*matrix[6];
453 
454  y = bomb*fY
455  + local[0]*matrix[1]
456  + local[1]*matrix[4]
457  + local[2]*matrix[7];
458 
459  z = bomb*fZ
460  + local[0]*matrix[2]
461  + local[1]*matrix[5]
462  + local[2]*matrix[8];
463 
464  master[0] = x; master[1] = y; master[2] = z;
465  }
466  else
467  for (Int_t i=0;i<3;i++) master[i] = local[i];
468 }
469 
470 ////////////////////////////////////////////////////////////////////////////////
471 /// List this geometry.
472 
473 void TGeometry::ls(Option_t *option) const
474 {
475  TString opt = option;
476  opt.ToLower();
477  if (opt.Contains("m")) {
478  Printf("=================List of Materials================");
479  fMaterials->ls(option);
480  }
481  if (opt.Contains("r")) {
482  Printf("=================List of RotationMatrices================");
483  fMatrices->ls(option);
484  }
485  if (opt.Contains("s")) {
486  Printf("=================List of Shapes==========================");
487  fShapes->ls(option);
488  }
489  if (opt.Contains("n")) {
490  Printf("=================List of Nodes===========================");
491  fNodes->ls(option);
492  }
493 }
494 
495 ////////////////////////////////////////////////////////////////////////////////
496 /// Convert one point from master system to local reference system.
497 ///
498 /// Note that before invoking this function, the global rotation matrix
499 /// and translation vector for this node must have been computed.
500 /// This is automatically done by the Paint functions.
501 /// Otherwise TNode::UpdateMatrix should be called before.
502 
503 void TGeometry::Master2Local(Double_t *master, Double_t *local)
504 {
505  if (GeomLevel()) {
506  Double_t x,y,z;
507  Double_t bomb = GetBomb();
508  Double_t *matrix = &fRotMatrix[GeomLevel()][0];
509 
510  Double_t xms = master[0] - bomb*fX;
511  Double_t yms = master[1] - bomb*fY;
512  Double_t zms = master[2] - bomb*fZ;
513 
514  x = xms*matrix[0] + yms*matrix[1] + zms*matrix[2];
515  y = xms*matrix[3] + yms*matrix[4] + zms*matrix[5];
516  z = xms*matrix[6] + yms*matrix[7] + zms*matrix[8];
517 
518  local[0] = x; local[1] = y; local[2] = z;
519  }
520  else
521  memcpy(local,master,sizeof(Double_t)* kVectorSize);
522 }
523 
524 ////////////////////////////////////////////////////////////////////////////////
525 /// Convert one point from master system to local reference system.
526 ///
527 /// Note that before invoking this function, the global rotation matrix
528 /// and translation vector for this node must have been computed.
529 /// This is automatically done by the Paint functions.
530 /// Otherwise TNode::UpdateMatrix should be called before.
531 
532 void TGeometry::Master2Local(Float_t *master, Float_t *local)
533 {
534  if (GeomLevel()) {
535  Float_t x,y,z;
536  Float_t bomb = GetBomb();
537 
538  Double_t *matrix = &fRotMatrix[GeomLevel()][0];
539 
540  Double_t xms = master[0] - bomb*fX;
541  Double_t yms = master[1] - bomb*fY;
542  Double_t zms = master[2] - bomb*fZ;
543 
544  x = xms*matrix[0] + yms*matrix[1] + zms*matrix[2];
545  y = xms*matrix[3] + yms*matrix[4] + zms*matrix[5];
546  z = xms*matrix[6] + yms*matrix[7] + zms*matrix[8];
547 
548  local[0] = x; local[1] = y; local[2] = z;
549  }
550  else
551  memcpy(local,master,sizeof(Float_t)* kVectorSize);
552 }
553 
554 ////////////////////////////////////////////////////////////////////////////////
555 /// Add a node to the current node in this geometry.
556 
557 void TGeometry::Node(const char *name, const char *title, const char *shapename, Double_t x, Double_t y, Double_t z, const char *matrixname, Option_t *option)
558 {
559  new TNode(name,title,shapename,x,y,z,matrixname,option);
560 }
561 
562 ////////////////////////////////////////////////////////////////////////////////
563 /// Recursively remove object from a Geometry list.
564 
565 void TGeometry::RecursiveRemove(TObject *obj)
566 {
567  if (fNodes) fNodes->RecursiveRemove(obj);
568 }
569 
570 ////////////////////////////////////////////////////////////////////////////////
571 /// Stream a class object.
572 
573 void TGeometry::Streamer(TBuffer &b)
574 {
575  if (b.IsReading()) {
576  UInt_t R__s, R__c;
577  Version_t R__v = b.ReadVersion(&R__s, &R__c);
578  if (R__v > 1) {
579  b.ReadClassBuffer(TGeometry::Class(), this, R__v, R__s, R__c);
580  } else {
581  //====process old versions before automatic schema evolution
582  TNamed::Streamer(b);
583  fMaterials->Streamer(b);
584  fMatrices->Streamer(b);
585  fShapes->Streamer(b);
586  fNodes->Streamer(b);
587  b >> fBomb;
588  b.CheckByteCount(R__s, R__c, TGeometry::IsA());
589  //====end of old versions
590  }
591  // Build direct access pointers to individual materials,matrices and shapes
592  Int_t i;
593  TMaterial *onemat;
594  TRotMatrix *onematrix;
595  TShape *oneshape;
596  Int_t nmat = fMaterials->GetSize();
597  if (nmat) fMaterialPointer = new TMaterial* [nmat];
598  TIter nextmat(fMaterials);
599  i = 0;
600  while ((onemat = (TMaterial*) nextmat())) {
601  fMaterialPointer[i] = onemat;
602  i++;
603  }
604 
605  Int_t nrot = fMatrices->GetSize();
606  if (nrot) fMatrixPointer = new TRotMatrix* [nrot];
607  TIter nextmatrix(fMatrices);
608  i = 0;
609  while ((onematrix = (TRotMatrix*) nextmatrix())) {
610  fMatrixPointer[i] = onematrix;
611  i++;
612  }
613 
614  Int_t nsha = fShapes->GetSize();
615  if (nsha) fShapePointer = new TShape* [nsha];
616  TIter nextshape(fShapes);
617  i = 0;
618  while ((oneshape = (TShape*) nextshape())) {
619  fShapePointer[i] = oneshape;
620  i++;
621  }
622 
623  gROOT->GetListOfGeometries()->Add(this);
624 
625  fCurrentNode = (TNode*)GetListOfNodes()->First();
626  } else {
627  b.WriteClassBuffer(TGeometry::Class(),this);
628  }
629 }
630 
631 ////////////////////////////////////////////////////////////////////////////////
632 /// Update global rotation matrix/translation vector for this node
633 /// this function must be called before invoking Local2Master
634 
635 void TGeometry::UpdateMatrix(TNode *node)
636 {
637  TNode *nodes[kMAXLEVELS];
638  for (Int_t i=0;i<kVectorSize;i++) fTranslation[0][i] = 0;
639  for (Int_t i=0;i<kMatrixSize;i++) fRotMatrix[0][i] = 0;
640  fRotMatrix[0][0] = 1; fRotMatrix[0][4] = 1; fRotMatrix[0][8] = 1;
641 
642  fGeomLevel = 0;
643  //build array of parent nodes
644  while (node) {
645  nodes[fGeomLevel] = node;
646  node = node->GetParent();
647  fGeomLevel++;
648  }
649  fGeomLevel--;
650  Int_t saveGeomLevel = fGeomLevel;
651  //Update matrices in the hierarchy
652  for (fGeomLevel=1;fGeomLevel<=saveGeomLevel;fGeomLevel++) {
653  node = nodes[fGeomLevel-1];
654  UpdateTempMatrix(node->GetX(),node->GetY(),node->GetZ(),node->GetMatrix());
655  }
656 }
657 
658 ////////////////////////////////////////////////////////////////////////////////
659 /// Update temp matrix.
660 
661 void TGeometry::UpdateTempMatrix(Double_t x, Double_t y, Double_t z, TRotMatrix *rotMatrix)
662 {
663  Double_t *matrix = 0;
664  Bool_t isReflection = kFALSE;
665  if (rotMatrix && rotMatrix->GetType()) {
666  matrix = rotMatrix->GetMatrix();
667  isReflection = rotMatrix->IsReflection();
668  }
669  UpdateTempMatrix( x,y,z, matrix,isReflection);
670 }
671 
672 ////////////////////////////////////////////////////////////////////////////////
673 /// Update temp matrix.
674 
675 void TGeometry::UpdateTempMatrix(Double_t x, Double_t y, Double_t z, Double_t *matrix,Bool_t isReflection)
676 {
677  Int_t i=GeomLevel();
678  if (i) {
679  if(matrix) {
680  UpdateTempMatrix(&(fTranslation[i-1][0]),&fRotMatrix[i-1][0]
681  ,x,y,z,matrix
682  ,&fTranslation[i][0],&fRotMatrix[i][0]);
683  fX = fTranslation[i][0];
684  fY = fTranslation[i][1];
685  fZ = fTranslation[i][2];
686  fIsReflection[i] = fIsReflection[i-1] ^ isReflection;
687  } else {
688  fX = fTranslation[i][0] = fTranslation[i-1][0] + x;
689  fY = fTranslation[i][1] = fTranslation[i-1][1] + y;
690  fZ = fTranslation[i][2] = fTranslation[i-1][2] + z;
691  }
692  } else {
693  fX=fY=fZ=0;
694  fIsReflection[0] = kFALSE;
695  for (i=0;i<kVectorSize;i++) fTranslation[0][i] = 0;
696  for (i=0;i<kMatrixSize;i++) fRotMatrix[0][i] = 0;
697  fRotMatrix[0][0] = 1; fRotMatrix[0][4] = 1; fRotMatrix[0][8] = 1;
698  }
699 }
700 
701 ////////////////////////////////////////////////////////////////////////////////
702 /// Compute new translation vector and global matrix.
703 ///
704 /// - dx old translation vector
705 /// - rmat old global matrix
706 /// - x,y,z offset of new local system with respect to mother
707 /// - dxnew new translation vector
708 /// - rmatnew new global rotation matrix
709 
710 void TGeometry::UpdateTempMatrix(Double_t *dx,Double_t *rmat
711  , Double_t x, Double_t y, Double_t z, Double_t *matrix
712  , Double_t *dxnew, Double_t *rmatnew)
713 {
714  dxnew[0] = dx[0] + x*rmat[0] + y*rmat[3] + z*rmat[6];
715  dxnew[1] = dx[1] + x*rmat[1] + y*rmat[4] + z*rmat[7];
716  dxnew[2] = dx[2] + x*rmat[2] + y*rmat[5] + z*rmat[8];
717 
718  rmatnew[0] = rmat[0]*matrix[0] + rmat[3]*matrix[1] + rmat[6]*matrix[2];
719  rmatnew[1] = rmat[1]*matrix[0] + rmat[4]*matrix[1] + rmat[7]*matrix[2];
720  rmatnew[2] = rmat[2]*matrix[0] + rmat[5]*matrix[1] + rmat[8]*matrix[2];
721  rmatnew[3] = rmat[0]*matrix[3] + rmat[3]*matrix[4] + rmat[6]*matrix[5];
722  rmatnew[4] = rmat[1]*matrix[3] + rmat[4]*matrix[4] + rmat[7]*matrix[5];
723  rmatnew[5] = rmat[2]*matrix[3] + rmat[5]*matrix[4] + rmat[8]*matrix[5];
724  rmatnew[6] = rmat[0]*matrix[6] + rmat[3]*matrix[7] + rmat[6]*matrix[8];
725  rmatnew[7] = rmat[1]*matrix[6] + rmat[4]*matrix[7] + rmat[7]*matrix[8];
726  rmatnew[8] = rmat[2]*matrix[6] + rmat[5]*matrix[7] + rmat[8]*matrix[8];
727 }