Code_TYMPAN  4.4.0
Industrial site acoustic simulation
Ray.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012-2024> <EDF-DTG> <FRANCE>
3  * This file is part of Code_TYMPAN (R).
4  * Code_TYMPAN (R) is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * Code_TYMPAN (R) is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  * You should have received a copy of the GNU General Public License along
13  * with Code_TYMPAN (R). If not, see <https://www.gnu.org/licenses/>.
14  */
15 
16 #include <cassert>
17 #include <vector>
18 #include "Geometry/Cylindre.h"
19 #include "Acoustic/Recepteur.h"
20 #include "Ray.h"
21 
23 {
24  if (source == NULL)
25  {
26  std::cerr << "Error : ray without source or receptor computeLongueur" << std::endl;
27  return;
28  }
29 
30  longueur = 0;
31 
32  if (events.size() == 0) // No events
33  {
34 
35  if (recepteur == NULL)
36  {
37  // If the ray has not reached a receptor, the length is 0
38  longueur = 0;
39  return;
40  }
41  else
42  {
43 
44  // If the ray has reached a receptor, the length is the distance between the source dans the
45  // receptor
46  vec3 posSource = vec3(source->getPosition());
47  vec3 posRecep = vec3(((Recepteur*)(recepteur))->getPosition());
48  longueur = posSource.distance(posRecep);
49  return;
50  }
51  }
52  else
53  { // Ray has some events
54 
55  longueur = 0;
56 
57  // Distance from source to first event
58  longueur = source->getPosition().distance(events.front()->getPosition());
59 
60  // Add length of events sequence
62 
63  // If the ray has reached a receptor, add the distance from the last event to the receptor
64  if (recepteur != NULL)
65  {
66  vec3 posLastEvent = vec3(events.back()->getPosition());
67  vec3 posRecepteur = vec3(((Recepteur*)(recepteur))->getPosition());
68  longueur += posLastEvent.distance(posRecepteur);
69  }
70  return;
71  }
72 }
73 
75 {
76  // Sum the distance between each event
77  decimal length = 0;
78 
79  if (events.size() == 0)
80  {
81  return 0;
82  }
83 
84  std::vector<boost::shared_ptr<Event>>::iterator iter = events.begin();
85 
86  vec3 previous = (*iter)->getPosition();
87  vec3 current(0., 0., 0.);
88 
89  iter++;
90  while (iter != events.end())
91  {
92  current = (*iter)->getPosition();
93  length += current.distance(previous);
94  previous = current;
95  iter++;
96  };
97 
98  return length;
99 }
100 
101 decimal Ray::computeTrueLength(const vec3& ref, const vec3& lastPos, vec3& closestPoint)
102 {
103  if (source == NULL)
104  {
105  std::cerr << "Error : ray without source or receptor computeTrueLength" << std::endl;
106  return 0.;
107  }
108 
109  decimal length = 0.;
110  vec3 posSource = source->getPosition();
111  vec3 posLastEvent;
112  switch (events.size())
113  {
114  // Ray has no events
115  case 0:
116  // Compute the projection of ref on the line passing by posSource and lastPos
117  closestPoint = ref.closestPointOnLine(posSource, lastPos);
118 
119  // Compute the distance between the source and closestPoint
120  return posSource.distance(closestPoint);
121  break;
122 
123  // Ray has some events
124  default:
125  // Distance from source to first event
126  length = source->getPosition().distance(events.front()->getPosition());
127 
128  // Add length of events sequence
129  length += computeEventsSequenceLength();
130 
131  // Find last event's position
132  posLastEvent = events.back()->getPosition();
133 
134  // Compute the projection of ref on the line passing by posLastEvent and lastPos
135  closestPoint = ref.closestPointOnLine(posLastEvent, lastPos);
136 
137  // Add the distance between closestPoint and the position of the last event to the length and
138  // return the trueLength
139  return length += closestPoint.distance(posLastEvent);
140 
141  break;
142  }
143 
144  return 0.;
145 }
146 
147 decimal Ray::computePertinentLength(const vec3& ref, const vec3& lastPos, vec3& closestPoint)
148 {
149  if (source == NULL)
150  {
151  std::cerr << "Error : ray without source (computePertinentLength)" << std::endl;
152  return 0.;
153  }
154 
155  decimal pertinent_length = 0.;
156 
157  vec3 posLastEvent;
158  vec3 current(0., 0., 0.), previous(0., 0., 0.);
159 
160  Source* s = NULL;
161  Event* e = NULL;
162 
163  // Get the last diffraction event, or source if theray has no diffraction event
164  Base* pertinentEvent = getLastPertinentEventOrSource();
165 
166  switch (events.size())
167  {
168  case 0:
169  // if no the ray has no events, simply compute the full (true) length
170  return computeTrueLength(ref, lastPos, closestPoint);
171  break;
172 
173  default:
174  s = dynamic_cast<Source*>(pertinentEvent);
175 
176  // if pertinentEvent is the source, simply compute the full (true) length
177  if (s)
178  {
179 
180  return computeTrueLength(ref, lastPos, closestPoint);
181  }
182 
183  // if pertinentEvent is not the source
184  else
185  {
186 
187  // Recover the pertinent event
188  e = dynamic_cast<Event*>(pertinentEvent);
189 
190  if (e)
191  {
192 
193  // Get the last event (begining of the reverse iterator)
194  std::vector<boost::shared_ptr<Event>>::reverse_iterator rit = events.rbegin();
195  // Get the position of the lastEvent
196  previous = (*rit)->getPosition();
197 
198  // Compute the length from the last event to pertinentEvent
199  while ((rit != events.rend()) && ((*rit).get() != e))
200  {
201  rit++;
202  current = (*rit)->getPosition();
203  pertinent_length += current.distance(previous);
204  previous = current;
205  }
206 
207  // Get the position of last event
208  posLastEvent = vec3(events.back()->getPosition());
209  // Compute the projection of ref on the line passing by posLastEvent and lastPos
210  closestPoint = ref.closestPointOnLine(posLastEvent, lastPos);
211 
212  // Return the distance from the last event to the projection of ref
213  return (pertinent_length += closestPoint.distance(posLastEvent));
214  }
215  }
216 
217  break;
218  }
219 
220  return 0.;
221 }
222 
224 {
225  Base* res = (Base*)source;
226 
227  for (std::vector<boost::shared_ptr<Event>>::iterator iter = events.begin(); iter != events.end(); ++iter)
228  {
229  if ((*iter)->getType() == evType)
230  {
231  res = (Base*)((*iter).get());
232  }
233  }
234 
235  return res;
236 }
237 
238 std::vector<unsigned int> Ray::getFaceHistory()
239 {
240  std::vector<unsigned int> result;
241  result.push_back(source->getId());
242  for (unsigned int i = 0; i < events.size(); i++)
243  {
244  result.push_back(events.at(i)->getShape()->getFaceId());
245  }
246 
247  result.push_back(((Recepteur*)recepteur)->getId());
248  return result;
249 }
250 
251 std::vector<unsigned int> Ray::getPrimitiveHistory()
252 {
253  std::vector<unsigned int> result;
254  result.push_back(source->getId());
255  for (unsigned int i = 0; i < events.size(); i++)
256  {
257  result.push_back(events.at(i)->getShape()->getPrimitiveId());
258  }
259 
260  result.push_back(((Recepteur*)recepteur)->getId());
261  return result;
262 }
263 
264 decimal Ray::getThickness(const decimal& distance, bool diffraction)
265 {
266  decimal angle = getSolidAngle(diffraction);
267 
268  if (diffraction)
269  {
270  return distance * angle;
271  }
272 
273  return (decimal)(2. * distance * sqrt(angle / M_PI));
274 }
275 
276 decimal Ray::getSolidAngle(bool& diffraction)
277 {
278  unsigned int nb_rays = source->getInitialRayCount();
279 
280  if (diffraction)
281  {
283  Event* e = dynamic_cast<Event*>(last);
284 
285  if (e && (e->getType() == DIFFRACTION))
286  {
287  return (decimal)(dynamic_cast<Diffraction*>(e)->getAngle() * M_2PI /
289  }
290  else // else is done to be explicit
291  {
292  diffraction = false;
293  }
294  }
295 
296  return M_4PI / static_cast<decimal>(nb_rays);
297 }
298 
300 {
301  bitSet SR = getSRBitSet(source->getId(), (static_cast<Recepteur*>(recepteur))->getId());
302  bitSet SD = getEventsBitSet(typeEv);
303 
304  return std::make_pair(SR, SD);
305 }
306 
307 std::vector<unsigned int> Ray::getEventSignature()
308 {
309  std::vector<unsigned int> signature;
310  signature.push_back(source->getId());
311 
312  for (size_t i = 0; i < events.size(); i++)
313  signature.push_back(events.at(i)->getType());
314 
315  signature.push_back(((Recepteur*)recepteur)->getId());
316 
317  return signature;
318 }
319 
321 {
322  bitSet SD = 0;
323  for (size_t i = 0; i < events.size(); i++)
324  {
325  SD = SD << 1;
326 
327  if (events.at(i)->getType() == typeEv)
328  {
329  SD++;
330  }
331  }
332 
333  return SD;
334 }
#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:101
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:276
Source * source
Pointer to the source of the ray.
Definition: Ray.h:509
std::vector< unsigned int > getPrimitiveHistory()
Return the array of primitives id encountered by the ray.
Definition: Ray.cpp:251
void * recepteur
Pointer to the receptor of the ray.
Definition: Ray.h:510
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:264
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:223
std::vector< unsigned int > getEventSignature()
Definition: Ray.cpp:307
signature getSignature(const typeevent &typeEv=SPECULARREFLEXION)
Compute the signature (i.e. std::pair<unsigned int, unsigned int>) of the ray)
Definition: Ray.cpp:299
std::vector< unsigned int > getFaceHistory()
Return the array of faces id encountered by the ray.
Definition: Ray.cpp:238
bitSet getEventsBitSet(const typeevent &typeEv)
Compute the bitSet associated with a list of events of type evType.
Definition: Ray.cpp:320
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:147
decimal longueur
Distance traveled by the ray.
Definition: Ray.h:511
decimal computeEventsSequenceLength()
Compute the length of the sequence of events.
Definition: Ray.cpp:74
void computeLongueur()
Compute the distance traveled (length) by the ray and the result is set into the longueur attribute.
Definition: Ray.cpp:22
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:81
float decimal
Definition: mathlib.h:45
base_vec3< decimal > vec3
Definition: mathlib.h:387
unsigned int bitSet
Definition: mathlib.h:47