45 bool vertical =
true, horizontal =
false;
50 bool conditionFav =
false;
54 assert(config->DSWindDirection >= 0 && config->DSWindDirection <= 360);
56 double windRadian =
DEGTORAD(config->DSWindDirection);
59 propaDirection.
_z = 0;
62 (windDirection.
norme() * propaDirection.
norme())));
63 assert(180 >= angle >= 0);
64 assert(180 >= config->AngleFavorable >= 0);
66 if (angle <= config->AngleFavorable)
93 if (tabChemins.size() == 0)
111 tabCheminsSansEcran.clear();
117 double distance)
const
136 tabEtapes.push_back(etape1);
141 TabChemins.push_back(chemin1);
165 ptSym.
_z = 2 * penteMoyenne.
_ptA.
_z - ptSym.
_z;
180 tabEtapes.push_back(etape2);
185 etape3.
_pt = ptReflex;
200 tabEtapes.push_back(etape3);
205 TabChemins.push_back(chemin2);
213 double distance,
bool conditionFav)
const
235 tabEtapes.push_back(Etapes[0]);
239 TabChemin.push_back(cheminDirect);
246 tabEtapes.push_back(Etapes[1]);
247 tabEtapes.push_back(Etapes[2]);
251 TabChemin.push_back(cheminReflechi);
263 double hauteurA = 0.0, hauteurB = 0.0;
269 ptProj = penteMoyenne.
_ptA;
271 hauteurA = rayon.
_ptA.
_z - ptProj.
_z;
275 ptProj = penteMoyenne.
_ptB;
277 hauteurB = rayon.
_ptB.
_z - ptProj.
_z;
283 hauteurA = rayon.
_ptA.
_z - ptProj.
_z;
286 hauteurB = rayon.
_ptB.
_z - ptProj.
_z;
291 if (rayon.
longueur() > (10 * (hauteurA + hauteurB)))
311 double distRef =
_paramH * hauteurA;
318 projA = penteMoyenne.
_ptA;
339 tabEtapes.push_back(etape);
342 etape.
_pt = ptReflex;
359 tabEtapes.push_back(etape);
384 projB = penteMoyenne.
_ptB;
403 tabEtapes.push_back(etape);
406 etape.
_pt = ptReflex;
424 tabEtapes.push_back(etape);
442 double distance,
bool conditionFav)
const
458 OPoint3D lastPt(pts[pts.size() - 1]);
461 double longTwoReflex = 0.0;
464 double longOneReflexBefore = 0.0;
467 double longOneReflexAfter = 0.0;
470 double longNoReflex = 0.0;
479 double tempLong = segCourant.
longueur();
481 bool bCheminOk =
addGroundSteps(rayon.
_ptA, firstPt, penteMoyenneTotale, source,
true,
false, Etapes,
491 tabNoReflex.push_back(Etapes[0]);
492 longNoReflex += tempLong;
494 tabOneReflexAfter.push_back(Etapes[0]);
495 longOneReflexAfter += tempLong;
497 tabOneReflexBefore.push_back(Etapes[1]);
498 tabOneReflexBefore.push_back(Etapes[2]);
499 longOneReflexBefore += rr;
501 tabTwoReflex.push_back(Etapes[1]);
502 tabTwoReflex.push_back(Etapes[2]);
509 double epaisseur = 0.0;
512 for (
unsigned int i = 1; i < pts.size() - 1; i++)
514 epaisseur += (
OSegment3D(pts[i], pts[i + 1])).longueur();
520 tabTwoReflex.push_back(Etape);
521 tabOneReflexBefore.push_back(Etape);
522 tabOneReflexAfter.push_back(Etape);
523 tabNoReflex.push_back(Etape);
526 longNoReflex += epaisseur;
527 longOneReflexAfter += epaisseur;
528 longOneReflexBefore += epaisseur;
529 longTwoReflex += epaisseur;
535 addGroundSteps(lastPt, rayon.
_ptB, penteMoyenneTotale, source,
false,
true, Etapes, rr);
537 tabNoReflex.push_back(Etapes[0]);
538 longNoReflex += tempLong;
540 tabOneReflexBefore.push_back(Etapes[0]);
541 longOneReflexBefore += tempLong;
543 tabOneReflexAfter.push_back(Etapes[1]);
544 tabOneReflexAfter.push_back(Etapes[2]);
545 longOneReflexAfter += rr;
547 tabTwoReflex.push_back(Etapes[1]);
548 tabTwoReflex.push_back(Etapes[2]);
563 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
false, longNoReflex, epaisseur, vertical,
false,
564 bDiffOk, conditionFav);
566 tabNoReflex.push_back(Etape);
569 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
false, longTwoReflex, epaisseur, vertical,
false,
570 bDiffOk, conditionFav);
572 tabTwoReflex.push_back(Etape);
575 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
true, longOneReflexBefore, epaisseur, vertical,
576 false, bDiffOk, conditionFav);
578 tabOneReflexBefore.push_back(Etape);
581 Diff =
calculAttDiffraction(rayon, penteMoyenneTotale,
true, longOneReflexAfter, epaisseur, vertical,
582 true, bDiffOk, conditionFav);
584 tabOneReflexAfter.push_back(Etape);
595 TabChemins.push_back(cheminEcranTwoReflex);
602 cheminOneReflexBefore.
setLongueur(longOneReflexBefore);
604 TabChemins.push_back(cheminOneReflexBefore);
611 cheminOneReflexAfter.
setLongueur(longOneReflexAfter);
613 TabChemins.push_back(cheminOneReflexAfter);
622 TabChemins.push_back(cheminNoReflex);
624 tabTwoReflex.clear();
625 tabOneReflexBefore.clear();
626 tabOneReflexAfter.clear();
636 const bool& fromSource,
const bool& toRecepteur,
650 EtapeCourante.
_pt = ptDebut;
664 Etapes.push_back(EtapeCourante);
674 OPoint3D(ptDebut.
_x, ptDebut.
_y, -100000), ptDebutProj);
686 EtapeCourante.
_pt = ptDebut;
713 ptSymFin.
_z = 2 * segPente.
_ptB.
_z - ptSymFin.
_z;
721 double coefH = (d1 + d2) != 0 ? d1 / (d2 + d1) : 0.0;
724 ptReflex.
_x = (ptSymFin.
_x - ptSym.
_x) * coefH + ptSym.
_x;
725 ptReflex.
_y = (ptSymFin.
_y - ptSym.
_y) * coefH + ptSym.
_y;
726 ptReflex.
_z = (ptSymFin.
_z - ptSym.
_z) * coefH + ptSym.
_z;
753 Etapes.push_back(EtapeCourante);
756 EtapeCourante.
_pt = ptReflex;
772 Etapes.push_back(EtapeCourante);
774 else if (fromSource || toRecepteur)
782 Etapes.push_back(EtapeCourante);
785 EtapeCourante.
_pt = ptReflex;
801 Etapes.push_back(EtapeCourante);
816 double distance)
const
834 size_t nbFaces = tabIntersect.size();
837 for (
unsigned int i = 0; i < nbFaces; i++)
858 segMontant.
_ptB = pt;
860 segDescendant.
_ptA = segMontant.
_ptB;
863 bool intersect =
false;
868 while ((j < nbFaces) && (!intersect))
876 segInter = tabIntersect[j].segInter[1];
896 SpectreAbso = SpectreAbso.
mult(-1.0).
sum(1.0);
928 tabEtapes.push_back(Etape);
931 Etape.
_pt = segDescendant.
_ptA;
935 tabEtapes.push_back(Etape);
943 TabChemins.push_back(Chemin);
957 if (epaisseur < 1.0E-2)
963 const double unTiers = 1.0 / 3.0;
966 opLambda = opLambda.
mult(opLambda);
968 C = opLambda.
sum(1.0);
969 C = C.
div(opLambda.
sum(unTiers));
979 const bool& miroir,
const double& re,
980 const double& epaisseur,
const bool& vertical,
981 const bool& avantApres,
bool& bDiffOk,
982 bool conditionFav)
const
1004 ptSym.
_z = 2 * penteMoyenne.
_ptA.
_z - ptSym.
_z;
1019 ptSym.
_z = 2 * penteMoyenne.
_ptB.
_z - ptSym.
_z;
1034 double gamma = rd * 8.0;
1035 gamma = (gamma > 1000 ? gamma : 1000.0);
1037 double alpha = 2 * asin(rd / (2 * gamma));
1043 double delta = re - rd;
1044 delta = delta <= 0 ? 0.0 : delta;
1070 double lim20dB = pow(10.0, (20.0 / 10.0));
1071 double lim25dB = pow(10.0, (25.0 / 10.0));
1072 double lim0dB = pow(10.0, (0.0 / 10.0));
1074 double valeur = NAN;
1076 for (
unsigned int i = 0; i < sNC.
getNbValues(); i++)
1080 valeur = valeur < lim0dB ? lim0dB : valeur;
1084 valeur = valeur > lim20dB ? lim20dB : valeur;
1088 valeur = valeur > lim25dB ? lim25dB : valeur;
1091 s.getTabValReel()[i] = valeur;
1099 const double PIM4 = 4.0 *
M_PI;
1102 float minSRDistance = config->MinSRDistance;
1140 Ray ray1(start,
vec3(0., 0., -1.));
1143 std::list<Intersection> LI;
1150 Ray ray1(start,
vec3(0., 0., -1.));
1155 assert(!LI.empty());
1156 unsigned int indexFace = LI.begin()->p->getPrimitiveId();
1166 Ray ray(start,
vec3(0, 0, -1));
1168 std::list<Intersection> LI2;
1173 indexFace = LI2.begin()->p->getPrimitiveId();
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< TYCheminDefaultSolver > TYTabCheminDefaultSolver
TYChemin collection.
std::deque< TYEtapeDefaultSolver > TYTabEtapeDefaultSolver
TYEtape collection.
virtual decimal traverse(Ray *r, std::list< Intersection > &result) const
Run this accelerator.
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.
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.
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.
void computeCheminSansEcran(const OSegment3D &rayon, const tympan::AcousticSource &source, TYTabCheminDefaultSolver &TabChemins, double distance, bool conditionFav=false) const
Compute the list of paths generated by reflection on the ground if there is no screen.
bool solve(TYTrajetDefaultSolver &trajet)
Compute the source contribution to the point.
virtual void compute(const std::deque< TYSIntersection > &tabIntersect, TYTrajetDefaultSolver &trajet, TabPoint3D &ptsTop, TabPoint3D &ptsLeft, TabPoint3D &ptsRight)
OSpectre limAttDiffraction(const OSpectre &sNC, const OSpectre &C) const
Limit the screen attenuation value with a frequency dependent criteria.
void computeCheminReflexion(const std::deque< TYSIntersection > &tabIntersect, const OSegment3D &rayon, const tympan::AcousticSource &source, TYTabCheminDefaultSolver &TabChemins, double distance) const
Compute the list of path generated by reflection on the vertical walls.
TYSolverDefaultSolver & _solver
Reference to the solver.
bool addGroundSteps(const OPoint3D &ptDebut, const OPoint3D &ptFin, const OSegment3D &penteMoyenne, const tympan::AcousticSource &source, const bool &fromSource, const bool &toRecepteur, TYTabEtapeDefaultSolver &Etapes, double &longueur) const
Compute the different steps from a point to another via a reflection and a direct view.
void computeCheminAPlat(const OSegment3D &rayon, const tympan::AcousticSource &source, TYTabCheminDefaultSolver &TabChemins, double distance) const
Compute the list of paths for a perfectly flat and reflective ground.
OSpectreComplex _absoNulle
OSpectre calculC(const double &epaisseur) const
Compute the spectrum of the C factor used in the diffraction calculation.
void computeWaveLength() override
Compute the wave length for the default solver.
TYAcousticModelDefaultSolver(TYSolverDefaultSolver &solver)
virtual bool computeCheminsAvecEcran(const OSegment3D &rayon, const tympan::AcousticSource &source, const TabPoint3D &pts, const bool vertical, TYTabCheminDefaultSolver &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...
Acoustic model for the considered solver.
std::unique_ptr< AtmosphericConditions > _pSolverAtmos
void meanSlope(const OSegment3D &director, OSegment3D &slope) const
Create a segment corresponding to the projection of "director" segment on the ground.
OPlan buildMeanSlopePlan(const OSegment3D &penteMoyenne) const
Representation of one of the most optimal path between source and receptor: S—>R. The class TYChemin ...
void calcAttenuation(const TYTabEtapeDefaultSolver &tabEtapes, const AtmosphericConditions &atmos)
Compute the global attenuation on the path.
void setType(const TYTypeChemin &type)
Change the path type.
void setDistance(const double &distance)
void setLongueur(const double &longueur)
OSpectreComplex _Absorption
absorption Spectrum
OSpectre _Attenuation
attenuation Spectrum
OPoint3D _pt
The starting point of this step.
ACOUSTIC_EVENT_TYPES _type
Acoustic event type.
void setPoint(const OPoint3D &pt)
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,...
OSpectre & getSpectre()
Get/Set the spectrum at the receptor point.
TYTabCheminDefaultSolver & getChemins()
Return the collection of paths of *this.
OSpectre getPInterference(const AtmosphericConditions &atmos)
Compute the quadratic pressure on the journey.
TYTabCheminDefaultSolver & getCheminsDirect()
Return an array of the direct paths.
OSpectre getPEnergetique(const AtmosphericConditions &atmos)
Compute the acoustic pressure (phase modulation) on the journey.
double getDistance()
Get/Set the distance between source and receptor.
void getPtSetPtRfromOSeg3D(OSegment3D &seg) const
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.
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.