RTFunctions.cc
Go to the documentation of this file.
1 #include "RTFunctions.h"
2 
3 #include <utl/config.h>
4 
5 #include <utl/Photon.h>
6 #include <utl/Point.h>
7 #include <utl/Vector.h>
8 #include <utl/CoordinateSystemPtr.h>
9 #include <utl/RandomEngine.h>
10 #include <utl/MathConstants.h>
11 
12 #include <CLHEP/Random/Randomize.h>
13 
14 #include <iostream>
15 #include <vector>
16 #include <utility>
17 
18 
19 using namespace utl;
20 using namespace std;
21 
22 using CLHEP::RandFlat;
23 using CLHEP::RandGauss;
24 
25 namespace TelescopeSimulatorKG {
26 
27  namespace RTFunctions {
28 
29  int Reflection(const utl::Photon& photonIn, const Vector& normal, utl::Photon& photonOut) {
30 
31  photonOut = photonIn;
32  const Vector& nIn = photonIn.GetDirection();
33 
34  const double dot = nIn*normal; // projection
35  photonOut.SetDirection(nIn - 2.*dot*normal); // -> new direction
36 
37  return 1;
38  }
39 
40 
41  double Plane (const utl::Point& point, const utl::Vector& normal,
42  const utl::Photon& photonIn, utl::Photon& photonOut) {
43 
44  photonOut = photonIn;
45  const Vector& nIn = photonIn.GetDirection();
46  const Point& pIn = photonIn.GetPosition();
47 
48  double b = normal*nIn;
49  double a = (point - pIn)*normal;
50 
51  if (b==0)
52  return (0);
53 
54  a/=b;
55 
56  photonOut.SetPosition(pIn + a*nIn);
57  return (a);
58  }
59 
60 
61  int Refraction(const double n12, const utl::Photon& photonIn, const Vector& normal, PhotonList& photonsOut) {
62 
63  const Vector& nIn = photonIn.GetDirection();
64 
65 
66  // Snell's law ------------------------------------
67 
68  double cosTheta_in = nIn*normal;
69  Vector projOnSurface = nIn - cosTheta_in*normal; // projected direction on surface
70 
71  projOnSurface *= n12; // take refraction into account -> outgoing
72 
73  double sin2theta_out = projOnSurface.GetMag2();
74 
75  // the reflected photon
76  Photon photonReflected(photonIn);
77  const double dot = nIn*normal; // projection
78  photonReflected.SetDirection(nIn - 2.*dot*normal); // -> new direction
79 
80 
81  if(sin2theta_out >= 1) { // TOTAL INTERNAL REFLECTION
82  photonsOut.push_back(photonReflected);
83  return 1;
84  }
85 
86  // check direction of incidence
87  double cosTheta_out;
88  if (cosTheta_in>0) cosTheta_out = +sqrt (1.-sin2theta_out);
89  else cosTheta_out = -sqrt (1.-sin2theta_out); // ray coming out of media ! sould not happen
90 
91 
92  // Fresnel's law ----------------------------------
93 
94  // T = t^2 transmisivity
95  // R = r^2 reflectivity
96  // R_unpolarized = 1/2 * (R_perp + R_par)
97  // T_unpolarized = 1/2 * (T_perp + T_par)
98  //
99  // because R and T gives the ratio of the energy flux per unit area (intensity),
100  // one has to take into acount the difference between theta1 and theta2 !
101  // 1. = R + [n2/n1 * cos(theta2)/cos(theta1)] * T
102 
103  double fact = 1.0;
104  if (cosTheta_in)
105  fact = 1./n12 * cosTheta_out/cosTheta_in;
106 
107  const double T_par = pow(2. * n12 * cosTheta_in / (n12 * cosTheta_out + cosTheta_in), 2);
108  const double T_perp = pow(2. * n12 * cosTheta_in / (n12 * cosTheta_in + cosTheta_out), 2);
109  const double T = fact * .5 * (T_par + T_perp); // unpolarized light
110 
111  const double weightIn = photonIn.GetWeight();
112 
113  Photon photonRefracted(photonIn);
114  photonRefracted.SetDirection(projOnSurface + cosTheta_out*normal);
115  photonRefracted.SetWeight(weightIn * T);
116  photonsOut.push_back(photonRefracted);
117 
118  photonReflected.SetWeight(weightIn * (1-T));
119  photonsOut.push_back(photonReflected);
120 
121  return 2;
122  }
123 
124 
125 
126  /* calculate the point and the normal vector on a sphere, where
127  the photon photonIn hits it.
128 
129  -----
130  origin: center of sphere
131  radius: radius
132  photonIn: incoming photon
133  photonOut: photon hitting the sphere
134  normal: surface normal on sphere at photonOut.GetPosition()
135  *****
136 
137  result:
138  0 : Error
139  1 : Ok
140  */
141 
142  int Sphere (const Point& origin, const double radius,
143  const utl::Photon& photonIn,
144  IntersectionList& intersection) {
145 
146  intersection.clear();
147 
148  const Vector& nIn = photonIn.GetDirection();
149  const Point& pIn = photonIn.GetPosition();
150 
151  const Vector pointToOrigin = pIn - origin;
152  const double dist2 = pointToOrigin.GetMag2();
153 
154  const double projection = pointToOrigin * nIn; // project nIn on radial Vector pointToOrigin
155  double delta = projection*projection + radius*radius - dist2;
156 
157  if (delta<0)
158  return 0; // no solution
159 
160  if (delta==0) {
161  Photon photonOut(photonIn);
162  photonOut.SetPosition(pIn - projection * nIn);
163  Vector normal = origin - photonOut.GetPosition();
164  normal.Normalize();
165  intersection.push_back(pair<Photon,Vector>(photonOut, normal));
166  }
167  else {
168 
169  delta = sqrt(delta);
170 
171  const double move1 = -projection - delta;
172  const double move2 = -projection + delta;
173 
174  Photon photonOut1(photonIn);
175  photonOut1.SetPosition(pIn + min(move1, move2)*nIn);
176  Vector normal1 = origin - photonOut1.GetPosition();
177  normal1.Normalize();
178  intersection.push_back(pair<Photon,Vector>(photonOut1, normal1));
179 
180  Photon photonOut2(photonIn);
181  photonOut2.SetPosition(pIn + max(move1, move2)*nIn);
182  Vector normal2 = origin - photonOut2.GetPosition();
183  normal2.Normalize();
184  intersection.push_back(pair<Photon,Vector>(photonOut2, normal2));
185  }
186 
187  return 1;
188 
189  }
190 
191 
192 
193 
194 
195 
196 
197  /*
198 
199  Code equivalent to geant4 optical boundary process for unified model:
200 
201  return facet normal of rough surface, a ray rayIn will hit
202 
203  This function code alpha to a random value taken from the
204  distribution p(alpha) = g(alpha; 0, sigma_alpha)*std::sin(alpha),
205  for alpha > 0 and alpha < 90, where g(alpha; 0, sigma_alpha)
206  is a gaussian distribution with mean 0 and standard deviation
207  sigma_alpha.
208  */
209 
210  Vector RandomNormal (utl::RandomEngine& rndm, const Vector& normalIn, double sigma_alpha,
211  const Vector& rayIn) {
212 
213  if (sigma_alpha==0) {
214  return normalIn; // nothing to do
215  }
216 
217  // first create a reference system with normalIn as z normal
218  CoordinateSystemPtr inCS = normalIn.GetCoordinateSystem();
219  double phiIn = normalIn.GetPhi (inCS);
220  double thetaIn = normalIn.GetTheta (inCS);
221  CoordinateSystemPtr tmpCS = CoordinateSystem::RotationZ (-phiIn, inCS);
222  CoordinateSystemPtr normalCS = CoordinateSystem::RotationY (-thetaIn, tmpCS);
223 
224 
225  double f_max = std::min(1.0, 4.*sigma_alpha);
226 
227  double phi = RandFlat::shoot (&rndm.GetEngine(), 0., 2.*kPi);
228  double sinPhi = sin(phi);
229  double cosPhi = cos(phi);
230 
231  Vector facetNormal;
232 
233  do {
234 
235  double alpha = 0;
236  do {
237  alpha = RandGauss::shoot (&rndm.GetEngine(), 0., sigma_alpha);
238  } while (RandFlat::shoot (&rndm.GetEngine(), 0., f_max) > sin(alpha) ||
239  alpha >= kPi/2.);
240 
241  double sinAlpha = sin(alpha);
242  double cosAlpha = cos(alpha);
243 
244  double unit_x = sinAlpha * cosPhi;
245  double unit_y = sinAlpha * sinPhi;
246  double unit_z = cosAlpha;
247 
248  facetNormal = Vector (unit_x, unit_y, unit_z, normalCS);
249 
250  } while (rayIn * facetNormal >= 0.0);
251 
252  return facetNormal;
253  }
254 
255  } // namespace RTFunctions
256 
257 } // namesapce TelescopeSimulatorKG
double Plane(const utl::Point &point, const utl::Vector &normal, const utl::Photon &photonIn, utl::Photon &photonOut)
Definition: RTFunctions.cc:41
void Normalize()
Definition: Vector.h:64
Point object.
Definition: Point.h:32
double GetPhi(const CoordinateSystemPtr &coordinateSystem) const
azimuth (phi) angle in spherical and cylindrical coordinates
Definition: BasicVector.h:254
std::vector< utl::Photon > PhotonList
Definition: RTFunctions.h:21
RandomEngineType & GetEngine()
Definition: RandomEngine.h:32
int Reflection(const utl::Photon &photonIn, const Vector &normal, utl::Photon &photonOut)
Definition: RTFunctions.cc:29
double GetTheta(const CoordinateSystemPtr &coordinateSystem) const
zenith (theta) angle in spherical coordinates
Definition: BasicVector.h:248
CoordinateSystemPtr GetCoordinateSystem() const
Get the coordinate system of the current internal representation.
Definition: BasicVector.h:234
double GetWeight() const
weight assigned to the photon
Definition: Photon.h:21
double pow(const double x, const unsigned int i)
void SetPosition(const utl::Point &p)
Definition: Photon.h:33
int Sphere(const Point &origin, const double radius, const utl::Photon &photonIn, IntersectionList &intersection)
Definition: RTFunctions.cc:142
boost::shared_ptr< const CoordinateTransformer > CoordinateSystemPtr
Shared pointer for coordinate systems.
#define max(a, b)
Wraps the random number engine used to generate distributions.
Definition: RandomEngine.h:27
constexpr double kPi
Definition: MathConstants.h:24
static Policy::type RotationY(const double angle, const CoordinateSystemPtr &theCS)
Construct from rotation about Y axis.
static Policy::type RotationZ(const double angle, const CoordinateSystemPtr &theCS)
Construct from rotation about Z axis.
void SetWeight(const double w)
source of the photons. Should use Eye::LightSource enum types
Definition: Photon.h:31
std::vector< PhotonNormalPair > IntersectionList
Definition: RTFunctions.h:28
const utl::Vector & GetDirection() const
Definition: Photon.h:26
int Refraction(const double n12, const utl::Photon &photonIn, const Vector &normal, PhotonList &photonsOut)
Definition: RTFunctions.cc:61
Vector object.
Definition: Vector.h:30
void SetDirection(const utl::Vector &v)
Definition: Photon.h:34
Vector RandomNormal(utl::RandomEngine &rndm, const Vector &normalIn, double sigma_alpha, const Vector &rayIn)
Definition: RTFunctions.cc:210
double GetMag2() const
Definition: Vector.h:61
const utl::Point & GetPosition() const
Definition: Photon.h:25

, generated on Tue Sep 26 2023.