32 : _useSol(true), _useReflex(false), _propaCond(0), _interference(false), _paramH(10.0), _solver(solver)
44 _useSol = config->UseRealGround;
50 double pression = config->AtmosPressure;
51 double temperature = config->AtmosTemperature;
52 double hygrometrie = config->AtmosHygrometry;
55 std::unique_ptr<AtmosphericConditions>(
new AtmosphericConditions(pression, temperature, hygrometrie));
60 double c_9613_2 = 340.0;
69 bool vertical =
true, horizontal =
false;
70 bool left =
true, right =
false;
75 bool conditionFav =
false;
79 assert(config->DSWindDirection >= 0 && config->DSWindDirection <= 360);
81 double windRadian =
DEGTORAD(config->DSWindDirection);
84 propaDirection.
_z = 0;
87 (windDirection.
norme() * propaDirection.
norme())));
88 assert(180 >= angle >= 0);
89 assert(180 >= config->AngleFavorable >= 0);
91 if (angle <= config->AngleFavorable)
111 if (ptsTop.size() > 1 || ptsLeft.size() > 1 || ptsRight.size() > 1)
154 tabEtapes.push_back(etape1);
159 TabChemins.push_back(chemin1);
183 ptSym.
_z = 2 * penteMoyenne.
_ptA.
_z - ptSym.
_z;
197 tabEtapes.push_back(etape2);
202 etape3.
_pt = ptReflex;
217 tabEtapes.push_back(etape3);
222 TabChemins.push_back(chemin2);
229 TYTabChemin& tabPaths,
double distance,
const bool left)
const
236 tabPaths[0].setAttenuationBarWhenNoPath(vertical, left);
244 OPoint3D lastPt(pts[pts.size() - 1]);
247 double pathLength = 0.0;
253 double tempLength = curSegment.
longueur();
255 bool bPathOk =
addStep(ray.
_ptA, firstPt, source,
true, steps);
263 tabSteps.push_back(steps[0]);
264 pathLength += tempLength;
274 for (
unsigned int i = 1; i < pts.size() - 1; i++)
276 width += (
OSegment3D(pts[i], pts[i + 1])).longueur();
282 tabSteps.push_back(step);
293 tabSteps.push_back(steps[0]);
294 pathLength += tempLength;
308 tabSteps.push_back(step);
317 tabPaths.push_back(path);
320 tabPaths[0].computeBarAttenuation(Dz, vertical, left);
340 curStep.
_pt = ptStart;
354 steps.push_back(curStep);
361 TYTabChemin& TabChemin,
double distance,
bool conditionFav)
const
378 double Gs{0.0}, Gm{0.0}, Gr{0.0};
379 double hs{0.0}, hr{0.0};
389 tabEtapes.push_back(Etapes[0]);
393 TabChemin.push_back(chemin);
399 const OSegment3D& ray2D,
double hs,
double hr,
double& Gs,
double& Gm,
402 double heightRatio = 30.0;
412 double dp = SR.norme();
419 if (heightRatio * hs < dp)
421 ptGSrcZone = ptStartProj + SR * heightRatio * hs;
425 ptGSrcZone = ptStartProj + SR * dp;
429 if (heightRatio * hr < dp)
431 ptGRcpZone = ptEndProj + (-1.0) * SR * heightRatio * hr;
435 ptGRcpZone = ptEndProj + (-1.0) * SR * dp;
439 double GZone{0.0}, dpZone{0.0};
440 computeGZone(ptStartProj, ptGSrcZone, GZone, dpZone, tabIntersect);
449 computeGZone(ptGRcpZone, ptEndProj, GZone, dpZone, tabIntersect);
458 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersect);
472 const std::deque<TYSIntersection>& tabIntersectDownSegment,
474 double& Gs,
double& Gm,
double& Gr)
const
476 double heightRatio = 30.0;
495 double dp = dpSO + dpOR;
502 bool bPtGSrcZoneInSO{
false};
503 bool bPtGRcpZoneInOR{
false};
506 if (heightRatio * hs < dpSO)
509 bPtGSrcZoneInSO =
true;
510 ptGSrcZone = ptSrc2D + (SO)*heightRatio * hs;
512 else if (heightRatio * hs < dp)
515 ptGSrcZone = ptO2D + (OR) * (heightRatio * hs - dpSO);
519 ptGSrcZone = ptO2D + (OR)*dpOR;
523 double GZone{0.0}, dpZone{0.0};
526 computeGZone(ptSrc2D, ptGSrcZone, GZone, dpZone, tabIntersectUpSegment);
530 double Gs1{0.0}, dp1{0.0}, Gs2{0.0}, dpOGs{0.0};
531 computeGZone(ptSrc2D, ptO2D, Gs1, dp1, tabIntersectUpSegment);
532 computeGZone(ptO2D, ptGSrcZone, Gs2, dpOGs, tabIntersectDownSegment);
534 dpZone = dp1 + dpOGs;
547 if (heightRatio * hr < dpOR)
550 bPtGRcpZoneInOR =
true;
551 ptGRcpZone = ptRcp2D + (-1.0) * OR * heightRatio * hr;
553 else if (heightRatio * hr < dp)
556 ptGRcpZone = ptO2D + (-1.0) * SO * (heightRatio * hr - dpOR);
560 ptGRcpZone = ptO2D + (-1.0) * SO * dpSO;
567 computeGZone(ptGRcpZone, ptRcp2D, GZone, dpZone, tabIntersectDownSegment);
571 double Gr1{0.0}, dp2{0.0}, Gr2{0.0}, dpGrO{0.0};
572 computeGZone(ptGRcpZone, ptO2D, Gr1, dpGrO, tabIntersectUpSegment);
573 computeGZone(ptO2D, ptRcp2D, Gr2, dp2, tabIntersectDownSegment);
576 dpZone = dpGrO + dp2;
590 if (bPtGSrcZoneInSO && !bPtGRcpZoneInOR)
592 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersectUpSegment);
595 else if (!bPtGSrcZoneInSO && bPtGRcpZoneInOR)
597 computeGZone(ptGSrcZone, ptGRcpZone, GZone, dpZone, tabIntersectDownSegment);
600 else if (bPtGSrcZoneInSO)
602 double Gm1{0.0}, dpm1{0.0}, Gm2{0.0}, dpm2{0.0};
603 computeGZone(ptGSrcZone, ptO2D, Gm1, dpm1, tabIntersectUpSegment);
604 computeGZone(ptO2D, ptGRcpZone, Gm2, dpm2, tabIntersectDownSegment);
606 dpZone = dpm1 + dpm2;
611 double Gm1{0.0}, dpm1{0.0}, Gm2{0.0}, dpm2{0.0};
612 computeGZone(ptGRcpZone, ptO2D, Gm1, dpm1, tabIntersectUpSegment);
613 computeGZone(ptO2D, ptGSrcZone, Gm2, dpm2, tabIntersectDownSegment);
615 dpZone = dpm1 + dpm2;
635 for (
unsigned int i = 0; i < TY_SPECTRE_OCT_NB_ELMT; i++)
655 if (pt2._x != pt1._x)
658 pt3._x = (pt1._y - pt2._y) * (pt3._y - pt1._y) / (pt2._x - pt1._x) + (pt1._x);
662 if (pt1._y != pt2._y)
665 pt3._y = (pt2._x - pt1._x) * (pt3._x - pt1._x) / (pt1._y - pt2._y) + (pt1._y);
672 pt3._x = (pt1._y - pt2._y) * (pt3._y - pt1._y) / (pt2._x - pt1._x) + (pt1._x);
676 return OPlan{pt1, pt2, pt3};
680 double& dpZone,
const std::deque<TYSIntersection>& tabIntersect)
const
690 size_t nbTriangles = tabIntersect.size();
691 double currentG = 0.0;
698 for (
unsigned int i = 0; i < nbTriangles; i++)
708 OSegment3D currentSeg = tabIntersect[i].segInter[0];
709 currentG = tabIntersect[i].material->get_ISO9613_G();
715 OSegment3D segAB{ptDebutCurrentProj, ptFinCurrentProj};
716 OVector3D AB{ptDebutCurrentProj, ptFinCurrentProj};
718 if (AB.scalar(DF) <= 0)
720 segAB = segAB.swap();
727 bool intersect =
true;
733 ptDebutResult = segAB._ptA;
739 ptFinResult = segAB._ptB;
744 ptFinResult = segZone.
_ptB;
757 ptDebutResult = segZone.
_ptA;
758 ptFinResult = segZone.
_ptB;
769 ptDebutResult = segZone.
_ptA;
770 ptFinResult = segAB._ptB;
776 OVector3D result{ptDebutResult, ptFinResult};
777 GZone = GZone + result.norme() * currentG;
781 dpZone = zone.norme();
805 size_t nbFaces = tabIntersect.size();
808 for (
unsigned int i = 0; i < nbFaces; i++)
834 bool intersect =
false;
838 while ((j < nbFaces) && (!intersect))
846 segInter = tabIntersect[j].segInter[1];
879 tabEtapes.push_back(Etape);
886 tabEtapes.push_back(Etape);
897 double dp = raySO.
longueur() + rayOR.longueur();
900 double Gs{0.0}, Gm{0.0}, Gr{0.0};
901 double hs{0.0}, hr{0.0};
906 std::deque<TYSIntersection> tabIntersectUpSegment, tabIntersectDownSegment;
912 getGroundfactors(tabIntersectUpSegment, tabIntersectDownSegment, raySO, rayOR, hs, hr, Gs, Gm,
921 TabChemins.push_back(Chemin);
941 const double oneThird = 1.0 / 3.0;
943 opLambda =
_lambda * (5.0 / width);
944 opLambda = opLambda * opLambda;
947 C3 = C3.
div(opLambda + oneThird);
956 const double& dss,
const double& dsr,
957 const double& width,
const bool& vertical)
const
970 z = z <= 0 ? 0.0 : z;
973 if (z > 0.0 && vertical)
975 Kmeteo = exp(-(1.0 / 2000.0) * sqrt(dss * dsr * rd / (2 * z)));
999 double lim20dB = 20.0;
1000 double lim25dB = 25.0;
1001 double lim0dB = 0.0;
1005 for (
unsigned int i = 0; i < sNC.
getNbValues(); i++)
1009 valeur = valeur < lim0dB ? lim0dB : valeur;
1013 valeur = valeur > lim20dB ? lim20dB : valeur;
1017 valeur = valeur > lim25dB ? lim25dB : valeur;
1020 s.getTabValReel()[i] = valeur;
1030 std::vector<PathResults> pathsResults;
1037 for (
unsigned int i = 0; i < trajet.
getNbChemins(); i++)
1039 currentPathResults.
path_id = i;
1070 currentPathResults.
A = currentPathResults.
Adiv + currentPathResults.
Aatm + currentPathResults.
Agr_s +
1071 currentPathResults.
Agr_r + currentPathResults.
Agr_m + currentPathResults.
Abar;
1079 currentPathResults.
Dc =
1085 currentPathResults.
LW =
1086 currentPathResults.
LW +
1089 currentPathResults.
L = currentPathResults.
LW + currentPathResults.
Dc - currentPathResults.
A;
1091 SLp = SLp.
sumdB(currentPathResults.
L);
1094 pathsResults.push_back(currentPathResults);
1121 Ray ray1(start,
vec3(0., 0., -1.));
1124 std::list<Intersection> LI;
1131 Ray ray1(start,
vec3(0., 0., -1.));
1136 assert(!LI.empty());
1137 unsigned int indexFace = LI.begin()->p->getPrimitiveId();
1147 Ray ray(start,
vec3(0, 0, -1));
1149 std::list<Intersection> LI2;
1154 indexFace = LI2.begin()->p->getPrimitiveId();
1183 Ray ray1(start,
vec3(0., 0., -1.));
1185 std::list<Intersection> LI;
1188 assert(distance1 > 0.);
1189 assert(!LI.empty());
1191 unsigned int indexFace = LI.begin()->p->getPrimitiveId();
1199 Ray ray(start,
vec3(0, 0, -1));
1201 std::list<Intersection> LI2;
1204 if (LI2.empty() || distance < 0.)
1206 distance1 += distance;
1207 indexFace = LI2.begin()->p->getPrimitiveId();
1215 Ray ray2(start,
vec3(0., 0., -1.));
1219 assert(distance2 > 0.);
1220 assert(!LI.empty());
1222 indexFace = LI.begin()->p->getPrimitiveId();
1230 Ray ray(start,
vec3(0, 0, -1));
1232 std::list<Intersection> LI2;
1235 if (LI2.empty() || distance < 0.)
1237 distance2 += distance;
1238 indexFace = LI2.begin()->p->getPrimitiveId();
1242 slope.
_ptA.
_z = director.
_ptA.
_z - (distance1 - 1000.);
1243 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.
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 intersects(const OSegment3D &seg, OPoint3D &pt, double seuilConfondus) const
Return the intersection point with another segment.
OPoint3D _ptB
Point B of the segment.
OSpectreAbstract & log(const double &base=10.0) const
Compute the log base n of this spectrum (n=10 by default).
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.
void setDefaultValue(const double &valeur=TY_SPECTRE_DEFAULT_VALUE)
OSpectreAbstract & round()
OSpectreAbstract & sumdB(const OSpectreAbstract &spectre) const
Energetic sum of two spectrums.
static OSpectreOctave getLambda(const double &c)
static OSpectreOctave getEmptyLinSpectre(const double &valInit=1.0E-20)
Create a physical quantity spectrum.
double * getTabValReel() override
Get an array of the real values of the spectrum.
double norme() const
Computes the length of this vector.
void normalize()
Normalizes this vector.
double scalar(const OVector3D &vector) const
Performs the scalar product between this object and another 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...
bool computeSegmentEdgesHeights(double &hauteurA, double &hauteurB, const OSegment3D &meanSlope, const OSegment3D &ray) const
Compute heights relative to real ground, of the edges of a segment.
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 computeEffectiveBarAttenuation(const OSpectreOctave &Abar_top, const OSpectreOctave &Abar_left, const OSpectreOctave &Abar_right)
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.
OSpectreOctave calculC3(const double &epaisseur) const
Compute the spectrum of the C3 factor used in the diffraction calculation.
void meanSlope(const OSegment3D &director, OSegment3D &slope) const
Create a segment corresponding to the projection of "director" segment on the ground.
bool computeGZone(const OPoint3D &ptDebut, const OPoint3D &ptFin, double &GZone, double &dpZone, const std::deque< TYSIntersection > &tabIntersect) const
Compute GZone and dpZone for the segment between ptDebut and ptFin.
virtual ~TYAcousticModel()
bool solve(TYTrajet &trajet)
Compute the source contributions to the receptor point.
virtual void compute(const std::deque< TYSIntersection > &tabIntersect, TYTrajet &trajet, TabPoint3D &ptsTop, TabPoint3D &ptsLeft, TabPoint3D &ptsRight)
Main entry point, trigger acoustic computations.
OPlan buildMeanSlopePlan(const OSegment3D &penteMoyenne) const
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,...
bool getGroundfactors(const std::deque< TYSIntersection > &tabIntersect, const OSegment3D &ray2D, double hs, double hr, double &Gs, double &Gm, double &Gr) const
Get ground factors for source, middle and receptor zones.
bool addStep(const OPoint3D &ptStart, const OPoint3D &ptEnd, const tympan::AcousticSource &source, const bool &fromSource, TYTabEtape &Etapes) const
Compute the different steps from a point to another via a reflection and a direct view.
Representation of one of the most optimal path between source and receptor: S—>R. The class TYChemin ...
double getLongueur()
Get/Set the path length.
const TYTypeChemin getType() const
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)
OSpectreOctave & getAttenuation(TYTypeAttenuation type)
void setType(const TYTypeChemin &type)
Change the path type.
void setDistance(const double &distance)
void setLongueur(const double &longueur)
void build_eq_path(const TYTabEtape &tabEtapes)
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
virtual void selectFaces(std::deque< TYSIntersection > &tabIntersect, const OSegment3D &rayon, const string &sourceVolumeId)
Build the array of intersections.
static void exportResults17534(const std::vector< PathResults > pathsResults, const OSpectreOctave &SLp, const AtmosphericConditions &atmos)
const Scene * getScene() const
Get the Scene.
const std::vector< TYStructSurfIntersect > & getTabPolygon() const
Get the array of polygons.
TYFaceSelector * getFaceSelector()
Get the face selector.
This class TYTrajet (journey) links a couple Source-Receptor and a collection of paths,...
double getDistance()
Get/Set the distance between source and receptor.
TYChemin getChemin(int index)
Return a path thanks to its index.
void getPtSetPtRfromOSeg3D(OSegment3D &seg) const
TYTabChemin & getChemins()
Return the collection of paths of *this.
size_t getNbChemins()
Return the number of path in *this (in addition to the direct path).
OSpectreOctave & getSpectreOct()
Get the spectrum in octave band at the receptor point \Used to compute the pressure spectrum in octav...
void reset()
Reset method.
tympan::AcousticSource & asrc
Business source.
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.
vec3 OPoint3Dtovec3(const OPoint3D &_p)
Converts a OPoint3D to vec3.
base_vec3< decimal > vec3
boost::shared_ptr< SolverConfiguration > LPSolverConfiguration
OSpectreOctave Abar_right
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.