33 : _useSol(true), _useReflex(false), _propaCond(0), _interference(false), _paramH(10.0), _solver(solver)
45 _useSol = config->UseRealGround;
51 double pression = config->AtmosPressure;
52 double temperature = config->AtmosTemperature;
53 double hygrometrie = config->AtmosHygrometry;
56 std::unique_ptr<AtmosphericConditions>(
new AtmosphericConditions(pression, temperature, hygrometrie));
68 bool vertical =
true, horizontal =
false;
73 bool conditionFav =
false;
77 assert(config->DSWindDirection >= 0 && config->DSWindDirection <= 360);
79 double windRadian =
DEGTORAD(config->DSWindDirection);
82 propaDirection.
_z = 0;
85 (windDirection.
norme() * propaDirection.
norme())));
86 assert(180 >= angle >= 0);
87 assert(180 >= config->AngleFavorable >= 0);
89 if (angle <= config->AngleFavorable)
116 if (tabChemins.size() == 0)
134 tabCheminsSansEcran.clear();
157 tabEtapes.push_back(etape1);
162 TabChemins.push_back(chemin1);
186 ptSym.
_z = 2 * penteMoyenne.
_ptA.
_z - ptSym.
_z;
195 double rr = seg1.longueur();
201 tabEtapes.push_back(etape2);
206 etape3.
_pt = ptReflex;
221 tabEtapes.push_back(etape3);
226 TabChemins.push_back(chemin2);
232 TYTabChemin& TabChemin,
double distance,
bool conditionFav)
const
254 tabEtapes.push_back(Etapes[0]);
258 TabChemin.push_back(chemin);
264 tabEtapes.push_back(Etapes[1]);
265 tabEtapes.push_back(Etapes[2]);
269 TabChemin.push_back(chemin);
281 double hauteurA = 0.0, hauteurB = 0.0;
287 ptProj = penteMoyenne.
_ptA;
289 hauteurA = rayon.
_ptA.
_z - ptProj.
_z;
293 ptProj = penteMoyenne.
_ptB;
295 hauteurB = rayon.
_ptB.
_z - ptProj.
_z;
301 hauteurA = rayon.
_ptA.
_z - ptProj.
_z;
304 hauteurB = rayon.
_ptB.
_z - ptProj.
_z;
309 if (rayon.
longueur() > (10 * (hauteurA + hauteurB)))
328 double distRef =
_paramH * hauteurA;
335 projA = penteMoyenne.
_ptA;
356 tabEtapes.push_back(etape);
359 etape.
_pt = ptReflex;
376 tabEtapes.push_back(etape);
382 TabChemin.push_back(chemin);
399 projB = penteMoyenne.
_ptB;
418 tabEtapes.push_back(etape);
421 etape.
_pt = ptReflex;
439 tabEtapes.push_back(etape);
445 TabChemin.push_back(chemin);
455 bool conditionFav)
const
471 OPoint3D lastPt(pts[pts.size() - 1]);
474 double longTwoReflex = 0.0;
477 double longOneReflexBefore = 0.0;
480 double longOneReflexAfter = 0.0;
483 double longNoReflex = 0.0;
492 double tempLong = segCourant.longueur();
494 bool bCheminOk =
addEtapesSol(rayon.
_ptA, firstPt, penteMoyenneTotale, source,
true,
false, Etapes,
504 tabNoReflex.push_back(Etapes[0]);
505 longNoReflex += tempLong;
507 tabOneReflexAfter.push_back(Etapes[0]);
508 longOneReflexAfter += tempLong;
510 tabOneReflexBefore.push_back(Etapes[1]);
511 tabOneReflexBefore.push_back(Etapes[2]);
512 longOneReflexBefore += rr;
514 tabTwoReflex.push_back(Etapes[1]);
515 tabTwoReflex.push_back(Etapes[2]);
522 double epaisseur = 0.0;
525 for (
unsigned int i = 1; i < pts.size() - 1; i++)
527 epaisseur += (
OSegment3D(pts[i], pts[i + 1])).longueur();
533 tabTwoReflex.push_back(Etape);
534 tabOneReflexBefore.push_back(Etape);
535 tabOneReflexAfter.push_back(Etape);
536 tabNoReflex.push_back(Etape);
539 longNoReflex += epaisseur;
540 longOneReflexAfter += epaisseur;
541 longOneReflexBefore += epaisseur;
542 longTwoReflex += epaisseur;
546 tempLong = segCourant.longueur();
548 addEtapesSol(lastPt, rayon.
_ptB, penteMoyenneTotale, source,
false,
true, Etapes, rr);
550 tabNoReflex.push_back(Etapes[0]);
551 longNoReflex += tempLong;
553 tabOneReflexBefore.push_back(Etapes[0]);
554 longOneReflexBefore += tempLong;
556 tabOneReflexAfter.push_back(Etapes[1]);
557 tabOneReflexAfter.push_back(Etapes[2]);
558 longOneReflexAfter += rr;
560 tabTwoReflex.push_back(Etapes[1]);
561 tabTwoReflex.push_back(Etapes[2]);
575 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
false, longNoReflex, epaisseur, vertical,
false,
576 bDiffOk, conditionFav);
578 tabNoReflex.push_back(Etape);
581 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
false, longTwoReflex, epaisseur, vertical,
false,
582 bDiffOk, conditionFav);
584 tabTwoReflex.push_back(Etape);
587 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
true, longOneReflexBefore, epaisseur, vertical,
588 false, bDiffOk, conditionFav);
590 tabOneReflexBefore.push_back(Etape);
593 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
true, longOneReflexAfter, epaisseur, vertical,
594 true, bDiffOk, conditionFav);
596 tabOneReflexAfter.push_back(Etape);
607 TabChemins.push_back(chemin);
612 TabChemins.push_back(chemin);
617 TabChemins.push_back(chemin);
622 TabChemins.push_back(chemin);
624 tabTwoReflex.clear();
625 tabOneReflexBefore.clear();
626 tabOneReflexAfter.clear();
635 const bool& fromSource,
const bool& toRecepteur,
TYTabEtape& Etapes,
649 EtapeCourante.
_pt = ptDebut;
663 Etapes.push_back(EtapeCourante);
672 if (pt2.
_x != pt1.
_x)
675 pt3.
_x = (pt1.
_y - pt2.
_y) * (pt3.
_y - pt1.
_y) / (pt2.
_x - pt1.
_x) + (pt1.
_x);
679 if (pt1.
_y != pt2.
_y)
682 pt3.
_y = (pt2.
_x - pt1.
_x) * (pt3.
_x - pt1.
_x) / (pt1.
_y - pt2.
_y) + (pt1.
_y);
689 pt3.
_x = (pt1.
_y - pt2.
_y) * (pt3.
_y - pt1.
_y) / (pt2.
_x - pt1.
_x) + (pt1.
_x);
693 OPlan planPenteMoyenne(pt1, pt2, pt3);
698 OPoint3D(ptDebut.
_x, ptDebut.
_y, -100000), ptDebutProj);
710 EtapeCourante.
_pt = ptDebut;
737 ptSymFin.
_z = 2 * segPente.
_ptB.
_z - ptSymFin.
_z;
745 double coefH = (d1 + d2) != 0 ? d1 / (d2 + d1) : 0.0;
748 ptReflex.
_x = (ptSymFin.
_x - ptSym.
_x) * coefH + ptSym.
_x;
749 ptReflex.
_y = (ptSymFin.
_y - ptSym.
_y) * coefH + ptSym.
_y;
750 ptReflex.
_z = (ptSymFin.
_z - ptSym.
_z) * coefH + ptSym.
_z;
777 Etapes.push_back(EtapeCourante);
780 EtapeCourante.
_pt = ptReflex;
796 Etapes.push_back(EtapeCourante);
798 else if (fromSource || toRecepteur)
806 Etapes.push_back(EtapeCourante);
809 EtapeCourante.
_pt = ptReflex;
825 Etapes.push_back(EtapeCourante);
856 size_t nbFaces = tabIntersect.size();
859 for (
unsigned int i = 0; i < nbFaces; i++)
880 segMontant.
_ptB = pt;
882 segDescendant.
_ptA = segMontant.
_ptB;
885 bool intersect =
false;
890 while ((j < nbFaces) && (!intersect))
898 segInter = tabIntersect[j].segInter[1];
918 SpectreAbso = SpectreAbso.
mult(-1.0).
sum(1.0);
950 tabEtapes.push_back(Etape);
953 Etape.
_pt = segDescendant.
_ptA;
957 tabEtapes.push_back(Etape);
965 TabChemins.push_back(Chemin);
979 if (epaisseur < 1.0E-2)
985 const double unTiers = 1.0 / 3.0;
988 opLambda = opLambda.
mult(opLambda);
990 C = opLambda.
sum(1.0);
991 C = C.
div(opLambda.
sum(unTiers));
1000 const bool& miroir,
const double& re,
const double& epaisseur,
1001 const bool& vertical,
const bool& avantApres,
bool& bDiffOk,
1002 bool conditionFav)
const
1024 ptSym.
_z = 2 * penteMoyenne.
_ptA.
_z - ptSym.
_z;
1039 ptSym.
_z = 2 * penteMoyenne.
_ptB.
_z - ptSym.
_z;
1054 double gamma = rd * 8.0;
1055 gamma = (gamma > 1000 ? gamma : 1000.0);
1057 double alpha = 2 * asin(rd / (2 * gamma));
1063 double delta = re - rd;
1064 delta = delta <= 0 ? 0.0 : delta;
1090 double lim20dB = pow(10.0, (20.0 / 10.0));
1091 double lim25dB = pow(10.0, (25.0 / 10.0));
1092 double lim0dB = pow(10.0, (0.0 / 10.0));
1094 double valeur = NAN;
1096 for (
unsigned int i = 0; i < sNC.
getNbValues(); i++)
1100 valeur = valeur < lim0dB ? lim0dB : valeur;
1104 valeur = valeur > lim20dB ? lim20dB : valeur;
1108 valeur = valeur > lim25dB ? lim25dB : valeur;
1111 s.getTabValReel()[i] = valeur;
1119 const double PIM4 = 4.0 *
M_PI;
1125 double divGeom =
pSolverAtmos->compute_z() / (PIM4 * rD2);
1156 Ray ray1(start,
vec3(0., 0., -1.));
1159 std::list<Intersection> LI;
1166 Ray ray1(start,
vec3(0., 0., -1.));
1167 ray1.setMaxt(20000);
1171 assert(!LI.empty());
1172 unsigned int indexFace = LI.begin()->p->getPrimitiveId();
1182 Ray ray(start,
vec3(0, 0, -1));
1184 std::list<Intersection> LI2;
1189 indexFace = LI2.begin()->p->getPrimitiveId();
1195 direction.normalize();
1218 Ray ray1(start,
vec3(0., 0., -1.));
1220 std::list<Intersection> LI;
1223 assert(distance1 > 0.);
1224 assert(!LI.empty());
1226 unsigned int indexFace = LI.begin()->p->getPrimitiveId();
1234 Ray ray(start,
vec3(0, 0, -1));
1236 std::list<Intersection> LI2;
1239 if (LI2.empty() || distance < 0.)
1241 distance1 += distance;
1242 indexFace = LI2.begin()->p->getPrimitiveId();
1250 Ray ray2(start,
vec3(0., 0., -1.));
1254 assert(distance2 > 0.);
1255 assert(!LI.empty());
1257 indexFace = LI.begin()->p->getPrimitiveId();
1265 Ray ray(start,
vec3(0, 0, -1));
1267 std::list<Intersection> LI2;
1270 if (LI2.empty() || distance < 0.)
1272 distance2 += distance;
1273 indexFace = LI2.begin()->p->getPrimitiveId();
1277 slope.
_ptA.
_z = director.
_ptA.
_z - (distance1 - 1000.);
1278 slope.
_ptB.
_z = director.
_ptB.
_z - (distance2 - 1000.);
double RADTODEG(double a)
Converts an angle from radians to degrees.
double DEGTORAD(double a)
Converts an angle from degrees to radians.
std::vector< OPoint3D > TabPoint3D
std::deque< TYChemin > TYTabChemin
TYChemin collection.
std::deque< TYEtape > TYTabEtape
TYEtape collection.
virtual decimal traverse(Ray *r, std::list< Intersection > &result) const
Run this accelerator.
Class for the definition of atmospheric conditions.
double _y
y coordinate of OCoord3D
double _z
z coordinate of OCoord3D
double _x
x coordinate of OCoord3D
Plan defined by its equation : ax+by+cz+d=0.
int intersectsSegment(const OPoint3D &pt1, const OPoint3D &pt2, OPoint3D &ptIntersec) const
Calculate the intersection of this plane with a segment defined by two points.
double distFrom(const OPoint3D &pt) const
Computes the distance from this point to another.
Class to define a segment.
virtual double longueur() const
Return the segment length.
virtual int symetrieOf(const OPoint3D &pt, OPoint3D &ptSym) const
Return the symmetrical of a point.
OPoint3D _ptA
Point A of the segment.
virtual OVector3D toVector3D() const
Build a OVector3D from a segment used for the direction of the sources.
virtual int projection(const OPoint3D &pt, OPoint3D &ptProj, double seuilConfondus) const
Return the projection of a point.
virtual int intersects(const OSegment3D &seg, OPoint3D &pt, double seuilConfondus) const
Return the intersection point with another segment.
OPoint3D _ptB
Point B of the segment.
OSpectreAbstract & sum(const OSpectreAbstract &spectre) const
Arithmetic sum of two spectrums in one-third Octave.
unsigned int getNbValues() const
Number of values in the spectrum.
OSpectreAbstract & invMult(const double &coefficient=1.0) const
Division of a double constant by this spectrum.
void setType(TYSpectreType type)
Set the spectrum type.
OSpectreAbstract & div(const OSpectreAbstract &spectre) const
Division of two spectrums.
OSpectreAbstract & racine() const
Compute the root square of this spectrum.
void setDefaultValue(const double &valeur=TY_SPECTRE_DEFAULT_VALUE)
OSpectreAbstract & mult(const OSpectreAbstract &spectre) const
Multiplication of two spectrums.
static OSpectre getLambda(const double &c)
static OSpectre getEmptyLinSpectre(const double &valInit=1.0E-20)
Create a physical quantity spectrum.
double * getTabValReel() override
double norme() const
Computes the length of this vector.
void normalize()
Normalizes this vector.
double dot(const OVector3D &v)
dot product (assuming an orthonormal reference frame)
: Describes a ray by a pair of unsigned int. The first one gives the source number (in the range 0-40...
void setMaxt(decimal _maxt)
set the maxt
Accelerator * getAccelerator() const
Get the accelerator.
OSpectreOctave limAttDiffraction(const OSpectreOctave &sNC, const OSpectreOctave &C) const
Limit the screen attenuation value with a frequency dependent criteria.
std::unique_ptr< AtmosphericConditions > pSolverAtmos
void computeCheminSansEcran(const std::deque< TYSIntersection > &tabIntersect, const OSegment3D &rayon, const tympan::AcousticSource &source, TYTabChemin &TabChemins, double distance, bool conditionFav=false) const
Compute the main path between source and receptor. In 9613 solver, this path includes all attenuation...
TYSolver & _solver
Reference to the solver.
void init()
Initialize the acoustic model.
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.
OSpectreOctave calculAttDiffraction(const OSegment3D &ray, const double &re, const double &dss, const double &dsr, const double &width, const bool &vertical) const
Compute the attenuation from the diffraction on the screen.
TYAcousticModel(TYSolver &solver)
OSpectreOctave 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.
void meanSlope(const OSegment3D &director, OSegment3D &slope) const
Create a segment corresponding to the projection of "director" segment on the ground.
virtual ~TYAcousticModel()
bool solve(TYTrajet &trajet)
Compute the source contributions to the receptor point.
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 void compute(const std::deque< TYSIntersection > &tabIntersect, TYTrajet &trajet, TabPoint3D &ptsTop, TabPoint3D &ptsLeft, TabPoint3D &ptsRight)
Main entry point, trigger acoustic computations.
OSpectre calculC(const double &epaisseur) const
Compute the spectrum of the C factor used in the diffraction calculation.
void computeCheminReflexion(const std::deque< TYSIntersection > &tabIntersect, const OSegment3D &ray, const tympan::AcousticSource &source, TYTabChemin &TabChemins, double distance) const
Compute the list of path generated by reflection on the vertical walls.
OSpectreOctave _absoNulle
virtual bool computeCheminsAvecEcran(const OSegment3D &rayon, const tympan::AcousticSource &source, const TabPoint3D &pts, const bool vertical, TYTabChemin &TabChemins, double distance, const bool left) const
Compute barrier attenuation effect on the direct path for the considered geometrical path (top,...
Representation of one of the most optimal path between source and receptor: S—>R. The class TYChemin ...
void calcAttenuation(const TYTabEtape &tabEtapes, const AtmosphericConditions &atmos, double dp=0.0, double hs=0.0, double hr=0.0, double Gs=0.5, double Gm=0.5, double Gr=0.5)
void setType(const TYTypeChemin &type)
Change the path type.
void setDistance(const double &distance)
void setLongueur(const double &longueur)
The TYEtape class is used to describe a part (a step) of a path (TYChemin) for the computation of tra...
OPoint3D _pt
The starting point of this step.
ACOUSTIC_EVENT_TYPES _type
Acoustic event type.
void setPoint(const OPoint3D &pt)
OSpectreOctave _Absorption
absorption Spectrum
OSpectreOctave _Attenuation
attenuation Spectrum
const Scene * getScene() const
Get the Scene.
const std::vector< TYStructSurfIntersect > & getTabPolygon() const
Get the array of polygons.
This class TYTrajet (journey) links a couple Source-Receptor and a collection of paths,...
double getDistance()
Get/Set the distance between source and receptor.
OSpectreOctave getPEnergetique(const AtmosphericConditions &atmos)
Compute the acoustic pressure in octave bands on the journey.
void getPtSetPtRfromOSeg3D(OSegment3D &seg) const
TYTabChemin & getCheminsDirect()
Return an array of the direct paths.
TYTabChemin & getChemins()
Return the collection of paths of *this.
OSpectre getSpectre()
Get the spectrum in third-octave band at the receptor point \Used to build the result matrix by TYSol...
tympan::AcousticSource & asrc
Business source.
OSpectre getPInterference(const AtmosphericConditions &atmos)
Compute the quadratic pressure on the journey.
3D vector Vector defined with 3 float numbers
Describes building material.
virtual ComplexSpectrum get_absorption(double incidence_angle, double length)
Virtual method to return material absorption at reflection point.
Describes an acoustic source.
string volume_id
Volume id.
SourceDirectivityInterface * directivity
Pointer to the source directivity.
Spectrum spectrum
Associated spectrum.
static LPSolverConfiguration get()
Get the configuration.
virtual Spectrum lwAdjustment(Vector direction, double distance)=0
< Pure virtual method to return directivity of the Source
This file provides class for solver configuration.
std::complex< double > TYComplex
vec3 OPoint3Dtovec3(const OPoint3D &_p)
Converts a OPoint3D to vec3.
base_vec3< decimal > vec3
boost::shared_ptr< SolverConfiguration > LPSolverConfiguration
Data structure for intersections.
bool isInfra
Flag to define if is a infrastructure face.
bool bIntersect[2]
Flag to indicate the face cuts vertical plane ([0]) or horizontal plane ([1])
tympan::AcousticMaterialBase * material
Pointer to a material.