00001 #include "PhotonUtil.h"
00002 #include <TMath.h>
00003
00004 #include "MessageService/MsgService.h"
00005
00006 CVSID(" $Id: PhotonUtil.cxx,v 1.5 2005/02/02 16:44:33 tagg Exp $ " );
00007
00008 ClassImp(PhotonUtil)
00009
00010 Bool_t PhotonUtil::Refract(const TVector3& v1,
00011 Double_t n1,
00012 Double_t n2,
00013 const TVector3& norm,
00014 TVector3& v2)
00015 {
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 double ns = 1;
00026 double b1 = norm.Dot(v1);
00027 if(b1<0) {
00028 b1 = -b1;
00029 ns = -1;
00030 };
00031
00032 if(b1>1.0) {
00033 MSG("Photon",Msg::kWarning) << "Bad arguments to Refract()" << endl;
00034 return false;
00035 }
00036 double a1 = sqrt(1.0-b1*b1);
00037
00038
00039 TVector3 a = ((1./a1)*v1) - (((b1/a1)*ns)*norm);
00040
00041
00042
00043 double a2 = a1*n1/n2;
00044 if(a2>=1.0) {
00045
00046
00047
00048 v2 = v1 - 2.0*b1*ns*norm;
00049 return false;
00050 }
00051
00052 double b2 = sqrt(1.0-a2*a2);
00053
00054
00055 v2 = a2*a + (b2*ns)*norm;
00056 return true;
00057 }
00058
00059
00060 Bool_t PhotonUtil::IntersectCylinder(const TVector3& x,
00061 const TVector3& v,
00062 Double_t R,
00063 Double_t &d1,
00064 Double_t &d2
00065 )
00066 {
00067
00068
00069
00070
00071
00072
00073
00074 d1=d2=0;
00075
00076 double v2 = (v.y()*v.y() + v.z()*v.z());
00077 if(v2==0) return false;
00078
00079 double vdotdx = (v.y() * x.y()) + (v.z() * x.z());
00080 double insqrt = (vdotdx*vdotdx) -
00081 (v2)*((x.y()*x.y()) + (x.z()*x.z()) - (R*R));
00082
00083
00084 if(insqrt<0) return false;
00085
00086 double a = -vdotdx/v2;
00087 double b = TMath::Sqrt(insqrt)/v2;
00088
00089
00090 d1 = a-b;
00091
00092
00093 d2 = a+b;
00094
00095 return true;
00096 }
00097
00098
00099 Int_t PhotonUtil::InteractWithCylinder( TVector3& x,
00100 TVector3& v,
00101 Double_t R,
00102 Double_t n1,
00103 Double_t n2)
00104 {
00105
00106
00107
00108
00109
00110
00111 double d1, d2;
00112 bool intersect = PhotonUtil::IntersectCylinder( x,
00113 v,
00114 R,
00115 d1,d2);
00116
00117 if(!intersect) return -1;
00118
00119
00120
00121
00122 x += v*d1;
00123
00124
00125
00126
00127 TVector3 normal(0,x.y(),x.z());
00128
00129 if(normal.Mag2()==0.0) {
00130
00131
00132 return 1;
00133 }
00134 normal.SetMag(1.0);
00135
00136 bool refract = PhotonUtil::Refract(v,n1,n2,normal,v);
00137 if(refract) return 0;
00138
00139 return 1;
00140 }