]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSv11Geometry.cxx
Print removed
[u/mrichter/AliRoot.git] / ITS / AliITSv11Geometry.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17  $Id$ 
18 */
19
20
21 ////////////////////////////////////////////////////////////////////////
22 //  This class is a base class for the ITS geometry version 11. It 
23 //  contains common/standard functions used in many places in defining 
24 //  the ITS geometry, version 11. Large posions of the ITS geometry, 
25 //  version 11, should be derived from this class so as to make maximum 
26 //  use of these common functions. This class also defines the proper 
27 //  conversion valuse such, to cm and degrees, such that the most usefull 
28 //  units, those used in the Engineering drawings, can be used.
29 ////////////////////////////////////////////////////////////////////////
30
31
32 #include <Riostream.h>
33 #include <TMath.h>
34 #include <TArc.h>
35 #include <TLine.h>
36 #include <TArrow.h>
37 #include <TCanvas.h>
38 #include <TText.h>
39 #include <TObjArray.h>
40 #include <TMatrixD.h>
41 #include <TArrayD.h>
42 #include <TArrayI.h>
43 #include <TGeoPcon.h>
44 #include <TGeoCone.h>
45 #include <TGeoTube.h> // contaings TGeoTubeSeg
46 #include <TGeoArb8.h>
47 #include <TGeoMaterial.h>
48 #include <TPolyMarker.h>
49 #include <TPolyLine.h>
50 #include "AliITSv11Geometry.h"
51
52 ClassImp(AliITSv11Geometry)
53
54 const Double_t AliITSv11Geometry::fgkmicron = 1.0E-4;
55 const Double_t AliITSv11Geometry::fgkmm = 0.10;
56 const Double_t AliITSv11Geometry::fgkcm = 1.00;
57 const Double_t AliITSv11Geometry::fgkDegree = 1.0;
58 const Double_t AliITSv11Geometry::fgkRadian = 180./3.14159265358979323846;
59
60 //----------------------------------------------------------------------
61 TGeoMixture * AliITSv11Geometry::CreateMixtureByVolume(const char* name,
62                                  Int_t nel,const TArrayD *v,
63                                  const TObjArray *mix,Double_t den){
64     // Create a new TGeoMixture object based on a TObject array of
65     // TGeoMixture/TGeoMaterials and their releative weight volume. For 
66     // example, Consider TGeoMixture of 
67     // Inputs:
68     //    const char*     name Name of the new TGeoMixture
69     //          Int_t     nel  The number of enteries
70     //    const TArrayD   *v   Array of releative volume of each mixture
71     //    const TObjArray *mix TObjArray holding the TGeoMixtures or 
72     //                         TGeoMaterials which make up this new mixture.
73     //          Double_t   den The density of this new mixture [g/cm^3].
74     // Output:
75     //    none.
76     // Retrun:
77     //    A pointer to a new instance of a TGeoMixture.
78     Int_t i;
79     TArrayD w(nel);
80
81     for(i=0;i<nel;i++) if(v->At(i)>=0.0){
82         w[i] = v->At(i) * ((TGeoMaterial*)(mix->At(i)))->GetDensity();
83     }else{
84         w[i] = 0.0;
85     } // end if/for i
86     return CreateMixtureByWeight(name,nel,&w,mix,den);
87 }
88 //______________________________________________________________________
89 TGeoMixture * AliITSv11Geometry::CreateMixtureByNumber(const char* name,
90                                  Int_t nel,const TArrayI *w,
91                                  const TObjArray *mix,Double_t den){
92     // Create a new TGeoMixture object based on a TObject array of
93     // TGeoMixture/TGeoMaterials and their releative number. For example,
94     // Consider TGeoMixture of BGO (Bi_2O_3)_2(GeO_2)_3. Assume you have
95     // defined Bismuth Oxide as Bi_2O_3 as one TGeoMixture ("Bi2O3") and 
96     // Germainium Oxide as another ("GeO2"), then BGO is defined at
97     // CreateMixtureByNumber("BGO",2,TArrayI(2,3),
98     // TObjArray(TGeoMixture("Bi2O3"),TGeoMixture("GeO2")));
99     // Inputs:
100     //    const char* name     Name of the new TGeoMixture
101     //          Int_t nel      The number of enteries
102     //    const TArrayI *w     Array of releative number of each mixture
103     //    const TObjArray *mix TObjArray holding the TGeoMixtures or 
104     //                         TGeoMaterials which make up this new mixture.
105     //          Double_t   den The density of this new mixture [g/cm^3].
106     // Output:
107     //    none.
108     // Retrun:
109     //    A pointer to a new instance of a TGeoMixture.
110     Int_t i,j;
111     Double_t a;
112     TArrayD wa;
113     TGeoMixture *mi;
114     TGeoMaterial *ma;
115
116     wa.Set(nel);
117     wa.Reset();
118     for(i=0;i<nel;i++) if(w->At(i)>0){
119         mi = dynamic_cast<TGeoMixture*>(mix->At(i));
120         if(mi!=0){ // Mixture
121             a = 0.0;
122             for(j=0;j<mi->GetNelements();j++) a+= mi->GetZmixt()[j];
123             wa[i] =  ((Double_t)(w->At(i)))*a/((Double_t)(mi->GetNelements()));
124         }else{ // Material
125             ma = dynamic_cast<TGeoMaterial*>(mix->At(i));
126             if(ma==0) continue; // don't know what this is.
127             wa[i] = ((Double_t)(w->At(i)))*ma->GetA();
128         } // end if
129     } // end if/for i
130
131     return CreateMixtureByWeight(name,nel,&wa,mix,den);
132 }
133 //----------------------------------------------------------------------
134 TGeoMixture * AliITSv11Geometry::CreateMixtureByWeight(const char* name,
135                                  Int_t nel,const TArrayD *w,
136                                  const TObjArray *mix,Double_t den){
137     // Create a new TGeoMixture object based on a TObject array of
138     // TGeoMixture/TGeoMaterials and their releative weight. For example,
139     // Consider TGeoMixture of "standard shielding blocks" 52% O_2, 32.5% Si,
140     // 6% Ca, 1.5% Na, 2% Fe, and 4% Al.
141     // Inputs:
142     //    const char* name     Name of the new TGeoMixture
143     //          Int_t nel      The number of enteries
144     //    const TArrayD *w     Array of releative Weights of each mixture
145     //    const TObjArray *mix TObjArray holding the TGeoMixtures or 
146     //                         TGeoMaterials which make up this new mixture.
147     //          Double_t   den The density of this new mixture [g/cm^3].
148     // Output:
149     //    none.
150     // Retrun:
151     //    A pointer to a new instance of a TGeoMixture.
152     Int_t i,j,k,n=0;
153     Double_t s=0.0;
154     TArrayD za,aa,wa;
155     TGeoMixture *mi,*mixnew;
156     TGeoMaterial *ma;
157     Bool_t add=kTRUE;
158
159     for(i=0;i<nel;i++) if(w->At(i)>0){
160         mi = dynamic_cast<TGeoMixture*>(mix->At(i));
161         if(mi!=0){
162             for(j=0;j<mi->GetNelements();j++) n++;
163         }else{
164             ma = dynamic_cast<TGeoMaterial*>(mix->At(i));
165             if(ma==0) continue; // don't know what this is.
166             n++;
167         } // end if
168         s += w->At(i);
169     } // end for i
170     if(n<=0) return 0; // No elements found.
171     za.Set(n); za.Reset();
172     aa.Set(n); aa.Reset();
173     wa.Set(n); wa.Reset();
174     TMatrixD wb(n,nel); wb.Zero();
175     //
176     n = 0; // Now use for the number of enteries.
177     for(i=0;i<nel;i++) {
178         for(j=0;j<n;j++) wb(j,i) = 0.0; // zero out array
179         if(w->At(i)>0){
180             mi = dynamic_cast<TGeoMixture*>(mix->At(i));
181             if(mi!=0){
182                 for(j=0;j<mi->GetNelements();j++){
183                     for(k=0;k<n;k++){
184                         if(za.At(k)==mi->GetZmixt()[j] && 
185                            aa.At(k)==mi->GetAmixt()[j]){
186                             add = kFALSE;
187                             wb(k,i) = mi->GetWmixt()[j] * w->At(i)/s;
188                             continue;
189                         } // end if
190                         if(add){
191                             za[n]   = mi->GetZmixt()[j];
192                             aa[n]   = mi->GetAmixt()[j];
193                             wb(n,i) = mi->GetWmixt()[j] * w->At(i)/s;
194                             n++;
195                         } // end if
196                         add = kTRUE;
197                     } // end for k
198                 } // end for j
199             }else{
200                 ma = dynamic_cast<TGeoMaterial*>(mix->At(i));
201                 if(ma==0) continue; // don't know what this is.
202                 for(k=0;k<n;k++){
203                     if(za.At(k)==ma->GetZ() && aa.At(k)==ma->GetA()){
204                         add = kFALSE;
205                         wb(k,i) = w->At(i)/s;
206                         continue;
207                     } // end if
208                     if(add){
209                         za[n] = ma->GetZ();
210                         aa[n] = ma->GetA();
211                         wb(n,i) = w->At(i)/s;
212                         n++;
213                     } // end if
214                     add = kTRUE;
215                 } // end for k
216             } // end if
217         } // end if
218     } // end for i
219     mixnew = new TGeoMixture(name,n,den);
220     k = 0;
221     for(i=0;i<n;i++) {
222         for(j=0;j<nel;j++) wa.AddAt(wb(i,j),i);
223         if(wa.At(i)<=0.0) continue;
224         mixnew->DefineElement(k++,aa.At(i),za.At(i),wa.At(i));
225     } // end for i
226     //
227     return mixnew;
228 }
229 //______________________________________________________________________
230 Double_t AliITSv11Geometry::Yfrom2Points(Double_t x0,Double_t y0,
231                                          Double_t x1,Double_t y1,
232                                          Double_t x)const{
233     // Given the two points (x0,y0) and (x1,y1) and the location x, returns
234     // the value y corresponding to that point x on the line defined by the
235     // two points.
236     // Inputs:
237     //    Double_t  x0  The first x value defining the line
238     //    Double_t  y0  The first y value defining the line
239     //    Double_t  x1  The second x value defining the line
240     //    Double_t  y1  The second y value defining the line
241     //    Double_t   x  The x value for which the y value is wanted.
242     // Outputs:
243     //    none.
244     // Return:
245     //    The value y corresponding to the point x on the line defined by
246     //    the two points (x0,y0) and (x1,y1).
247
248     if(x0==x1 && y0==y1) {
249         printf("Error: AliITSv11Geometry::Yfrom2Ponts The two points are "
250                "the same (%e,%e) and (%e,%e)",x0,y0,x1,y1);
251         return 0.0;
252     } // end if
253     if(x0==x1){
254         printf("Warning: AliITSv11Geometry::Yfrom2Points x0=%e == x1=%e. "
255                "line vertical ""returning mean y",x0,x1);
256         return 0.5*(y0+y1);
257     }// end if x0==x1
258     Double_t m = (y0-y1)/(x0-x1);
259     return m*(x-x0)+y0;
260 }
261 //______________________________________________________________________
262 Double_t AliITSv11Geometry::Xfrom2Points(Double_t x0,Double_t y0,
263                                          Double_t x1,Double_t y1,
264                                          Double_t y)const{
265     // Given the two points (x0,y0) and (x1,y1) and the location y, returns
266     // the value x corresponding to that point y on the line defined by the
267     // two points.
268     // Inputs:
269     //    Double_t  x0  The first x value defining the line
270     //    Double_t  y0  The first y value defining the line
271     //    Double_t  x1  The second x value defining the line
272     //    Double_t  y1  The second y value defining the line
273     //    Double_t   y  The y value for which the x value is wanted.
274     // Outputs:
275     //    none.
276     // Return:
277     //    The value x corresponding to the point y on the line defined by
278     //    the two points (x0,y0) and (x1,y1).
279
280     if(x0==x1 && y0==y1) {
281         printf("Error: AliITSv11Geometry::Yfrom2Ponts The two points are "
282                "the same (%e,%e) and (%e,%e)",x0,y0,x1,y1);
283         return 0.0;
284     } // end if
285     if(y0==y1){
286         printf("Warrning: AliITSv11Geometry::Yfrom2Points y0=%e == y1=%e. "
287                "line horizontal returning mean x",y0,y1);
288         return 0.5*(x0+x1);
289     }// end if y0==y1
290     Double_t m = (x0-x1)/(y0-y1);
291     return m*(y-y0)+x0;
292 }
293 //______________________________________________________________________
294 Double_t AliITSv11Geometry::RmaxFrom2Points(const TGeoPcon *p,Int_t i1,
295                                             Int_t i2,Double_t z)const{
296     // functions Require at parts of Volume A to be already defined.
297     // Retruns the value of Rmax corresponding to point z alone the line
298     // defined by the two points p.Rmax(i1),p-GetZ(i1) and p->GetRmax(i2),
299     // p->GetZ(i2).
300     // Inputs:
301     //    TGeoPcon *p  The Polycone where the two points come from
302     //    Int_t    i1  Point 1
303     //    Int_t    i2  Point 2
304     //    Double_t  z  The value of z for which Rmax is to be found
305     // Outputs:
306     //    none.
307     // Return:
308     //    Double_t Rmax the value corresponding to z
309     Double_t d0,d1,d2,r;
310
311     d0 = p->GetRmax(i1)-p->GetRmax(i2);// cout <<"L263: d0="<<d0<<endl;
312     d1 = z-p->GetZ(i2);// cout <<"L264: d1="<<d1<<endl;
313     d2 = p->GetZ(i1)-p->GetZ(i2);// cout <<"L265: d2="<<d2<<endl;
314     r  = p->GetRmax(i2) + d1*d0/d2;// cout <<"L266: r="<<r<<endl;
315     return r;
316 }
317 //______________________________________________________________________
318 Double_t AliITSv11Geometry::RminFrom2Points(const TGeoPcon *p,Int_t i1,
319                                             Int_t i2,Double_t z)const{
320     // Retruns the value of Rmin corresponding to point z alone the line
321     // defined by the two points p->GetRmin(i1),p->GetZ(i1) and 
322     // p->GetRmin(i2),  p->GetZ(i2).
323     // Inputs:
324     //    TGeoPcon *p  The Polycone where the two points come from
325     //    Int_t    i1  Point 1
326     //    Int_t    i2  Point 2
327     //    Double_t  z  The value of z for which Rmax is to be found
328     // Outputs:
329     //    none.
330     // Return:
331     //    Double_t Rmax the value corresponding to z
332
333     return p->GetRmin(i2)+(p->GetRmin(i1)-p->GetRmin(i2))*(z-p->GetZ(i2))/
334      (p->GetZ(i1)-p->GetZ(i2));
335 }
336 //______________________________________________________________________
337 Double_t AliITSv11Geometry::RFrom2Points(const Double_t *p,const Double_t *az,
338                                          Int_t i1,Int_t i2,Double_t z)const{
339     // Retruns the value of Rmin corresponding to point z alone the line
340     // defined by the two points p->GetRmin(i1),p->GetZ(i1) and 
341     // p->GetRmin(i2), p->GetZ(i2).
342     // Inputs:
343     //    Double_t az  Array of z values
344     //    Double_t  r  Array of r values
345     //    Int_t    i1  First Point in arrays
346     //    Int_t    i2  Second Point in arrays
347     //    Double_t z   Value z at which r is to be found
348     // Outputs:
349     //    none.
350     // Return:
351     //    The value r corresponding to z and the line defined by the two points
352
353     return p[i2]+(p[i1]-p[i2])*(z-az[i2])/(az[i1]-az[i2]);
354 }
355 //______________________________________________________________________
356 Double_t AliITSv11Geometry::Zfrom2MinPoints(const TGeoPcon *p,Int_t i1,
357                                             Int_t i2,Double_t r)const{
358     // Retruns the value of Z corresponding to point R alone the line
359     // defined by the two points p->GetRmin(i1),p->GetZ(i1) and 
360     // p->GetRmin(i2),p->GetZ(i2)
361     // Inputs:
362     //    TGeoPcon *p  The Poly cone where the two points come from.
363     //    Int_t    i1  First Point in arrays
364     //    Int_t    i2  Second Point in arrays
365     //    Double_t r   Value r min at which z is to be found
366     // Outputs:
367     //    none.
368     // Return:
369     //    The value z corresponding to r min and the line defined by 
370     //    the two points
371
372     return p->GetZ(i2)+(p->GetZ(i1)-p->GetZ(i2))*(r-p->GetRmin(i2))/
373      (p->GetRmin(i1)-p->GetRmin(i2));
374 }
375 //______________________________________________________________________
376 Double_t AliITSv11Geometry::Zfrom2MaxPoints(const TGeoPcon *p,Int_t i1,
377                                             Int_t i2,Double_t r)const{
378     // Retruns the value of Z corresponding to point R alone the line
379     // defined by the two points p->GetRmax(i1),p->GetZ(i1) and 
380     // p->GetRmax(i2),p->GetZ(i2)
381     // Inputs:
382     //    TGeoPcon *p  The Poly cone where the two points come from.
383     //    Int_t    i1  First Point in arrays
384     //    Int_t    i2  Second Point in arrays
385     //    Double_t r   Value r max at which z is to be found
386     // Outputs:
387     //    none.
388     // Return:
389     //    The value z corresponding to r max and the line defined by 
390     //    the two points
391
392     return p->GetZ(i2)+(p->GetZ(i1)-p->GetZ(i2))*(r-p->GetRmax(i2))/
393      (p->GetRmax(i1)-p->GetRmax(i2));
394 }
395 //______________________________________________________________________
396 Double_t AliITSv11Geometry::Zfrom2Points(const Double_t *z,const Double_t *ar,
397                                          Int_t i1,Int_t i2,Double_t r)const{
398     // Retruns the value of z corresponding to point R alone the line
399     // defined by the two points p->GetRmax(i1),p->GetZ(i1) and 
400     // p->GetRmax(i2),p->GetZ(i2)
401     // Inputs:
402     //    Double_t  z  Array of z values
403     //    Double_t ar  Array of r values
404     //    Int_t    i1  First Point in arrays
405     //    Int_t    i2  Second Point in arrays
406     //    Double_t r   Value r at which z is to be found
407     // Outputs:
408     //    none.
409     // Return:
410     //    The value z corresponding to r and the line defined by the two points
411
412     return z[i2]+(z[i1]-z[i2])*(r-ar[i2])/(ar[i1]-ar[i2]);
413 }
414 //______________________________________________________________________
415 Double_t AliITSv11Geometry::RmaxFromZpCone(const TGeoPcon *p,int ip,
416                                            Double_t tc,Double_t z,
417                                            Double_t th)const{
418     // General Outer Cone surface equation Rmax.
419     // Intputs:
420     //     TGeoPcon  *p   The poly cone where the initial point comes from
421     //     Int_t     ip   The index in p to get the point location
422     //     Double_t  tc   The angle of that part of the cone is at
423     //     Double_t   z   The value of z to compute Rmax from
424     //     Double_t  th   The perpendicular distance the parralell line is
425     //                    from the point ip.
426     // Outputs:
427     //     none.
428     // Return:
429     //     The value Rmax correstponding to the line at angle th, offeset by
430     //     th, and the point p->GetZ/Rmin[ip] at the location z.
431     Double_t tantc = TMath::Tan(tc*TMath::DegToRad());
432     Double_t costc = TMath::Cos(tc*TMath::DegToRad());
433
434     return -tantc*(z-p->GetZ(ip))+p->GetRmax(ip)+th/costc;
435 }
436 //______________________________________________________________________
437 Double_t AliITSv11Geometry::RFromZpCone(const Double_t *ar,
438                                         const Double_t *az,int ip,
439                                         Double_t tc,Double_t z,
440                                         Double_t th)const{
441     // General Cone surface equation R(z).
442     // Intputs:
443     //     Double_t  ar   The array of R values
444     //     Double_t  az   The array of Z values
445     //     Int_t     ip   The index in p to get the point location
446     //     Double_t  tc   The angle of that part of the cone is at
447     //     Double_t   z   The value of z to compute R from
448     //     Double_t  th   The perpendicular distance the parralell line is
449     //                    from the point ip.
450     // Outputs:
451     //     none.
452     // Return:
453     //     The value R correstponding to the line at angle th, offeset by
454     //     th, and the point p->GetZ/Rmax[ip] at the locatin z.
455     Double_t tantc = TMath::Tan(tc*TMath::DegToRad());
456     Double_t costc = TMath::Cos(tc*TMath::DegToRad());
457
458     return -tantc*(z-az[ip])+ar[ip]+th/costc;
459 }
460 //______________________________________________________________________
461 Double_t AliITSv11Geometry::RminFromZpCone(const TGeoPcon *p,Int_t ip,
462                                            Double_t tc,Double_t z,
463                                            Double_t th)const{
464     // General Inner Cone surface equation Rmin.
465     // Intputs:
466     //     TGeoPcon  *p   The poly cone where the initial point comes from
467     //     Int_t     ip   The index in p to get the point location
468     //     Double_t  tc   The angle of that part of the cone is at
469     //     Double_t   z   The value of z to compute Rmin from
470     //     Double_t  th   The perpendicular distance the parralell line is
471     //                    from the point ip.
472     // Outputs:
473     //     none.
474     // Return:
475     //     The value Rmin correstponding to the line at angle th, offeset by
476     //     th, and the point p->GetZ/Rmin[ip] at the location z.
477     Double_t tantc = TMath::Tan(tc*TMath::DegToRad());
478     Double_t costc = TMath::Cos(tc*TMath::DegToRad());
479
480     return -tantc*(z-p->GetZ(ip))+p->GetRmin(ip)+th/costc;
481 }
482 //______________________________________________________________________
483 Double_t AliITSv11Geometry::ZFromRmaxpCone(const TGeoPcon *p,int ip,
484                                            Double_t tc,Double_t r,
485                                            Double_t th)const{
486     // General Outer cone Surface equation for z.
487     // Intputs:
488     //     TGeoPcon  *p   The poly cone where the initial point comes from
489     //     Int_t     ip   The index in p to get the point location
490     //     Double_t  tc   The angle of that part of the cone is at
491     //     Double_t   r   The value of Rmax to compute z from
492     //     Double_t  th   The perpendicular distance the parralell line is
493     //                    from the point ip.
494     // Outputs:
495     //     none.
496     // Return:
497     //     The value Z correstponding to the line at angle th, offeset by
498     //     th, and the point p->GetZ/Rmax[ip] at the location r.
499     Double_t tantc = TMath::Tan(tc*TMath::DegToRad());
500     Double_t costc = TMath::Cos(tc*TMath::DegToRad());
501
502     return p->GetZ(ip)+(p->GetRmax(ip)+th/costc-r)/tantc;
503 }
504 //______________________________________________________________________
505 Double_t AliITSv11Geometry::ZFromRmaxpCone(const Double_t *ar,
506                                            const Double_t *az,int ip,
507                                            Double_t tc,Double_t r,
508                                            Double_t th)const{
509     // General Outer cone Surface equation for z.
510     // Intputs:
511     //     Double_t  ar   The array of R values
512     //     Double_t  az   The array of Z values
513     //     Int_t     ip   The index in p to get the point location
514     //     Double_t  tc   The angle of that part of the cone is at
515     //     Double_t   r   The value of Rmax to compute z from
516     //     Double_t  th   The perpendicular distance the parralell line is
517     //                    from the point ip.
518     // Outputs:
519     //     none.
520     // Return:
521     //     The value Z correstponding to the line at angle th, offeset by
522     //     th, and the point p->GetZ/Rmax[ip] at the locatin r.
523     Double_t tantc = TMath::Tan(tc*TMath::DegToRad());
524     Double_t costc = TMath::Cos(tc*TMath::DegToRad());
525
526     return az[ip]+(ar[ip]+th/costc-r)/tantc;
527 }
528 //______________________________________________________________________
529 Double_t AliITSv11Geometry::ZFromRminpCone(const TGeoPcon *p,int ip,
530                                            Double_t tc,Double_t r,
531                                            Double_t th)const{
532     // General Inner cone Surface equation for z.
533     // Intputs:
534     //     TGeoPcon  *p   The poly cone where the initial point comes from
535     //     Int_t     ip   The index in p to get the point location
536     //     Double_t  tc   The angle of that part of the cone is at
537     //     Double_t   r   The value of Rmin to compute z from
538     //     Double_t  th   The perpendicular distance the parralell line is
539     //                    from the point ip.
540     // Outputs:
541     //     none.
542     // Return:
543     //     The value Z correstponding to the line at angle th, offeset by
544     //     th, and the point p->GetZ/Rmin[ip] at the location r.
545     Double_t tantc = TMath::Tan(tc*TMath::DegToRad());
546     Double_t costc = TMath::Cos(tc*TMath::DegToRad());
547
548     return p->GetZ(ip)+(p->GetRmin(ip)+th/costc-r)/tantc;
549 }
550 //______________________________________________________________________
551 void AliITSv11Geometry::RadiusOfCurvature(Double_t rc,Double_t theta0,
552                                           Double_t z0,Double_t r0,
553                                           Double_t theta1,Double_t &z1,
554                                           Double_t &r1)const{
555     // Given a initial point z0,r0, the initial angle theta0, and the radius
556     // of curvature, returns the point z1, r1 at the angle theta1. Theta
557     // measured from the r axis in the clock wise direction [degrees].
558     // Inputs:
559     //    Double_t rc     The radius of curvature
560     //    Double_t theta0 The starting angle (degrees)
561     //    Double_t z0     The value of z at theta0
562     //    Double_t r0     The value of r at theta0
563     //    Double_t theta1 The ending angle (degrees)
564     // Outputs:
565     //    Double_t &z1  The value of z at theta1
566     //    Double_t &r1  The value of r at theta1
567     // Return:
568     //    none.
569
570     z1 = rc*(TMath::Sin(theta1*TMath::DegToRad())-TMath::Sin(theta0*TMath::DegToRad()))+z0;
571     r1 = rc*(TMath::Cos(theta1*TMath::DegToRad())-TMath::Cos(theta0*TMath::DegToRad()))+r0;
572     return;
573 }
574 //______________________________________________________________________
575 void AliITSv11Geometry::InsidePoint(const TGeoPcon *p,Int_t i1,Int_t i2,
576                                     Int_t i3,Double_t c,TGeoPcon *q,Int_t j1,
577                                     Bool_t max)const{
578     // Given two lines defined by the points i1, i2,i3 in the TGeoPcon 
579     // class p that intersect at point p->GetZ(i2) return the point z,r 
580     // that is Cthick away in the TGeoPcon class q. If points i1=i2
581     // and max == kTRUE, then p->GetRmin(i1) and p->GetRmax(i2) are used.
582     // if points i2=i3 and max=kTRUE then points p->GetRmax(i2) and
583     // p->GetRmin(i3) are used. If i2=i3 and max=kFALSE, then p->GetRmin(i2)
584     // and p->GetRmax(i3) are used.
585     // Inputs:
586     //    TGeoPcon  *p  Class where points i1, i2, and i3 are taken from
587     //    Int_t     i1  First point in class p
588     //    Int_t     i2  Second point in class p
589     //    Int_t     i3  Third point in class p
590     //    Double_t  c   Distance inside the outer surface/inner suface
591     //                  that the point j1 is to be computed for.
592     //    TGeoPcon  *q  Pointer to class for results to be put into.
593     //    Int_t     j1  Point in class q where data is to be stored.
594     //    Bool_t    max if kTRUE, then a Rmax value is computed,
595     //                  else a Rmin valule is computed.
596     // Output:
597     //    TGeoPcon  *q  Pointer to class for results to be put into.
598     // Return:
599     //    none.
600     Double_t x0,y0,x1,y1,x2,y2,x,y;
601
602     if(max){
603         c = -c; //cout <<"L394 c="<<c<<endl;
604         y0 = p->GetRmax(i1);
605         if(i1==i2) y0 = p->GetRmin(i1); //cout <<"L396 y0="<<y0<<endl;
606         y1 = p->GetRmax(i2);  //cout <<"L397 y1="<<y1<<endl;
607         y2 = p->GetRmax(i3); //cout <<"L398 y2="<<y2<<endl;
608         if(i2==i3) y2 = p->GetRmin(i3); //cout <<"L399 y2="<<y2<<endl;
609     }else{ // min
610         y0 = p->GetRmin(i1); //cout <<"L401 y0="<<y0<<endl;
611         y1 = p->GetRmin(i2); //cout <<"L402 y1="<<y1<<endl;
612         y2 = p->GetRmin(i3);
613         if(i2==i3) y2 = p->GetRmax(i3); //cout <<"L404 y2="<<y2<<endl;
614     } // end if
615     x0 = p->GetZ(i1); //cout <<"L406 x0="<<x0<<endl;
616     x1 = p->GetZ(i2); //cout <<"L407 x1="<<x1<<endl;
617     x2 = p->GetZ(i3); //cout <<"L408 x2="<<x2<<endl;
618     //
619     InsidePoint(x0,y0,x1,y1,x2,y2,c,x,y);
620     q->Z(j1) = x;
621     if(max) q->Rmax(j1) = y;
622     else    q->Rmin(j1) = y;
623     return;
624 }
625 //----------------------------------------------------------------------
626 void AliITSv11Geometry::InsidePoint(Double_t x0,Double_t y0,
627                                     Double_t x1,Double_t y1,
628                                     Double_t x2,Double_t y2,Double_t c,
629                                     Double_t &x,Double_t &y)const{
630     // Given two intersecting lines defined by the points (x0,y0), (x1,y1) and
631     // (x1,y1), (x1,y2) {intersecting at (x1,y1)} the point (x,y) a distance
632     // c away is returned such that two lines a distance c away from the
633     // lines defined above intersect at (x,y).
634     // Inputs:
635     //    Double_t  x0 X point on the first intersecting sets of lines
636     //    Double_t  y0 Y point on the first intersecting sets of lines
637     //    Double_t  x1 X point on the first/second intersecting sets of lines
638     //    Double_t  y1 Y point on the first/second intersecting sets of lines
639     //    Double_t  x2 X point on the second intersecting sets of lines
640     //    Double_t  y2 Y point on the second intersecting sets of lines
641     //    Double_t  c  Distance the two sets of lines are from each other
642     // Output:
643     //    Double_t  x  X point for the intersecting sets of parellel lines
644     //    Double_t  y  Y point for the intersecting sets of parellel lines
645     // Return:
646     //    none.
647     Double_t dx01,dx12,dy01,dy12,r01,r12,m;
648     dx01 = x0-x1; //cout <<"L410 dx01="<<dx01<<endl;
649     dx12 = x1-x2; //cout <<"L411 dx12="<<dx12<<endl;
650     dy01 = y0-y1; //cout <<"L412 dy01="<<dy01<<endl;
651     dy12 = y1-y2; //cout <<"L413 dy12="<<dy12<<endl;
652     r01  = TMath::Sqrt(dy01*dy01+dx01*dx01); //cout <<"L414 r01="<<r01<<endl;
653     r12  = TMath::Sqrt(dy12*dy12+dx12*dx12); //cout <<"L415 r12="<<r12<<endl;
654     m = dx12*dy01-dy12*dx01;
655     if(m*m<DBL_EPSILON){ // m == n
656         if(dy01==0.0){ // line are =
657             x = x1+c; //cout <<"L419 x="<<x<<endl;
658             y = y1; //cout <<"L420 y="<<y<<endl;
659             return;
660         }else if(dx01==0.0){
661             x = x1;
662             y = y1+c;
663             return;
664         }else{ // dx01!=0 and dy01 !=0.
665             x = x1-0.5*c*r01/dy01; //cout <<"L434 x="<<x<<endl;
666             y = y1+0.5*c*r01/dx01; //cout <<"L435 y="<<y<<endl;
667         } // end if
668         return;
669     } //
670     x = x1+c*(dx12*r01-dx01*r12)/m; //cout <<"L442 x="<<x<<endl;
671     y = y1+c*(dy12*r01-dy01*r12)/m; //cout <<"L443 y="<<y<<endl;
672     //cout <<"=============================================="<<endl;
673     return;
674 }
675 //----------------------------------------------------------------------
676 void AliITSv11Geometry:: PrintArb8(const TGeoArb8 *a)const{
677     // Prints out the content of the TGeoArb8. Usefull for debugging.
678     // Inputs:
679     //   TGeoArb8 *a
680     // Outputs:
681     //   none.
682     // Return:
683     //   none.
684
685     if(!GetDebug()) return;
686     printf("%s",a->GetName());
687     a->InspectShape();
688     return;
689 }
690 //----------------------------------------------------------------------
691 void AliITSv11Geometry:: PrintPcon(const TGeoPcon *a)const{
692     // Prints out the content of the TGeoPcon. Usefull for debugging.
693     // Inputs:
694     //   TGeoPcon *a
695     // Outputs:
696     //   none.
697     // Return:
698     //   none.
699   
700     if(!GetDebug()) return;
701     cout << a->GetName() << ": N=" << a->GetNz() << " Phi1=" << a->GetPhi1()
702          << ", Dphi=" << a->GetDphi() << endl;
703     cout << "i\t   Z   \t  Rmin \t  Rmax" << endl;
704     for(Int_t iii=0;iii<a->GetNz();iii++){
705         cout << iii << "\t" << a->GetZ(iii) << "\t" << a->GetRmin(iii)
706              << "\t" << a->GetRmax(iii) << endl;
707     } // end for iii
708     return;
709 }
710 //----------------------------------------------------------------------
711 void AliITSv11Geometry::PrintTube(const TGeoTube *a)const{
712     // Prints out the content of the TGeoTube. Usefull for debugging.
713     // Inputs:
714     //   TGeoTube *a
715     // Outputs:
716     //   none.
717     // Return:
718     //   none.
719
720     if(!GetDebug()) return;
721     cout << a->GetName() <<": Rmin="<<a->GetRmin()
722          <<" Rmax=" <<a->GetRmax()<<" Dz="<<a->GetDz()<<endl;
723     return;
724 }
725 //----------------------------------------------------------------------
726 void AliITSv11Geometry::PrintTubeSeg(const TGeoTubeSeg *a)const{
727     // Prints out the content of the TGeoTubeSeg. Usefull for debugging.
728     // Inputs:
729     //   TGeoTubeSeg *a
730     // Outputs:
731     //   none.
732     // Return:
733     //   none.
734
735     if(!GetDebug()) return;
736     cout << a->GetName() <<": Phi1="<<a->GetPhi1()<<
737         " Phi2="<<a->GetPhi2()<<" Rmin="<<a->GetRmin()
738          <<" Rmax=" <<a->GetRmax()<<" Dz="<<a->GetDz()<<endl;
739     return;
740 }
741 //----------------------------------------------------------------------
742 void AliITSv11Geometry::PrintConeSeg(const TGeoConeSeg *a)const{
743     // Prints out the content of the TGeoConeSeg. Usefull for debugging.
744     // Inputs:
745     //   TGeoConeSeg *a
746     // Outputs:
747     //   none.
748     // Return:
749     //   none.
750
751     if(!GetDebug()) return;
752     cout << a->GetName() <<": Phi1="<<a->GetPhi1()<<
753         " Phi2="<<a->GetPhi2()<<" Rmin1="<<a->GetRmin1()
754          <<" Rmax1=" <<a->GetRmax1()<<" Rmin2="<<a->GetRmin2()
755          <<" Rmax2=" <<a->GetRmax2()<<" Dz="<<a->GetDz()<<endl;
756     return;
757 }
758 //----------------------------------------------------------------------
759 void AliITSv11Geometry::PrintBBox(const TGeoBBox *a)const{
760     // Prints out the content of the TGeoBBox. Usefull for debugging.
761     // Inputs:
762     //   TGeoBBox *a
763     // Outputs:
764     //   none.
765     // Return:
766     //   none.
767
768     if(!GetDebug()) return;
769     cout << a->GetName() <<": Dx="<<a->GetDX()<<
770         " Dy="<<a->GetDY()<<" Dz="<<a->GetDZ() <<endl;
771     return;
772 }
773 //---------------------------------------------------------------------
774 void AliITSv11Geometry::DrawCrossSection(const TGeoPcon *p,
775                             Int_t fillc,Int_t fills,
776                             Int_t linec,Int_t lines,Int_t linew,
777                             Int_t markc,Int_t marks,Float_t marksize)const{
778     // Draws a cross sectional view of the TGeoPcon, Primarily for debugging.
779     // A TCanvas should exist first.
780     //  Inputs:
781     //    TGeoPcon  *p  The TGeoPcon to be "drawn"
782     //    Int_t  fillc  The fill color to be used
783     //    Int_t  fills  The fill style to be used
784     //    Int_t  linec  The line color to be used
785     //    Int_t  lines  The line style to be used
786     //    Int_t  linew  The line width to be used
787     //    Int_t  markc  The markder color to be used
788     //    Int_t  marks  The markder style to be used
789     //    Float_t marksize The marker size
790     // Outputs:
791     //   none.
792     // Return:
793     //   none.
794     Int_t n=0,m=0,i=0;
795     Double_t *z=0,*r=0;
796     TPolyMarker *pts=0;
797     TPolyLine   *line=0;
798
799     n = p->GetNz();
800     if(n<=0) return;
801     m = 2*n+1;
802     z = new Double_t[m];
803     r = new Double_t[m];
804
805     for(i=0;i<n;i++){
806         z[i] = p->GetZ(i);
807         r[i] = p->GetRmax(i);
808         z[i+n] = p->GetZ(n-1-i);
809         r[i+n] = p->GetRmin(n-1-i);
810     } //  end for i
811     z[n-1] = z[0];
812     r[n-1] = r[0];
813
814     line = new TPolyLine(n,z,r);
815     pts  = new TPolyMarker(n,z,r);
816
817     line->SetFillColor(fillc);
818     line->SetFillStyle(fills);
819     line->SetLineColor(linec);
820     line->SetLineStyle(lines);
821     line->SetLineWidth(linew);
822     pts->SetMarkerColor(markc);
823     pts->SetMarkerStyle(marks);
824     pts->SetMarkerSize(marksize);
825
826     line->Draw("f");
827     line->Draw();
828     pts->Draw();
829
830     delete[] z;
831     delete[] r;
832
833     cout<<"Hit Return to continue"<<endl;
834     cin >> n;
835     delete line;
836     delete pts;
837     return;
838 }
839 //______________________________________________________________________
840 Bool_t AliITSv11Geometry::AngleOfIntersectionWithLine(Double_t x0,Double_t y0,
841                                                       Double_t x1,Double_t y1,
842                                                       Double_t xc,Double_t yc,
843                                                       Double_t rc,Double_t &t0,
844                                                       Double_t &t1)const{
845     // Computes the angles, t0 and t1 corresponding to the intersection of
846     // the line, defined by {x0,y0} {x1,y1}, and the circle, defined by
847     // its center {xc,yc} and radius r. If the line does not intersect the
848     // line, function returns kFALSE, otherwise it returns kTRUE. If the
849     // line is tangent to the circle, the angles t0 and t1 will be the same.
850     // Inputs:
851     //   Double_t x0   X of first point defining the line
852     //   Double_t y0   Y of first point defining the line
853     //   Double_t x1   X of Second point defining the line
854     //   Double_t y1   Y of Second point defining the line
855     //   Double_t xc   X of Circle center point defining the line
856     //   Double_t yc   Y of Circle center point defining the line
857     //   Double_t r    radius of circle
858     // Outputs:
859     //   Double_t &t0  First angle where line intersects circle
860     //   Double_t &t1  Second angle where line intersects circle
861     // Return:
862     //    kTRUE, line intersects circle, kFALSE line does not intersect circle
863     //           or the line is not properly defined point {x0,y0} and {x1,y1}
864     //           are the same point.
865     Double_t dx,dy,cx,cy,s2,t[4];
866     Double_t a0,b0,c0,a1,b1,c1,sinthp,sinthm,costhp,costhm;
867     Int_t i,j;
868
869     t0 = 400.0;
870     t1 = 400.0;
871     dx = x1-x0;
872     dy = y1-y0;
873     cx = xc-x0;
874     cy = yc-y0;
875     s2 = dx*dx+dy*dy;
876     if(s2==0.0) return kFALSE;
877
878     a0 = rc*rc*s2;
879     if(a0==0.0) return kFALSE;
880     b0 = 2.0*rc*dx*(dx*cy-cx*dy);
881     c0 = dx*dx*cy*cy-2.0*dy*dx*cy*cx+cx*cx*dy*dy-rc*rc*dy*dy;
882     c0 = 0.25*b0*b0/(a0*a0)-c0/a0;
883     if(c0<0.0) return kFALSE;
884     sinthp = -0.5*b0/a0+TMath::Sqrt(c0);
885     sinthm = -0.5*b0/a0-TMath::Sqrt(c0);
886
887     a1 = rc*rc*s2;
888     if(a1==0.0) return kFALSE;
889     b1 = 2.0*rc*dy*(dy*cx-dx*cy);
890     c1 = dy*dy*cx*cx-2.0*dy*dx*cy*cx+dx*dx*cy*cy-rc*rc*dx*dx;
891     c1 = 0.25*b1*b1/(a1*a1)-c1/a1;
892     if(c1<0.0) return kFALSE;
893     costhp = -0.5*b1/a1+TMath::Sqrt(c1);
894     costhm = -0.5*b1/a1-TMath::Sqrt(c1);
895
896     t[0] = t[1] = t[2] = t[3] = 400.;
897     a0 = TMath::ATan2(sinthp,costhp); if(a0<0.0) a0 += 2.0*TMath::Pi();
898     a1 = TMath::ATan2(sinthp,costhm); if(a1<0.0) a1 += 2.0*TMath::Pi();
899     b0 = TMath::ATan2(sinthm,costhp); if(b0<0.0) b0 += 2.0*TMath::Pi();
900     b1 = TMath::ATan2(sinthm,costhm); if(b1<0.0) b1 += 2.0*TMath::Pi();
901     x1 = xc+rc*TMath::Cos(a0);
902     y1 = yc+rc*TMath::Sin(a0);
903     s2 = dx*(y1-y0)-dy*(x1-x0);
904     if(s2*s2<DBL_EPSILON) t[0] = a0*TMath::RadToDeg();
905     x1 = xc+rc*TMath::Cos(a1);
906     y1 = yc+rc*TMath::Sin(a1);
907     s2 = dx*(y1-y0)-dy*(x1-x0);
908     if(s2*s2<DBL_EPSILON) t[1] = a1*TMath::RadToDeg();
909     x1 = xc+rc*TMath::Cos(b0);
910     y1 = yc+rc*TMath::Sin(b0);
911     s2 = dx*(y1-y0)-dy*(x1-x0);
912     if(s2*s2<DBL_EPSILON) t[2] = b0*TMath::RadToDeg();
913     x1 = xc+rc*TMath::Cos(b1);
914     y1 = yc+rc*TMath::Sin(b1);
915     s2 = dx*(y1-y0)-dy*(x1-x0);
916     if(s2*s2<DBL_EPSILON) t[3] = b1*TMath::RadToDeg();
917     for(i=0;i<4;i++)for(j=i+1;j<4;j++){
918         if(t[i]>t[j]) {t0 = t[i];t[i] = t[j];t[j] = t0;}
919     } // end for i,j
920     t0 = t[0];
921     t1 = t[1];
922     //
923     return kTRUE;
924 }
925 //______________________________________________________________________
926 Double_t AliITSv11Geometry::AngleForRoundedCorners0(Double_t dx,Double_t dy,
927                                                     Double_t sdr)const{
928     // Basic function used to determine the ending angle and starting angles
929     // for rounded corners given the relative distance between the centers
930     // of the circles and the difference/sum of their radii. Case 0.
931     // Inputs:
932     //   Double_t dx    difference in x locations of the circle centers
933     //   Double_t dy    difference in y locations of the circle centers
934     //   Double_t sdr   difference or sum of the circle radii
935     // Outputs:
936     //   none.
937     // Return:
938     //   the angle in Degrees
939     Double_t a,b;
940
941     b = dy*dy+dx*dx-sdr*sdr;
942     if(b<0.0) Error("AngleForRoundedCorners0",
943                     "dx^2(%e)+dy^2(%e)-sdr^2(%e)=b=%e<0",dx,dy,sdr,b);
944     b = TMath::Sqrt(b);
945     a = -sdr*dy+dx*b;
946     b = -sdr*dx-dy*b;
947     return TMath::ATan2(a,b)*TMath::RadToDeg();
948     
949 }
950 //______________________________________________________________________
951 Double_t AliITSv11Geometry::AngleForRoundedCorners1(Double_t dx,Double_t dy,
952                                                     Double_t sdr)const{
953     // Basic function used to determine the ending angle and starting angles
954     // for rounded corners given the relative distance between the centers
955     // of the circles and the difference/sum of their radii. Case 1.
956     // Inputs:
957     //   Double_t dx    difference in x locations of the circle centers
958     //   Double_t dy    difference in y locations of the circle centers
959     //   Double_t sdr   difference or sum of the circle radii
960     // Outputs:
961     //   none.
962     // Return:
963     //   the angle in Degrees
964     Double_t a,b;
965
966     b = dy*dy+dx*dx-sdr*sdr;
967     if(b<0.0) Error("AngleForRoundedCorners1",
968                     "dx^2(%e)+dy^2(%e)-sdr^2(%e)=b=%e<0",dx,dy,sdr,b);
969     b = TMath::Sqrt(b);
970     a = -sdr*dy-dx*b;
971     b = -sdr*dx+dy*b;
972     return TMath::ATan2(a,b)*TMath::RadToDeg();
973     
974 }
975 //----------------------------------------------------------------------
976 void AliITSv11Geometry::AnglesForRoundedCorners(Double_t x0,Double_t y0,
977                                                 Double_t r0,Double_t x1,
978                                                 Double_t y1,Double_t r1,
979                                                 Double_t &t0,Double_t &t1)
980     const{
981     // Function to compute the ending angle, for arc 0, and starting angle,
982     // for arc 1, such that a straight line will connect them with no
983     // discontinuities.
984     //Begin_Html
985     /*
986       <img src="picts/ITS/AliITSv11Geometry_AnglesForRoundedCorners.gif">
987      */
988     //End_Html
989     // Inputs:
990     //    Double_t x0  X Coordinate of arc 0 center.
991     //    Double_t y0  Y Coordinate of arc 0 center.
992     //    Double_t r0  Radius of curvature of arc 0. For signe see figure.
993     //    Double_t x1  X Coordinate of arc 1 center.
994     //    Double_t y1  Y Coordinate of arc 1 center.
995     //    Double_t r1  Radius of curvature of arc 1. For signe see figure.
996     // Outputs:
997     //    Double_t t0  Ending angle of arch 0, with respect to x axis, Degrees.
998     //    Double_t t1  Starting angle of arch 1, with respect to x axis, 
999     //                 Degrees.
1000     // Return:
1001     //    none.
1002     Double_t t;
1003
1004     if(r0>=0.0&&r1>=0.0) { // Inside to inside    ++
1005         t = AngleForRoundedCorners1(x1-x0,y1-y0,r1-r0);
1006         t0 = t1 = t;
1007         return;
1008     }else if(r0>=0.0&&r1<=0.0){ // Inside to Outside  +-
1009         r1 = -r1; // make positive
1010         t = AngleForRoundedCorners0(x1-x0,y1-y0,r1+r0);
1011         t0 = 180.0 + t;
1012         if(t0<0.0) t += 360.;
1013         if(t<0.0) t += 360.;
1014         t1 = t;
1015         return;
1016     }else if(r0<=0.0&&r1>=0.0){ // Outside to Inside  -+
1017         r0 = - r0; // make positive
1018         t = AngleForRoundedCorners1(x1-x0,y1-y0,r1+r0);
1019         t0 = 180.0 + t;
1020         if(t0>180.) t0 -= 360.;
1021         if(t >180.) t  -= 360.;
1022         t1 = t;
1023         return;
1024     }else if(r0<=0.0&&r1<=0.0) { // Outside to outside --
1025         r0 = -r0; // make positive
1026         r1 = -r1; // make positive
1027         t = AngleForRoundedCorners0(x1-x0,y1-y0,r1-r0);
1028         t0 = t1 = t;
1029         return;
1030     } // end if
1031     return;
1032 }
1033 //----------------------------------------------------------------------
1034 void AliITSv11Geometry::MakeFigure1(Double_t x0,Double_t y0,Double_t r0,
1035                                     Double_t x1,Double_t y1,Double_t r1){
1036     // Function to create the figure discribing how the function 
1037     // AnglesForRoundedCorners works.
1038     //
1039     // Inputs:
1040     //    Double_t x0  X Coordinate of arc 0 center.
1041     //    Double_t y0  Y Coordinate of arc 0 center.
1042     //    Double_t r0  Radius of curvature of arc 0. For signe see figure.
1043     //    Double_t x1  X Coordinate of arc 1 center.
1044     //    Double_t y1  Y Coordinate of arc 1 center.
1045     //    Double_t r1  Radius of curvature of arc 1. For signe see figure.
1046     // Outputs:
1047     //    none.
1048     // Return:
1049     //    none.
1050     Double_t t0[4],t1[4],xa0[4],ya0[4],xa1[4],ya1[4],ra0[4],ra1[4];
1051     Double_t xmin,ymin,xmax,ymax,h;
1052     Int_t j;
1053
1054     for(j=0;j<4;j++) {
1055         ra0[j] = r0; if(j%2) ra0[j] = -r0;
1056         ra1[j] = r1; if(j>1) ra1[j] = -r1;
1057         AnglesForRoundedCorners(x0,y0,ra0[j],x1,y1,ra1[j],t0[j],t1[j]);
1058         xa0[j] = TMath::Abs(r0)*CosD(t0[j])+x0;
1059         ya0[j] = TMath::Abs(r0)*SinD(t0[j])+y0;
1060         xa1[j] = TMath::Abs(r1)*CosD(t1[j])+x1;
1061         ya1[j] = TMath::Abs(r1)*SinD(t1[j])+y1;
1062     } // end for j
1063     if(r0<0.0) r0 = -r0;
1064     if(r1<0.0) r1 = -r1;
1065     xmin = TMath::Min(x0 - r0,x1-r1);
1066     ymin = TMath::Min(y0 - r0,y1-r1);
1067     xmax = TMath::Max(x0 + r0,x1+r1);
1068     ymax = TMath::Max(y0 + r0,y1+r1);
1069     for(j=1;j<4;j++) {
1070         xmin = TMath::Min(xmin,xa0[j]);
1071         xmin = TMath::Min(xmin,xa1[j]);
1072         ymin = TMath::Min(ymin,ya0[j]);
1073         ymin = TMath::Min(ymin,ya1[j]);
1074
1075         xmax = TMath::Max(xmax,xa0[j]);
1076         xmax = TMath::Max(xmax,xa1[j]);
1077         ymax = TMath::Max(ymax,ya0[j]);
1078         ymax = TMath::Max(ymax,ya1[j]);
1079     } // end for j
1080     if(xmin<0.0) xmin *= 1.1; else xmin *= 0.9;
1081     if(ymin<0.0) ymin *= 1.1; else ymin *= 0.9;
1082     if(xmax<0.0) xmax *= 0.9; else xmax *= 1.1;
1083     if(ymax<0.0) ymax *= 0.9; else ymax *= 1.1;
1084     j = (Int_t)(500.0*(ymax-ymin)/(xmax-xmin));
1085     TCanvas *can = new TCanvas("AliITSv11Geometry_AnglesForRoundedCorners",
1086                                "Figure for AliITSv11Geometry",500,j);
1087     h = ymax-ymin; if(h<0) h = -h;
1088     can->Range(xmin,ymin,xmax,ymax);
1089     TArc *c0 = new TArc(x0,y0,r0);
1090     TArc *c1 = new TArc(x1,y1,r1);
1091     TLine *line[4];
1092     TArrow *ar0[4];
1093     TArrow *ar1[4];
1094     for(j=0;j<4;j++){
1095         ar0[j] = new TArrow(x0,y0,xa0[j],ya0[j]);
1096         ar1[j] = new TArrow(x1,y1,xa1[j],ya1[j]);
1097         line[j] = new TLine(xa0[j],ya0[j],xa1[j],ya1[j]);
1098         ar0[j]->SetLineColor(j+1);
1099         ar0[j]->SetArrowSize(0.1*r0/h);
1100         ar1[j]->SetLineColor(j+1);
1101         ar1[j]->SetArrowSize(0.1*r1/h);
1102         line[j]->SetLineColor(j+1);
1103     } // end for j
1104     c0->Draw();
1105     c1->Draw();
1106     for(j=0;j<4;j++){
1107         ar0[j]->Draw();
1108         ar1[j]->Draw();
1109         line[j]->Draw();
1110     } // end for j
1111     TText *t = new TText();
1112     t->SetTextSize(0.02);
1113     Char_t txt[100];
1114     sprintf(txt,"(x0=%5.2f,y0=%5.2f)",x0,y0);
1115     t->DrawText(x0,y0,txt);
1116     sprintf(txt,"(x1=%5.2f,y1=%5.2f)",x1,y1);
1117     for(j=0;j<4;j++) {
1118         t->SetTextColor(j+1);
1119         t->DrawText(x1,y1,txt);
1120         sprintf(txt,"r0=%5.2f",ra0[j]);
1121         t->DrawText(0.5*(x0+xa0[j]),0.5*(y0+ya0[j]),txt);
1122         sprintf(txt,"r1=%5.2f",ra1[j]);
1123         t->DrawText(0.5*(x1+xa1[j]),0.5*(y1+ya1[j]),txt);
1124     } // end for j
1125 }