Code_TYMPAN  4.4.0
Industrial site acoustic simulation
UniformBeamSampler.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012> <EDF-R&D> <FRANCE>
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  * See the GNU General Public License for more details.
11  * You should have received a copy of the GNU General Public License along
12  * with this program; if not, write to the Free Software Foundation, Inc.,
13  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14  */
15 
16 // Rajout de libraires pour creation fichier externe de sortie
17 #include <limits>
18 #include <iostream>
19 #include <fstream>
20 #include <sstream>
21 #include <deque>
22 #include <stack>
23 #include <string>
24 #include <math.h>
25 #include "Sampler.h"
26 #include "Tools/UnitConverter.h"
27 #include "Repere.h"
28 #include "Geometry/mathlib.h"
29 
30 #ifndef UNIFORM_BEAM_SAMPLER
31  #define UNIFORM_BEAM_SAMPLER
32 
33 using namespace std;
34 
65 {
66 public:
68  UniformBeamSampler(const unsigned int& nbRays = 0, const decimal& alpha = (decimal)M_PI,
69  const vec3& directivity = vec3(0, 0, 1))
70  : Sampler(nbRays, (decimal)M_PI, (decimal)M_2PI), _real_nb_rays(0), _slices(0), _slice_rays(0),
71  _radius(0.), _alpha(alpha / 2), _directivity(directivity), _i(0), _j(0),
72  _repere(Repere(vec3(1., 0., 0.), vec3(0., 1., 0.), vec3(0., 0., 1.), vec3(0., 0., 0.)))
73  {
74  init();
75  }
76 
78  {
79  _real_nb_rays = 0;
80  _slices = 0;
81  _slice_rays = 0;
82  _radius = other._radius;
83  _alpha = other._alpha;
84  _directivity = other._directivity;
85  _i = 0;
86  _j = 0;
87  _repere = Repere(vec3(1., 0., 0.), vec3(0., 1., 0.), vec3(0., 0., 1.), vec3(0., 0., 0.));
88  init();
89  }
90 
92  {
93  _real_nb_rays = 0;
94  _slices = 0;
95  _slice_rays = 0;
96  _radius = sampler->_radius;
97  _alpha = sampler->_alpha;
98  _directivity = sampler->_directivity;
99  _i = 0;
100  _j = 0;
101  _repere = Repere(vec3(1., 0., 0.), vec3(0., 1., 0.), vec3(0., 0., 1.), vec3(0., 0., 0.));
102  init();
103  }
104 
105  virtual Sampler* Clone()
106  {
107  Sampler* sampler = new UniformBeamSampler(this);
108  return sampler;
109  }
111  virtual ~UniformBeamSampler() {}
112 
113  // Move to next slice
114  void next_slice()
115  {
116  _i++; // Increment the slice index
117  _radius = sin(_i * _phi); // Radius of the new slice
118  decimal perimeter = static_cast<decimal>(2 * M_PI * _radius); // Perimeter of the new slice
119  _slice_rays = static_cast<int>(floor(perimeter / _phi)); // Number of rays on the new slice
120  _theta = static_cast<decimal>(2 * M_PI /
121  _slice_rays); // Angle between consecutive samples on the new slice
122  _j = 0; // Reset the sample index
123  }
124 
125  virtual vec3 getSample()
126  {
127 
128  if (_i > _slices || _nb_rays == 0) // if all samples have been drawn
129  return vec3(0., 0., 0.);
130 
131  vec3 res(0., 0., 1.); // first sample is points in direction of the z-axis <=> points in the direction
132  // of the directivity after the rotation
133 
134  if (_i != 0)
135  {
136  res = vec3(cos(_j * _theta) * _radius, // x
137  sin(_j * _theta) * _radius, // y
138  cos(_i * _phi)); // z
139  _j++;
140  }
141 
142  if (_j >= _slice_rays)
143  { // if _j as reached the number of samples on the current slice
144  next_slice(); // move to the next slice
145  }
146 
147  return _repere.vectorFromLocalToGlobal(
148  res); // rotate the sample according to the rotation between the z-axis and the directivity
149  }
150 
151  // v is acceptable if it lies in the beam's cone
152  virtual bool isAcceptableSample(vec3 v)
153  {
154  return acos(v * _directivity) <= (_alpha + EPSILON_5);
155  }
156 
157  virtual void init()
158  {
159  find_number_of_slices(); // determine the minimum number of slices so that _real_nb_rays >= _nb_rays
160 
161  // Compute the axises of the global repere
162  vec3 ax1 = vec3(0., 0., 1.);
163  ax1.cross(_directivity); // the first axis is orthogonal to the z_axis and to the directivity
164  ax1.normalize();
165 
166  vec3 ax2 = _directivity;
167  ax2.cross(ax1); // the second axis is orthogonal to the first one and to the directivity
168  ax2.normalize();
169 
170  // Mapping from the local repere to the global one (the third axis is the directivity and corresponds
171  // to the local z_axis)
172  _repere = Repere(ax1, ax2, _directivity, vec3(0., 0., 0.));
173  }
174 
175  // Return the real number of launched rays
176  unsigned int getRealNbRays() const
177  {
178  return _real_nb_rays;
179  }
180 
181  // Set the opening angle of the beam (input angle in degrees)
182  void setOpeningAngle(const decimal& Alpha)
183  {
184  _alpha = Alpha * M_PIDIV180 / 2;
185  init();
186  }
187 
188  // Get the opening angle of the beam (radians)
190  {
191  return _alpha * 2;
192  }
193 
194  // Set the directivity of the sampler
195  void setDirectivity(const vec3& Directivity)
196  {
197  _directivity = Directivity;
198  init();
199  }
200 
201  // Set the directivity of the sampler
203  {
204  return _directivity;
205  }
206 
207  virtual unsigned int computeDiffractionNbr(const decimal& thetaCalcul)
208  {
209 
210  decimal p = static_cast<decimal>(2 * _radius * M_PI); // perimeter of the slice
211  return static_cast<int>(floor(p / _phi)); // number of samples on the slice
212  }
213 
214 private:
215  inline void find_number_of_slices()
216  {
217  _slices = 0;
218  _real_nb_rays = _nb_rays;
219  // increase the number of slices until the desired number of rays is reached
220  for (unsigned int i = 1; i < _nb_rays; i++)
221  {
222 
223  _real_nb_rays = 1;
224  _slices = i;
225  decimal phi = static_cast<decimal>(
226  _alpha / _slices); // phi is equal to the opening angle divided by the number of slices
227 
228  for (unsigned int j = 1; j <= _slices; j++)
229  {
230 
231  decimal r = static_cast<decimal>(sin(j * phi)); // radius of the slice
232  decimal p = static_cast<decimal>(2 * r * M_PI); // perimeter of the slice
233  _real_nb_rays += static_cast<int>(
234  floor(p / phi)); // add the number of rays on the current slice to the total _real_nb_rays
235  }
236 
237  if (_real_nb_rays >= _nb_rays)
238  {
239  _phi = static_cast<decimal>(
240  _alpha / _slices); // phi is equal to the opening angle divided by the number of slices
241  break; // break if the desired number of rays has been reached
242  }
243  }
244  }
245 
246 private:
247  unsigned int _real_nb_rays;
248  unsigned int _slices;
249  unsigned int _slice_rays;
253  unsigned int _i,
254  _j;
256 };
257 
258 #endif
#define M_2PI
2Pi.
Definition: 3d.h:55
#define EPSILON_5
Definition: 3d.h:38
Frame class.
Definition: Repere.h:26
Sampler class and its sub-classes describe ray generators used in AcousticRayTracer....
Definition: Sampler.h:30
A Sampler class for sampling rays uniformely from a cone.
virtual unsigned int computeDiffractionNbr(const decimal &thetaCalcul)
Return the number of rays to launch after a diffraction event.
unsigned int getRealNbRays() const
virtual bool isAcceptableSample(vec3 v)
Return true for an acceptable sample.
vec3 _directivity
Directivity of the beam.
unsigned int _real_nb_rays
Real number of rays launched.
virtual vec3 getSample()
Return the sample.
virtual Sampler * Clone()
Clone a sample.
void setDirectivity(const vec3 &Directivity)
void setOpeningAngle(const decimal &Alpha)
unsigned int _slices
Number of slices.
UniformBeamSampler(UniformBeamSampler *sampler)
unsigned int _j
Current indices ( respectively slice index and sample index of the current slice)
UniformBeamSampler(const UniformBeamSampler &other)
UniformBeamSampler(const unsigned int &nbRays=0, const decimal &alpha=(decimal) M_PI, const vec3 &directivity=vec3(0, 0, 1))
Constructors.
virtual ~UniformBeamSampler()
Destructor.
virtual void init()
Initialize the sample.
decimal _alpha
Opening angle of the cone.
Repere _repere
Repere used to rotate the beam in direction of the directivity.
unsigned int _slice_rays
Number of remaining rays to launch for the current slice.
decimal _radius
radius of the current slice
#define M_PI
Pi.
Definition: color.cpp:25
#define M_PIDIV180
Definition: mathlib.h:79
float decimal
Definition: mathlib.h:45
base_vec3< decimal > vec3
Definition: mathlib.h:381