51 _useSol = config->UseRealGround;
57 double pression = config->AtmosPressure;
58 double temperature = config->AtmosTemperature;
59 double hygrometrie = config->AtmosHygrometry;
75 bool vertical =
true, horizontal =
false;
80 bool conditionFav =
false;
84 assert(config->DSWindDirection >= 0 && config->DSWindDirection <= 360);
86 double windRadian =
DEGTORAD(config->DSWindDirection);
89 propaDirection.
_z = 0;
90 double angle =
RADTODEG(acos(windDirection.
dot(propaDirection)/(windDirection.
norme()*propaDirection.
norme())));
91 assert(180 >= angle >= 0);
92 assert(180 >= config->AngleFavorable >= 0);
94 if (angle <= config->AngleFavorable)
100 conditionFav =
false;
122 if (tabChemins.size() == 0)
140 tabCheminsSansEcran.clear();
161 tabEtapes.push_back(etape1);
166 TabChemins.push_back(chemin1);
190 ptSym.
_z = 2 * penteMoyenne.
_ptA.
_z - ptSym.
_z;
204 tabEtapes.push_back(etape2);
209 etape3.
_pt = ptReflex;
224 tabEtapes.push_back(etape3);
229 TabChemins.push_back(chemin2);
257 tabEtapes.push_back(Etapes[0]);
261 TabChemin.push_back(chemin) ;
267 tabEtapes.push_back(Etapes[1]);
268 tabEtapes.push_back(Etapes[2]);
272 TabChemin.push_back(chemin);
284 double hauteurA = 0.0, hauteurB = 0.0;
288 if (res == 0) {ptProj = penteMoyenne.
_ptA;}
289 hauteurA = rayon.
_ptA.
_z - ptProj.
_z;
291 if (res == 0) {ptProj = penteMoyenne.
_ptB;}
292 hauteurB = rayon.
_ptB.
_z - ptProj.
_z;
298 hauteurA = rayon.
_ptA.
_z - ptProj.
_z;
301 hauteurB = rayon.
_ptB.
_z - ptProj.
_z;
306 if (rayon.
longueur() > (10 * (hauteurA + hauteurB)))
326 double distRef =
_paramH * hauteurA;
331 if (res == 0) {projA = penteMoyenne.
_ptA;}
349 tabEtapes.push_back(etape);
352 etape.
_pt = ptReflex;
369 tabEtapes.push_back(etape);
375 TabChemin.push_back(chemin) ;
390 if (res == 0) {projB = penteMoyenne.
_ptB;}
406 tabEtapes.push_back(etape);
409 etape.
_pt = ptReflex;
428 tabEtapes.push_back(etape);
434 TabChemin.push_back(chemin) ;
450 if (pts.size() <= 1) {
return false; }
456 OPoint3D lastPt(pts[pts.size() - 1]);
459 double longTwoReflex = 0.0 ;
462 double longOneReflexBefore = 0.0;
465 double longOneReflexAfter = 0.0;
468 double longNoReflex = 0.0;
477 double tempLong = segCourant.
longueur();
479 bool bCheminOk =
addEtapesSol(rayon.
_ptA, firstPt, penteMoyenneTotale, source,
true,
false, Etapes, rr);
482 if (!bCheminOk) {
return true; }
484 tabNoReflex.push_back(Etapes[0]);
485 longNoReflex += tempLong;
487 tabOneReflexAfter.push_back(Etapes[0]);
488 longOneReflexAfter += tempLong;
490 tabOneReflexBefore.push_back(Etapes[1]);
491 tabOneReflexBefore.push_back(Etapes[2]);
492 longOneReflexBefore += rr;
494 tabTwoReflex.push_back(Etapes[1]);
495 tabTwoReflex.push_back(Etapes[2]);
502 double epaisseur = 0.0;
505 for (
unsigned int i = 1; i < pts.size() - 1; i++)
507 epaisseur += (
OSegment3D(pts[i], pts[i + 1])).longueur();
513 tabTwoReflex.push_back(Etape);
514 tabOneReflexBefore.push_back(Etape);
515 tabOneReflexAfter.push_back(Etape);
516 tabNoReflex.push_back(Etape);
519 longNoReflex += epaisseur;
520 longOneReflexAfter += epaisseur;
521 longOneReflexBefore += epaisseur;
522 longTwoReflex += epaisseur;
528 addEtapesSol(lastPt, rayon.
_ptB, penteMoyenneTotale, source,
false,
true, Etapes, rr);
530 tabNoReflex.push_back(Etapes[0]);
531 longNoReflex += tempLong;
533 tabOneReflexBefore.push_back(Etapes[0]);
534 longOneReflexBefore += tempLong;
536 tabOneReflexAfter.push_back(Etapes[1]);
537 tabOneReflexAfter.push_back(Etapes[2]);
538 longOneReflexAfter += rr;
540 tabTwoReflex.push_back(Etapes[1]);
541 tabTwoReflex.push_back(Etapes[2]);
555 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
false, longNoReflex, epaisseur, vertical,
false, bDiffOk, conditionFav);
557 tabNoReflex.push_back(Etape);
560 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
false, longTwoReflex, epaisseur, vertical,
false, bDiffOk, conditionFav);
562 tabTwoReflex.push_back(Etape);
565 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
true, longOneReflexBefore, epaisseur, vertical,
false, bDiffOk, conditionFav);
567 tabOneReflexBefore.push_back(Etape);
570 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
true, longOneReflexAfter, epaisseur, vertical,
true, bDiffOk,conditionFav);
572 tabOneReflexAfter.push_back(Etape);
583 TabChemins.push_back(chemin);
588 TabChemins.push_back(chemin);
593 TabChemins.push_back(chemin);
598 TabChemins.push_back(chemin);
600 tabTwoReflex.clear();
601 tabOneReflexBefore.clear();
602 tabOneReflexAfter.clear();
623 EtapeCourante.
_pt = ptDebut;
636 Etapes.push_back(EtapeCourante);
645 if (pt2.
_x != pt1.
_x)
648 pt3.
_x = (pt1.
_y - pt2.
_y) * (pt3.
_y - pt1.
_y) / (pt2.
_x - pt1.
_x) + (pt1.
_x);
652 if (pt1.
_y != pt2.
_y)
655 pt3.
_y = (pt2.
_x - pt1.
_x) * (pt3.
_x - pt1.
_x) / (pt1.
_y - pt2.
_y) + (pt1.
_y);
662 pt3.
_x = (pt1.
_y - pt2.
_y) * (pt3.
_y - pt1.
_y) / (pt2.
_x - pt1.
_x) + (pt1.
_x);
666 OPlan planPenteMoyenne(pt1, pt2, pt3);
682 EtapeCourante.
_pt = ptDebut;
709 ptSymFin.
_z = 2 * segPente.
_ptB.
_z - ptSymFin.
_z;
717 double coefH = (d1 + d2) != 0 ? d1 / (d2 + d1) : 0.0;
720 ptReflex.
_x = (ptSymFin.
_x - ptSym.
_x) * coefH + ptSym.
_x;
721 ptReflex.
_y = (ptSymFin.
_y - ptSym.
_y) * coefH + ptSym.
_y;
722 ptReflex.
_z = (ptSymFin.
_z - ptSym.
_z) * coefH + ptSym.
_z;
748 Etapes.push_back(EtapeCourante);
751 EtapeCourante.
_pt = ptReflex;
767 Etapes.push_back(EtapeCourante);
769 else if (fromSource || toRecepteur)
777 Etapes.push_back(EtapeCourante);
780 EtapeCourante.
_pt = ptReflex;
796 Etapes.push_back(EtapeCourante);
809 double distance )
const 824 size_t nbFaces = tabIntersect.size();
827 for (
unsigned int i = 0; i < nbFaces; i++)
845 segMontant.
_ptB = pt;
847 segDescendant.
_ptA = segMontant.
_ptB;
850 bool intersect =
false;
854 while ((j < nbFaces) && (!intersect))
862 segInter = tabIntersect[j].segInter[1];
882 SpectreAbso = SpectreAbso.
mult(-1.0).
sum(1.0);
912 tabEtapes.push_back(Etape);
915 Etape.
_pt = segDescendant.
_ptA;
919 tabEtapes.push_back(Etape);
927 TabChemins.push_back(Chemin);
943 if (epaisseur < 1.0E-2)
949 const double unTiers = 1.0 / 3.0;
952 opLambda = opLambda.
mult(opLambda);
954 C = opLambda.
sum(1.0);
955 C = C.
div(opLambda.
sum(unTiers));
984 ptSym.
_z = 2 * penteMoyenne.
_ptA.
_z - ptSym.
_z;
999 ptSym.
_z = 2 * penteMoyenne.
_ptB.
_z - ptSym.
_z;
1014 double gamma = rd * 8.0;
1015 gamma = (gamma > 1000 ? gamma : 1000.0);
1017 double alpha = 2 * asin(rd / (2 * gamma));
1022 double delta = re - rd ;
1023 delta = delta <= 0 ? 0.0 : delta;
1049 double lim20dB = pow(10.0, (20.0 / 10.0));
1050 double lim25dB = pow(10.0, (25.0 / 10.0));
1051 double lim0dB = pow(10.0, (0.0 / 10.0));
1055 for (
unsigned int i = 0 ; i < sNC.
getNbValues() ; i++)
1059 valeur = valeur < lim0dB ? lim0dB : valeur ;
1063 valeur = valeur > lim20dB ? lim20dB : valeur;
1067 valeur = valeur > lim25dB ? lim25dB : valeur;
1079 const double PIM4 = 4.0 *
M_PI;
1085 double divGeom =
pSolverAtmos->compute_z() / (PIM4 * rD2);
1114 Ray ray1( start,
vec3(0., 0., -1.) );
1117 std::list<Intersection> LI;
1124 Ray ray1( start,
vec3(0., 0., -1.) );
1129 assert(!LI.empty());
1130 unsigned int indexFace = LI.begin()->p->getPrimitiveId();
1140 std::list<Intersection> LI2;
1145 indexFace = LI2.begin()->p->getPrimitiveId();
1174 Ray ray1( start,
vec3(0., 0., -1.) );
1176 std::list<Intersection> LI;
1179 assert( distance1 > 0. );
1180 assert(!LI.empty());
1182 unsigned int indexFace = LI.begin()->p->getPrimitiveId();
1190 std::list<Intersection> LI2;
1193 if (LI2.empty() || distance < 0.)
1195 distance1 += distance;
1196 indexFace = LI2.begin()->p->getPrimitiveId();
1204 Ray ray2( start,
vec3(0., 0., -1.) );
1208 assert( distance2 > 0. );
1209 assert(!LI.empty());
1211 indexFace = LI.begin()->p->getPrimitiveId();
1219 std::list<Intersection> LI2;
1222 if (LI2.empty() || distance < 0.)
1224 distance2 += distance;
1225 indexFace = LI2.begin()->p->getPrimitiveId();
OSpectre _Attenuation
attenuation Spectrum
void setType(const int &type)
Change the path type.
static OSpectre getLambda(const double &c)
Describes building material.
void init()
Initialize the acoustic model.
const std::vector< TYStructSurfIntersect > & getTabPolygon() const
Get the array of polygons.
Accelerator * getAccelerator() const
Get the accelerator.
Representation of one of the most optimal path between source and receptor: S—>R. The class TYChemin represents a path between a Source and a receptor (Recepteur class). It's constituted of a collection of steps (TYEtape class).
The TYEtape class is used to describe a part (a step) of a path (TYChemin) for the computation of tra...
static OSpectre getEmptyLinSpectre(const double &valInit=1.0E-20)
Create a physical quantity spectrum.
virtual OSpectre sum(const OSpectre &spectre) const
Arithmetic sum of two spectrums in one-third Octave.
virtual ComplexSpectrum get_absorption(double incidence_angle, double length)
Virtual method to return material absorption at reflection point.
void normalize()
Normalizes this vector.
void computeCheminReflexion(const std::deque< TYSIntersection > &tabIntersect, const OSegment3D &rayon, const tympan::AcousticSource &source, TYTabChemin &TabChemins, double distance) const
Compute the list of path generated by reflection on the vertical walls.
OSpectre getPInterference(const AtmosphericConditions &atmos)
Compute the quadratic pressure on the journey.
virtual int symetrieOf(const OPoint3D &pt, OPoint3D &ptSym) const
Return the symmetrical of a point.
OPoint3D _ptB
Point B of the segment.
OPoint3D _ptA
Point A of the segment.
double distFrom(const OPoint3D &pt) const
Computes the distance from this point to another.
This file provides class for solver configuration.
base_vec3< decimal > vec3
std::vector< OPoint3D > TabPoint3D
virtual double longueur() const
Return the segment length.
void setPoint(const OPoint3D &pt)
OSpectre limAttDiffraction(const OSpectre &sNC, const OSpectre &C) const
Limit the screen attenuation value with a frequency dependent criteria.
OSpectreComplex getReflexionSpectrumAt(const OSegment3D &incident, double length, const OSegment3D &segPente, const tympan::AcousticSource &source) const
Find Reflexion spectrum at point defined by the end of an incident segment.
std::deque< TYChemin > TYTabChemin
TYChemin collection.
std::complex< double > TYComplex
OSpectre getPEnergetique(const AtmosphericConditions &atmos)
Compute the acoustic pressure (phase modulation) on the journey.
double norme() const
Computes the length of this vector.
double getDistance()
Get/Set the distance between source and receptor.
virtual OSpectre invMult(const double &coefficient=1.0) const
Division of a double constant by this spectrum.
bool bIntersect[2]
Flag to indicate the face cuts vertical plane ([0]) or horizontal plane ([1])
virtual OSpectre div(const OSpectre &spectre) const
Division of two spectrums.
virtual decimal traverse(Ray *r, std::list< Intersection > &result) const
Run this accelerator.
OSpectre & getSpectre()
Get/Set the spectrum at the receptor point.
virtual unsigned int getNbValues() const
Number of values in the spectrum.
virtual void setType(TYSpectreType type)
Set the spectrum type.
TYTabChemin & getCheminsDirect()
Return an array of the direct paths.
OPoint3D _pt
The starting point of this step.
3D vector Vector defined with 3 float numbers
virtual void compute(const std::deque< TYSIntersection > &tabIntersect, TYTrajet &trajet, TabPoint3D &ptsTop, TabPoint3D &ptsLeft, TabPoint3D &ptsRight)
void getPtSetPtRfromOSeg3D(OSegment3D &seg) const
TYTabChemin & getChemins()
Return the collection of paths of *this.
virtual ~TYAcousticModel()
This class TYTrajet (journey) links a couple Source-Receptor and a collection of paths, in addition to the direct path.
double _y
y coordinate of OCoord3D
double _x
x coordinate of OCoord3D
Plan defined by its equation : ax+by+cz+d=0.
double DEGTORAD(double a)
Converts an angle from degrees to radians.
virtual Spectrum lwAdjustment(Vector direction, double distance)=0
< Pure virtual method to return directivity of the Source
const Scene * getScene() const
Get the Scene.
virtual bool computeCheminsAvecEcran(const OSegment3D &rayon, const tympan::AcousticSource &source, const TabPoint3D &pts, const bool vertical, TYTabChemin &TabChemins, double distance, bool conditionFav=false) const
Compute the segment path from the list of the points of the TYTrajet journey. It takes in account the...
: Describes a ray by a pair of unsigned int. The first one gives the source number (in the range 0-40...
OSpectreComplex _absoNulle
bool isInfra
Flag to define if is a infrastructure face.
void calcAttenuation(const TYTabEtape &tabEtapes, const AtmosphericConditions &atmos)
Compute the global attenuation on the path.
void setMaxt(decimal _maxt)
set the maxt
TYAcousticModel(TYSolver &solver)
OSpectre calculAttDiffraction(const OSegment3D &rayon, const OSegment3D &penteMoyenne, const bool &miroir, const double &re, const double &epaisseur, const bool &vertical, const bool &avantApres, bool &bDiffOk, bool conditionFav=false) const
Compute the attenuation from the diffraction on the screen.
vec3 OPoint3Dtovec3(const OPoint3D &_p)
Converts a OPoint3D to vec3.
tympan::AcousticMaterialBase * material
Pointer to a material.
OSpectre calculC(const double &epaisseur) const
Compute the spectrum of the C factor used in the diffraction calculation.
Spectrum spectrum
Associated spectrum.
Data structure for intersections.
TYSolver & _solver
Reference to the solver.
void meanSlope(const OSegment3D &director, OSegment3D &slope) const
Create a segment corresponding to the projection of "director" segment on the ground.
Class to define a segment.
double RADTODEG(double a)
Converts an angle from radians to degrees.
int intersectsSegment(const OPoint3D &pt1, const OPoint3D &pt2, OPoint3D &ptIntersec) const
Calculate the intersection of this plane with a segment defined by two points.
void setDistance(const double &distance)
boost::shared_ptr< SolverConfiguration > LPSolverConfiguration
std::deque< TYEtape > TYTabEtape
TYEtape collection.
void setLongueur(const double &longueur)
virtual double * getTabValReel()
SourceDirectivityInterface * directivity
Pointer to the source directivity.
virtual int projection(const OPoint3D &pt, OPoint3D &ptProj, double seuilConfondus) const
Return the projection of a point.
std::unique_ptr< AtmosphericConditions > pSolverAtmos
ACOUSTIC_EVENT_TYPES _type
Acoustic event type.
Describes an acoustic source.
bool addEtapesSol(const OPoint3D &ptDebut, const OPoint3D &ptFin, const OSegment3D &penteMoyenne, const tympan::AcousticSource &source, const bool &fromSource, const bool &toRecepteur, TYTabEtape &Etapes, double &longueur) const
Compute the different steps from a point to another via a reflection and a direct view...
virtual OVector3D toVector3D() const
Build a OVector3D from a segment used for the direction of the sources.
virtual OSpectre mult(const OSpectre &spectre) const
Multiplication of two spectrums.
Class for the definition of atmospheric conditions.
OSegment3D segInter[2]
Intersection segment between face and vertical plane ([0]) and horizontal plane ([1]) ...
bool solve(TYTrajet &trajet)
Compute the source contribution to the point.
double _z
z coordinate of OCoord3D
virtual OSpectre racine() const
Compute the root square of this spectrum.
void computeCheminSansEcran(const OSegment3D &rayon, const tympan::AcousticSource &source, TYTabChemin &TabChemins, double distance, bool conditionFav=false) const
Compute the list of paths generated by reflection on the ground if there is no screen.
Store acoustic power values for different frequencies.
OSpectreComplex _Absorption
absorption Spectrum
string volume_id
Volume id.
void computeCheminAPlat(const OSegment3D &rayon, const tympan::AcousticSource &source, TYTabChemin &TabChemins, double distance) const
Compute the list of paths for a perfectly flat and reflective ground.
virtual int intersects(const OSegment3D &seg, OPoint3D &pt, double seuilConfondus) const
Return the intersection point with another segment.
virtual void setDefaultValue(const double &valeur=TY_SPECTRE_DEFAULT_VALUE)
double dot(const OVector3D &v)
dot product (assuming an orthonormal reference frame)
static LPSolverConfiguration get()
Get the configuration.
tympan::AcousticSource & asrc
Business source.