FlyoDoc_2011 Pisa 2011 by GmP --- 011
|
00001 /*************************************************************************** 00002 devsector.cpp - description 00003 ------------------- 00004 begin : settembre 2008 00005 copyright : (C) 2001 by Giuseppe Pierazzini 00006 email : pierazzini@unipi.it 00007 *************************************************************************** 00008 * * 00009 * NA48 simulation program. * 00010 * * 00011 ***************************************************************************/ 00012 #include "parm.h" 00013 #include "devsector.h" 00014 00015 //using namespace std; 00016 00017 DevSector::~DevSector() 00018 { 00019 } 00020 //================== Cilindro=======Erede di RettEdro 00021 DevSector::DevSector() 00022 { 00023 devtype=TypDevSector; 00024 devclass="Cili_Sector"; 00025 rin =Lin.y=Lin.x; 00026 Lin.Norma(); 00027 rinq=rin*rin; 00028 } 00029 00030 //----------------- -------- 00031 void DevSector::Prgeom() 00032 { 00033 Gout<<"================== R i v e l a t o r e ================="; 00034 Gout<<"\n --> < "<<nome <<" > [ "<<fun 00035 <<" ] Settoredi cilindro senza buco. "; 00036 Device::Prgeom(); 00037 00038 } 00039 00040 //====================================================== 00041 //----------------- -----P o s i z i o n e --- 00042 int DevSector::Posizione() 00043 { 00044 00045 if ( DevCln::Posizione() >0 ) return 1; 00046 // ritorn 1: il punto e' esterno al cilindro in cui è inscritto il settore 00047 // il centro del cilindro non è detto che sia sull'asse z! 00048 00050 // verifico se il punto è interno al settore cilindrico. 00051 // Il vertice del settore corrisponde al centro coordinate del device. 00052 // L'asse x è mediano al settore. La semiapertura è 00053 // OpenSector= x rad. 00054 // verifico se il punto è interno al settore cilindrico 00055 // che suppongo avere un raggio maggiore rout già verificato 00056 // e un raggio minore rin che verifico ora 00057 if ( ( X_dev.x*X_dev.x+X_dev.y*X_dev.y ) <rinq ) return 1; 00058 double fi= atan2 ( X_dev.y,X_dev.x ); 00059 if ( abs ( fi ) > OpenSector ) return 1; 00060 return 0; // zero se interno, 1 se esterno. 00061 00062 00063 } 00064 //---------------------------------------------------------- 00065 //----------------------C a m E s t e r -------------------- 00066 double DevSector::CamEster() 00067 { 00068 double nv,dxyq,b,c,dltq,fi,t=-1.; 00069 gvet Vn,Xpos; 00070 camm=-1.; 00072 00073 // se mi allontano ritorno -1. 00074 if ( ( nv=V_dev.z ) >0.0&&Doutd.z>0.0 ) return -1.; 00075 00076 // ***** controllo se colpisce la base 00077 if ( nv >0.0 && Douts.z>0.0 ) // piani z 00078 {t=Douts.z/nv; if ( t>camm ) camm=t;} 00079 else if ( nv<0.0 && Doutd.z>0.0 ) 00080 {t=-Doutd.z/nv; if ( t>camm ) camm=t;} 00081 // colpisco nei limiti giusti 00082 Xpos= X_dev+V_dev*camm; 00083 dxyq=Xpos.x *Xpos.x +Xpos.y*Xpos.y; 00084 fi= atan2 ( X_dev.y,X_dev.x ); 00085 if ( abs ( fi ) <= OpenSector && dxyq >=rinq && dxyq<=routq ) return camm; 00086 else camm=-1.0; 00087 if ( vxyq<=0.0 ) return camm; //per vxyq==0 corre lungo zeta e non colpisce nulla 00088 00090 if ( ( c=drq-routq ) >0.0 ) // la particella è esterna e può colpire il cilindro lateralmente.... 00091 { 00092 b=V_dev.x*X_dev.x+V_dev.y*X_dev.y; 00093 if ( b<0.0 ) 00094 { 00095 if ( ( dltq=b*b-vxyq*c ) < 0.0 ) return camm; // non colpisce mai il cilindro... quindi esco con -1.0 00096 t= - ( b + sqrt ( dltq ) ) /vxyq; // Scelgo la soluzione minore 00097 if ( t>0.0 ) // ma lo è per forza....verifico i limiti 00098 { 00099 Xpos= X_dev+V_dev*t; 00100 fi= atan2 ( X_dev.y,X_dev.x ); 00101 if ( abs ( fi ) <= OpenSector && fabs ( Xpos.z ) <= Lout.z ) {camm=t; return camm;} // esco contento 00102 } 00103 } 00104 } 00105 00107 // la normale al piano è calcolata uscente dal settore. 00108 // se urta il piano laterale verifico i limiti. 00109 00110 Vn.x=-sin ( OpenSector ); 00111 Vn.y= cos ( OpenSector ); 00112 Vn.z=0.0; 00113 if ( ( b=Vn%V_dev ) <0. ) t= - ( Vn%X_dev ) /b; 00114 else 00115 { 00116 Vn.x=sin ( OpenSector ); 00117 Vn.y=cos ( OpenSector ); 00118 Vn.z=0.0; 00119 if ( ( b=Vn%V_dev ) <0. ) t= - ( Vn%X_dev ) /b; 00120 } 00121 if ( t>0.0 ) // verifico i limiti....in raggi e zeta 00122 { 00123 Xpos= X_dev+V_dev*t; 00124 dxyq=Xpos.x *Xpos.x +Xpos.y*Xpos.y; 00125 if ( dxyq <=routq && dxyq >=rinq && 00126 fabs ( Xpos.z ) <= Lout.z ) {camm=t; return camm;} // ha colpito il lato ed esco contento.. 00127 } 00128 00130 // e verifico i limiti in zeta e angolo (note vxyq>0.) 00131 // la posizione della particella può essere dentro o fuori il cerchio di raggio rin 00132 00133 b=V_dev.x*X_dev.x+V_dev.y*X_dev.y; 00134 if( (c=drq-rinq) >0.0) return camm; 00135 // return camm=-1.0: punto di partenza più distante di rin dall'asse ... non posso colpire l'interno 00136 00137 if ( ( dltq=b*b-vxyq*c ) <0.0 ) return camm; // se il punto è interno è sempre positivo.... 00138 t= - ( b - sqrt ( dltq ) ) /vxyq; // devo scegliere comunque la soluzione positiva 00139 if ( t>0.0 ) 00140 { 00141 Xpos= X_dev+V_dev*t; 00142 fi= atan2 ( X_dev.y,X_dev.x ); 00143 if ( abs ( fi ) > OpenSector ) return camm; 00144 if ( fabs ( Xpos.z ) > Lout.z ) return camm; 00145 camm=t; 00146 } 00147 00148 return camm; 00149 } 00150 //=========================================================== 00151 //----------------------C a m I n t e r -------------------- 00152 00153 double DevSector::CamInter() 00154 { 00155 double b,c,dltq,t=1.0e+11; 00156 00157 gvet Vn,Xpos; 00158 camm=DevCln::CamInter(); 00159 00161 00162 Vn.x=-sin ( OpenSector ); 00163 Vn.y= cos ( OpenSector ); 00164 Vn.z=0.0; 00165 00166 if ( ( b=Vn%V_dev ) >0. ) t= - ( Vn%X_dev ) /b; 00167 00168 else 00169 { 00170 Vn.x=sin ( OpenSector ); 00171 Vn.y=cos ( OpenSector ); 00172 if ( ( b=Vn%V_dev ) >0. ) t= - ( Vn%X_dev ) /b; 00173 00174 } 00175 if ( t<camm ) 00176 { 00177 Xpos= X_dev+V_dev*t; 00178 double dxyq=Xpos.x *Xpos.x +Xpos.y*Xpos.y; 00179 if ( dxyq <=routq && dxyq >=rinq && 00180 fabs ( Xpos.z ) <= Lout.z ) camm=t; // ha colpito un piano laterale 00181 } 00182 00184 if ( vxyq>0.0 ) 00185 { 00186 b=V_dev.x*X_dev.x+V_dev.y*X_dev.y; 00187 if ( b<0. ) // revised 31.07.01 gmp 00188 { 00189 c=drq-rinq; 00190 if ( ( dltq=b*b-vxyq*c ) >=0.0 ) 00191 { 00192 t= - ( b + sqrt ( dltq ) ) /vxyq; // Scelgo la soluzione minore 00193 if ( t<camm ) 00194 { 00195 Xpos= X_dev+V_dev*t; 00196 double fi= atan2 ( X_dev.y,X_dev.x ); 00197 if ( abs ( fi ) > OpenSector ) return camm; 00198 if ( fabs ( Xpos.z ) > Lin.z ) return camm; 00199 camm=t; 00200 } 00201 } 00202 } 00203 } 00204 00205 00206 return camm; 00207 } 00209 //-------------------------------------------- 00210 gvet& DevSector::Lab2cDev ( gvet &Xin ) 00211 { 00212 // trasformazione di vettori al dev con rototraslazione... 00213 // la procedura qui è invertita rispetto al metodo di base... 00216 00217 00218 static gvet _Xdc,_Xdev; 00219 _Xdc.setvn (Xin%Nx,Xin%Ny,Xin%Nz ); 00220 _Xdev=_Xdc-Centro; 00221 return _Xdev; 00222 00223 } 00225 //-------------------------------------------- 00226 gvet& DevSector::Devc2Lab ( gvet &Xdev ) 00227 { 00228 // trasformazione di vettori dal Dev al lab con traslazione... 00230 // non calcola la norma... 00231 /* 00232 static gvet _Xlab; 00233 _Xlab=Nx*Xdev[0] + Ny*Xdev[1] + Nz*Xdev[2]; 00234 _Xlab=_Xlab+Centro; 00235 return _Xlab; 00236 */ 00237 00238 static gvet _Xlab, _Xaux; 00239 _Xaux=Xdev+Centro; 00240 _Xlab=Nx*_Xaux[0] + Ny*_Xaux[1] + Nz*_Xaux[2]; 00241 return _Xlab; 00242 00243 00244 }