Code_TYMPAN  4.4.0
Industrial site acoustic simulation
Ray.cpp
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 #include <cassert>
17 #include <vector>
18 #include "Geometry/mathlib.h"
19 #include "Geometry/Cylindre.h"
20 #include "Acoustic/Event.h"
21 #include "Acoustic/Recepteur.h"
22 #include "Ray.h"
23 
25 {
26  if (source == NULL)
27  {
28  std::cerr << "Error : ray without source or receptor computeLongueur" << endl;
29  return;
30  }
31 
32  longueur = 0;
33 
34  if (events.size() == 0) // No events
35  {
36 
37  if (recepteur == NULL)
38  {
39  // If the ray has not reached a receptor, the length is 0
40  longueur = 0;
41  return;
42  }
43  else
44  {
45 
46  // If the ray has reached a receptor, the length is the distance between the source dans the
47  // receptor
48  vec3 posSource = vec3(source->getPosition());
49  vec3 posRecep = vec3(((Recepteur*)(recepteur))->getPosition());
50  longueur = posSource.distance(posRecep);
51  return;
52  }
53  }
54  else
55  { // Ray has some events
56 
57  longueur = 0;
58 
59  // Distance from source to first event
60  longueur = source->getPosition().distance(events.front()->getPosition());
61 
62  // Add length of events sequence
64 
65  // If the ray has reached a receptor, add the distance from the last event to the receptor
66  if (recepteur != NULL)
67  {
68  vec3 posLastEvent = vec3(events.back()->getPosition());
69  vec3 posRecepteur = vec3(((Recepteur*)(recepteur))->getPosition());
70  longueur += posLastEvent.distance(posRecepteur);
71  }
72  return;
73  }
74 }
75 
77 {
78  // Sum the distance between each event
79  decimal length = 0;
80 
81  if (events.size() == 0)
82  {
83  return 0;
84  }
85 
86  std::vector<boost::shared_ptr<Event>>::iterator iter = events.begin();
87 
88  vec3 previous = (*iter)->getPosition();
89  vec3 current(0., 0., 0.);
90 
91  iter++;
92  while (iter != events.end())
93  {
94  current = (*iter)->getPosition();
95  length += current.distance(previous);
96  previous = current;
97  iter++;
98  };
99 
100  return length;
101 }
102 
103 decimal Ray::computeTrueLength(const vec3& ref, const vec3& lastPos, vec3& closestPoint)
104 {
105  if (source == NULL)
106  {
107  std::cerr << "Error : ray without source or receptor computeTrueLength" << endl;
108  return 0.;
109  }
110 
111  decimal length = 0.;
112  vec3 posSource = source->getPosition();
113  vec3 posLastEvent;
114  switch (events.size())
115  {
116  // Ray has no events
117  case 0:
118  // Compute the projection of ref on the line passing by posSource and lastPos
119  closestPoint = ref.closestPointOnLine(posSource, lastPos);
120 
121  // Compute the distance between the source and closestPoint
122  return posSource.distance(closestPoint);
123  break;
124 
125  // Ray has some events
126  default:
127  // Distance from source to first event
128  length = source->getPosition().distance(events.front()->getPosition());
129 
130  // Add length of events sequence
131  length += computeEventsSequenceLength();
132 
133  // Find last event's position
134  posLastEvent = events.back()->getPosition();
135 
136  // Compute the projection of ref on the line passing by posLastEvent and lastPos
137  closestPoint = ref.closestPointOnLine(posLastEvent, lastPos);
138 
139  // Add the distance between closestPoint and the position of the last event to the length and
140  // return the trueLength
141  return length += closestPoint.distance(posLastEvent);
142 
143  break;
144  }
145 
146  return 0.;
147 }
148 
149 decimal Ray::computePertinentLength(const vec3& ref, const vec3& lastPos, vec3& closestPoint)
150 {
151  if (source == NULL)
152  {
153  std::cerr << "Error : ray without source (computePertinentLength)" << endl;
154  return 0.;
155  }
156 
157  decimal pertinent_length = 0.;
158 
159  vec3 posLastEvent;
160  vec3 current(0., 0., 0.), previous(0., 0., 0.);
161 
162  Source* s = NULL;
163  Event* e = NULL;
164 
165  // Get the last diffraction event, or source if theray has no diffraction event
166  Base* pertinentEvent = getLastPertinentEventOrSource();
167 
168  switch (events.size())
169  {
170  case 0:
171  // if no the ray has no events, simply compute the full (true) length
172  return computeTrueLength(ref, lastPos, closestPoint);
173  break;
174 
175  default:
176  s = dynamic_cast<Source*>(pertinentEvent);
177 
178  // if pertinentEvent is the source, simply compute the full (true) length
179  if (s)
180  {
181 
182  return computeTrueLength(ref, lastPos, closestPoint);
183  }
184 
185  // if pertinentEvent is not the source
186  else
187  {
188 
189  // Recover the pertinent event
190  e = dynamic_cast<Event*>(pertinentEvent);
191 
192  if (e)
193  {
194 
195  // Get the last event (begining of the reverse iterator)
196  std::vector<boost::shared_ptr<Event>>::reverse_iterator rit = events.rbegin();
197  // Get the position of the lastEvent
198  previous = (*rit)->getPosition();
199 
200  // Compute the length from the last event to pertinentEvent
201  while ((rit != events.rend()) && ((*rit).get() != e))
202  {
203  rit++;
204  current = (*rit)->getPosition();
205  pertinent_length += current.distance(previous);
206  previous = current;
207  }
208 
209  // Get the position of last event
210  posLastEvent = vec3(events.back()->getPosition());
211  // Compute the projection of ref on the line passing by posLastEvent and lastPos
212  closestPoint = ref.closestPointOnLine(posLastEvent, lastPos);
213 
214  // Return the distance from the last event to the projection of ref
215  return (pertinent_length += closestPoint.distance(posLastEvent));
216  }
217  }
218 
219  break;
220  }
221 
222  return 0.;
223 }
224 
226 {
227  Base* res = (Base*)source;
228 
229  for (std::vector<boost::shared_ptr<Event>>::iterator iter = events.begin(); iter != events.end(); ++iter)
230  {
231  if ((*iter)->getType() == evType)
232  {
233  res = (Base*)((*iter).get());
234  }
235  }
236 
237  return res;
238 }
239 
240 std::vector<unsigned int> Ray::getFaceHistory()
241 {
242  vector<unsigned int> result;
243  result.push_back(source->getId());
244  for (unsigned int i = 0; i < events.size(); i++)
245  {
246  result.push_back(events.at(i)->getShape()->getFaceId());
247  }
248 
249  result.push_back(((Recepteur*)recepteur)->getId());
250  return result;
251 }
252 
253 std::vector<unsigned int> Ray::getPrimitiveHistory()
254 {
255  vector<unsigned int> result;
256  result.push_back(source->getId());
257  for (unsigned int i = 0; i < events.size(); i++)
258  {
259  result.push_back(events.at(i)->getShape()->getPrimitiveId());
260  }
261 
262  result.push_back(((Recepteur*)recepteur)->getId());
263  return result;
264 }
265 
266 decimal Ray::getThickness(const decimal& distance, bool diffraction)
267 {
268  decimal angle = getSolidAngle(diffraction);
269 
270  if (diffraction)
271  {
272  return distance * angle;
273  }
274 
275  return (decimal)(2. * distance * sqrt(angle / M_PI));
276 }
277 
278 decimal Ray::getSolidAngle(bool& diffraction)
279 {
280  unsigned int nb_rays = source->getInitialRayCount();
281 
282  if (diffraction)
283  {
285  Event* e = dynamic_cast<Event*>(last);
286 
287  if (e && (e->getType() == DIFFRACTION))
288  {
289  return (decimal)(dynamic_cast<Diffraction*>(e)->getAngle() * M_2PI /
291  }
292  else // else is done to be explicit
293  {
294  diffraction = false;
295  }
296  }
297 
298  return M_4PI / static_cast<decimal>(nb_rays);
299 }
300 
302 {
303  bitSet SR = getSRBitSet(source->getId(), (static_cast<Recepteur*>(recepteur))->getId());
304  bitSet SD = getEventsBitSet(typeEv);
305 
306  return std::make_pair(SR, SD);
307 }
308 
309 vector<unsigned int> Ray::getEventSignature()
310 {
311  vector<unsigned int> signature;
312  signature.push_back(source->getId());
313 
314  for (size_t i = 0; i < events.size(); i++)
315  signature.push_back(events.at(i)->getType());
316 
317  signature.push_back(((Recepteur*)recepteur)->getId());
318 
319  return signature;
320 }
321 
323 {
324  bitSet SD = 0;
325  for (size_t i = 0; i < events.size(); i++)
326  {
327  SD = SD << 1;
328 
329  if (events.at(i)->getType() == typeEv)
330  {
331  SD++;
332  }
333  }
334 
335  return SD;
336 }
#define M_2PI
2Pi.
Definition: 3d.h:55
typeevent
Definition: Event.h:24
@ DIFFRACTION
Definition: Event.h:27
NxReal s
Definition: NxVec3.cpp:317
std::pair< bitSet, bitSet > signature
Definition: Ray.h:30
Base class of Event, Material, PostFilter, Ray, Repere, Scene, Shape, Simulation, Source.
Definition: Base.h:25
Diffraction class Event.
Definition: Diffraction.h:31
Class describing an event (reflection, diffraction, ...)
Definition: Event.h:37
virtual int getType() const
Return the event type.
Definition: Event.h:205
virtual int getInitialNbResponseLeft() const
Return the number of rays to launch after event.
Definition: Event.h:133
decimal computeTrueLength(const vec3 &ref, const vec3 &lastPos, vec3 &closestPoint)
Compute ray length from source to closestPoint.
Definition: Ray.cpp:103
std::vector< boost::shared_ptr< Event > > events
Events list for the ray.
Definition: Ray.h:517
bitSet getSRBitSet(const unsigned int &source_id, const unsigned int &receptor_id)
Compute the bitSet associated with a source and a receptor.
Definition: Ray.h:266
decimal getSolidAngle(bool &diffraction)
Compute the solid angle associated with the ray (depends on the type of source which generated the ra...
Definition: Ray.cpp:278
Source * source
Pointer to the source of the ray.
Definition: Ray.h:509
vector< unsigned int > getPrimitiveHistory()
Return the array of primitives id encountered by the ray.
Definition: Ray.cpp:253
void * recepteur
Pointer to the receptor of the ray.
Definition: Ray.h:510
vector< unsigned int > getEventSignature()
Definition: Ray.cpp:309
decimal getThickness(const decimal &distance, bool diffraction)
Compute the thickness of the ray after having traveled a certain distance depending on the type of so...
Definition: Ray.cpp:266
vec3 getPosition() const
Return starting point ray.
Definition: Ray.h:356
Base * getLastPertinentEventOrSource(typeevent evType=DIFFRACTION)
Return a pointer to the last event of type evType or source if none.
Definition: Ray.cpp:225
signature getSignature(const typeevent &typeEv=SPECULARREFLEXION)
Compute the signature (i.e. std::pair<unsigned int, unsigned int>) of the ray)
Definition: Ray.cpp:301
vector< unsigned int > getFaceHistory()
Return the array of faces id encountered by the ray.
Definition: Ray.cpp:240
bitSet getEventsBitSet(const typeevent &typeEv)
Compute the bitSet associated with a list of events of type evType.
Definition: Ray.cpp:322
decimal computePertinentLength(const vec3 &ref, const vec3 &lastPos, vec3 &closestPoint)
Compute ray length from last pertinent event (i.e. source or last diffraction) to the nearest point o...
Definition: Ray.cpp:149
decimal longueur
Distance traveled by the ray.
Definition: Ray.h:511
decimal computeEventsSequenceLength()
Compute the length of the sequence of events.
Definition: Ray.cpp:76
void computeLongueur()
Compute the distance traveled (length) by the ray and the result is set into the longueur attribute.
Definition: Ray.cpp:24
Receptor inherits from a Sphere Shape.
Definition: Recepteur.h:28
Acoustic source class.
Definition: Source.h:33
int getInitialRayCount()
Get the initial rays counter.
Definition: Source.h:140
vec3 getPosition()
Get the position of the Source.
Definition: Source.h:105
unsigned int getId()
Get the Source id.
Definition: Source.h:161
#define M_PI
Pi.
Definition: color.cpp:25
#define M_4PI
Definition: mathlib.h:75
float decimal
Definition: mathlib.h:45
base_vec3< decimal > vec3
Definition: mathlib.h:381
unsigned int bitSet
Definition: mathlib.h:47