Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYAcousticSemiCircle.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012> <EDF-R&D> <FRANCE>
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  * See the GNU General Public License for more details.
11  * You should have received a copy of the GNU General Public License along
12  * with this program; if not, write to the Free Software Foundation, Inc.,
13  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14  */
15 
16 #include "Tympan/core/logging.h"
20 #if TY_USE_IHM
24 #endif
25 
26 #include "TYAcousticSemiCircle.h"
27 
30 
32 {
34 
35  // Couleur par default
36  float r = 255.0f, g = 67.0f, b = 133.0f;
37 
38 #if TY_USE_IHM
39  if (TYPreferenceManager::exists(TYDIRPREFERENCEMANAGER, "TYAcousticCircleGraphicColorR"))
40  {
41  TYPreferenceManager::getColor(TYDIRPREFERENCEMANAGER, "TYAcousticCircleGraphicColor", r, g, b);
42  }
43  else
44  {
45  TYPreferenceManager::setColor(TYDIRPREFERENCEMANAGER, "TYAcousticCircleGraphicColor", r, g, b);
46  }
47 #endif // TY_USE_IHM
48  OColor color;
49  color.r = r / 255;
50  color.g = g / 255;
51  color.b = b / 255;
52 
53  setColor(color);
54 }
55 
57 {
58  *this = other;
59 }
60 
62 
64 {
65  if (this != &other)
66  {
68  }
69  return *this;
70 }
71 
73 {
74  if (this != &other)
75  {
76  if (TYAcousticSurface::operator!=(other))
77  {
78  return false;
79  }
80  }
81  return true;
82 }
83 
85 {
86  return !operator==(other);
87 }
88 
89 bool TYAcousticSemiCircle::deepCopy(const TYElement* pOther, bool copyId /*=true*/,
90  bool pUseCopyTag /*=false*/)
91 {
92  return TYAcousticSurface::deepCopy(pOther, copyId);
93 }
94 
95 std::string TYAcousticSemiCircle::toString() const
96 {
97  return "TYAcousticSemiCircle";
98 }
99 
101 {
102  DOM_Element domNewElem = TYAcousticSurface::toXML(domElement);
103  return domNewElem;
104 }
105 
107 {
108  return TYAcousticSurface::fromXML(domElement);
109 }
110 
112 {
114 }
115 
117 {
118  return TYSourcePonctuelle();
119 }
120 
122 {
123  // Suppression des sources existantes
124  _pSrcSurf->purge();
125 
126  if ((_isRayonnant == false) || (_pSrcSurf->getDensiteSrcsH() == 0) || (_pSrcSurf->getDensiteSrcsV() == 0))
127  {
128  // Pas de calcul
129  return;
130  }
131 
132  double rayon = getDiameter() / 2.0;
133  // Distance angulaire (sur la circonference de chaque cercle
134  // concentrique) et nombre de sources
135  int nbSrcsAngulaire = (int)(M_PI * rayon / _pSrcSurf->getDensiteSrcsH());
136  nbSrcsAngulaire = nbSrcsAngulaire < 1 ? 1 : nbSrcsAngulaire; // Au moins 1 source opposees
137 
138  double distAngulaire = M_PI / nbSrcsAngulaire;
139 
140  // Distance radiale
141  int nbSrcsRadiale = (int)(rayon / _pSrcSurf->getDensiteSrcsV());
142  nbSrcsRadiale = nbSrcsRadiale < 1 ? 1 : nbSrcsRadiale; // Au moins 1 source opposees
143 
144  double distRayon = rayon / (nbSrcsRadiale + 1);
145 
146  OMatrix matrix;
147  OPoint3D pt;
148  double angle = 0.0;
149  double posCercle = distRayon;
150 
151  // On recupere le repere local au plan du cercle
153  // On place l'origine au centre du cercle pour simplifier les calculs
154  repere._origin = getCenter();
155  // Matrice de changement de repere
156  matrix = repere.asMatrix();
157 
158  // To define directivity
159  double specificSize = getBoundingRect()->getDiagSize();
160  OVector3D faceNormal = normal();
161  faceNormal.normalize();
163 
164  for (int i = 0; i < nbSrcsRadiale; i++)
165  {
166  for (int j = 0; j < nbSrcsAngulaire; j++)
167  {
168  angle = (-M_PI / 2) + ((j + 1) * distAngulaire) - (distAngulaire / 2);
169  pt._x = cos(angle) * posCercle;
170  pt._y = sin(angle) * posCercle;
171  pt._z = _offsetSources;
172 
173  // On revient dans le repere d'origine
174  pt = matrix * pt;
175 
176  // Creation d'une source ponctuelle
178  pSrc->setDirectivity(new TYComputedDirectivity(faceNormal, type, specificSize));
179 
180  // Definition de sa position
181  *pSrc->getPos() = pt;
182 
183  // Attribution du parent
184  pSrc->setParent(this);
185 
186  // Definition des sources comme sources a directivite calculee
187  pSrc->setTypeRaynt(CALCULATED);
188 
189  // Ajout de la src ponct a la src surf
190  _pSrcSurf->addSrc(pSrc);
191  }
192  // Increment du rayon
193  posCercle += distRayon;
194  }
195 }
196 
198 {
199  return TYAcousticSurface::setSrcsLw(); // Appel de la methode generale
200 }
201 
203 {
204  // La moitie de l'aire d'un cercle
205  double rayon = getDiameter() / 2.0;
206  return (M_PI * rayon * rayon) / 2.0;
207 }
208 
210 {
211  return _pBoundingRect->normal();
212 }
213 
215 {
216  return OPlan(getCenter(), normal());
217 }
218 
220 {
221  TYTabPoint tab;
222 
223  if (n == -1)
224  {
225  // Prise en compte de la precision
226  n = ROUND((getDiameter() / 2.0) / TYPRECISIONCIRCLE);
227 
228  // On veut au moins tous les Pi/2 (90i¿½)
229  n = ROUND(n / 4 * 4);
230  }
231  else if ((getDiameter() == 0) || (n < 3))
232  {
233  return tab;
234  }
235 
236  OMatrix matrix;
237  double angle = 0.0;
238  double rayon = getDiameter() / 2.0;
239  double demiPi = M_PI / 2.0;
240 
241  // On recupere le repere local au plan du cercle
243 
244  // On place l'origine au centre du cercle pour simplifier les calculs
245  repere._origin = getCenter();
246 
247  // Matrice de changement de repere
248  matrix = repere.asMatrix();
249 
250  // On connait la taille du tableau de point a retourner
251  tab.reserve(n);
252  TYPoint pt;
253 
254  // On calcul la position de chaque portion
255  // (on travaille dans le repere local au plan du cercle)
256  // Les calculs sont fait de 0 a Pi(180i¿½) seulement
257  for (int i = 0; i < (n + 1); i++)
258  {
259  // Increment de la portion (sens horaire)
260  angle = ((M_PI * (n - i)) / n) - demiPi;
261 
262  // Point correspondant
263  pt._x = cos(angle) * rayon;
264  pt._y = sin(angle) * rayon;
265  pt._z = 0;
266 
267  // On revient dans le repere d'origine
268  pt = matrix * pt;
269 
270  // On ajoute ce point au tableau
271  tab.push_back(pt);
272  }
273 
274  return tab;
275 }
276 
278 {
279  TYTabPoint3D tab;
280 
281  if (n == -1)
282  {
283  // Prise en compte de la precision
284  n = ROUND((getDiameter() / 2.0) / TYPRECISIONCIRCLE);
285 
286  // On veut au moins tous les Pi/2 (90i¿½)
287  n = ROUND(n / 4 * 4);
288  }
289  else if ((getDiameter() == 0) || (n < 3))
290  {
291  return tab;
292  }
293 
294  OMatrix matrix;
295  double angle = 0.0;
296  double rayon = getDiameter() / 2.0;
297  double demiPi = M_PI / 2.0;
298 
299  // On recupere le repere local au plan du cercle
301 
302  // On place l'origine au centre du cercle pour simplifier les calculs
303  repere._origin = getCenter();
304 
305  // Matrice de changement de repere
306  matrix = repere.asMatrix();
307 
308  // On connait la taille du tableau de point a retourner
309  OPoint3D pt;
310 
311  // On calcul la position de chaque portion
312  // (on travaille dans le repere local au plan du cercle)
313  // Les calculs sont fait de 0 a Pi(180i¿½) seulement
314  for (int i = 0; i < (n + 1); i++)
315  {
316  // Increment de la portion (sens horaire)
317  angle = ((M_PI * (n - i)) / n) - demiPi;
318 
319  // Point correspondant
320  pt._x = cos(angle) * rayon;
321  pt._y = sin(angle) * rayon;
322  pt._z = 0;
323 
324  // On revient dans le repere d'origine
325  pt = matrix * pt;
326 
327  // On ajoute ce point au tableau
328  tab.push_back(pt);
329  }
330 
331  return tab;
332 }
334 {
335  return TYSurfaceInterface::intersects(pSurf, seg);
336 }
337 
339 {
340  int res = INTERS_NULLE;
341 
342  res = _pBoundingRect->intersects(seg, pt);
343 
344  if (res != INTERS_NULLE)
345  {
346  res = intersects(pt);
347  }
348 
349  return res;
350 }
351 
353 {
354  int res = INTERS_NULLE;
355 
356  // Pour que le point coupe le cercle, la dist [centre du cercle , pt]
357  // doit etre <= au rayon du demi-cercle
358 
359  double distPtCentre = OVector3D(pt, getCenter()).norme();
360 
361  if (2 * distPtCentre <= getDiameter())
362  {
363  res = INTERS_OUI;
364  }
365 
366  return res;
367 }
368 
370 {
371  OVector3D vecCote(_pBoundingRect->_pts[0], _pBoundingRect->_pts[3]);
372  OVector3D vecCentre = OVector3D(_pBoundingRect->_pts[0]) + (vecCote * 0.5);
373 
374  return TYPoint(vecCentre);
375 }
376 
378 {
380 }
381 
383 {
384  double rayon = diameter / 2.0;
385  double norm = 1.41421356 * rayon;
386 
387  OPoint3D ptCenter = getCenter();
388  OVector3D vecOP0(ptCenter, _pBoundingRect->_pts[0]);
389  double normOP0 = vecOP0.norme();
390  OVector3D vecOP1(ptCenter, _pBoundingRect->_pts[1]);
391  double normOP1 = vecOP1.norme();
392  OVector3D vecOP2(ptCenter, _pBoundingRect->_pts[2]);
393  double normOP2 = vecOP2.norme();
394  OVector3D vecOP3(ptCenter, _pBoundingRect->_pts[3]);
395  double normOP3 = vecOP3.norme();
396 
397  if ((normOP0 == 0) || (normOP1 == 0) || (normOP2 == 0) || (normOP3 == 0))
398  {
399  // Cercle invalide
400  return;
401  }
402 
403  OVector3D vecPtCenter = getCenter();
404 
405  _pBoundingRect->_pts[0] = vecPtCenter + (vecOP0 * (rayon / normOP0));
406  _pBoundingRect->_pts[1] = vecPtCenter + (vecOP1 * (norm / normOP1));
407  _pBoundingRect->_pts[2] = vecPtCenter + (vecOP2 * (norm / normOP2));
408  _pBoundingRect->_pts[3] = vecPtCenter + (vecOP3 * (rayon / normOP3));
409 
410  setIsGeometryModified(true);
411 }
412 
413 void TYAcousticSemiCircle::exportMesh(std::deque<OPoint3D>& points, std::deque<OTriangle>& triangles,
414  const TYGeometryNode& geonode) const
415 {
416  assert(points.size() == 0 && "Output arguments 'points' is expected to be initially empty");
417  assert(triangles.size() == 0 && "Output arguments 'triangles' is expected to be initially empty");
418 
419  int resolution = TYDEFAULTRESOLUTIONIONCIRCLE;
420 #if TY_USE_IHM
421  if (TYPreferenceManager::exists(TYDIRPREFERENCEMANAGER, "ResolutionCircle"))
422  {
423  resolution = TYPreferenceManager::getInt(TYDIRPREFERENCEMANAGER, "ResolutionCircle");
424  }
425  else
426  {
427  TYPreferenceManager::setInt(TYDIRPREFERENCEMANAGER, "ResolutionCircle", resolution);
428  }
429 #endif // TY_USE_IHM
430 
431  TYTabPoint3D poly = getOContour(resolution); // local r/ frame
432 
433  // 1. We set all points to global repere
434  // Center is the 1st point of the list
435  OPoint3D center = geonode.localToGlobal() * getCenter(); // converted early to global r/ frame
436  for (int i = 0; i < poly.size(); ++i)
437  {
438  points.push_front(geonode.localToGlobal() * poly[i]);
439  }
440 
441  points.push_front(center);
442 
443  // 2. Now, we create triangles
444  for (int i = 1; i < (resolution + 1); ++i) // resolution points = resolution+1 triangles
445  {
446  // Use only global coordinates
447  OTriangle tri(center, points[i], points[(i % (resolution + 1)) + 1]);
448  tri._p1 = 0;
449  tri._p2 = i;
450  tri._p3 = (i % (resolution + 1)) + 1;
451  triangles.push_back(tri);
452  }
453 }
All base classes related to 3D manipulation.
int ROUND(double a)
Compute the rounded value of a number.
Definition: 3d.h:192
#define INTERS_OUI
The intersection exists.
Definition: 3d.h:33
#define INTERS_NULLE
No intersection.
Definition: 3d.h:35
QDomElement DOM_Element
Definition: QT2DOM.h:30
Représentation graphique d'1/2 cercle acoustique (fichier header)
outil IHM pour un demi cercle acoustique (fichier header)
TY_EXTENSION_INST(TYAcousticSemiCircle)
TY_EXT_GRAPHIC_INST(TYAcousticSemiCircle)
std::vector< TYPoint > TYTabPoint
Collection de TYPoint.
Definition: TYDefines.h:340
#define TYDEFAULTRESOLUTIONIONCIRCLE
Resolution par defaut pour la representation des cercles par des segments.
Definition: TYDefines.h:415
std::deque< OPoint3D > TYTabPoint3D
Collection de OPoint3D.
Definition: TYDefines.h:403
#define TYPRECISIONCIRCLE
Precision pour la representation des cercles par des segments.
Definition: TYDefines.h:412
#define TYDIRPREFERENCEMANAGER
Definition: TYElement.h:52
std::vector< LPTYSourcePonctuelleGeoNode > TYTabSourcePonctuelleGeoNode
Collection de noeuds geometriques de type TYSourcePonctuelle.
@ CALCULATED
Definition: color.h:31
float b
Definition: color.h:33
float r
Definition: color.h:33
float g
Definition: color.h:33
double _y
y coordinate of OCoord3D
Definition: 3d.h:283
double _z
z coordinate of OCoord3D
Definition: 3d.h:284
double _x
x coordinate of OCoord3D
Definition: 3d.h:282
The 4x4 matrix class.
Definition: 3d.h:625
Plan defined by its equation : ax+by+cz+d=0.
Definition: plan.h:31
The 3D point class.
Definition: 3d.h:487
virtual const char * getClassName() const
Definition: TYElement.h:249
3D frame with a point and 3 vectors.
Definition: 3d.h:1211
OPoint3D _origin
The origin point.
Definition: 3d.h:1279
OMatrix asMatrix() const
return the transformation matrix from unity to this pose such as this = transform * unity
Definition: 3d.cpp:1462
Class to define a segment.
Definition: 3d.h:1089
Triangle class.
Definition: triangle.h:28
int _p1
Index of the first OPoint3D _A.
Definition: triangle.h:49
int _p3
Index of the third OPoint3D _C.
Definition: triangle.h:51
int _p2
Index of the second OPoint3D _B.
Definition: triangle.h:50
The 3D vector class.
Definition: 3d.h:298
double norme() const
Computes the length of this vector.
Definition: 3d.cpp:215
void normalize()
Normalizes this vector.
Definition: 3d.cpp:225
double _offsetSources
Offset de decalage des sources ponctuelles sur les surfaces.
bool _isRayonnant
Etat courant de l'element (rayonnant ou non rayonnant)
virtual TYTabPoint3D getOContour(int n=-1) const
bool operator!=(const TYAcousticSemiCircle &other) const
Operateur !=.
virtual std::string toString() const
virtual int intersects(const TYSurfaceInterface *pSurf, OSegment3D &seg) const
virtual void exportMesh(std::deque< OPoint3D > &points, std::deque< OTriangle > &triangles, const TYGeometryNode &geonode) const
Export the surface as a triangular mesh.
virtual double surface() const
virtual TYTabSourcePonctuelleGeoNode getSrcs() const
virtual DOM_Element toXML(DOM_Element &domElement)
virtual OPlan plan() const
void setDiameter(double diameter)
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
virtual int fromXML(DOM_Element domElement)
TYAcousticSemiCircle & operator=(const TYAcousticSemiCircle &other)
Operateur =.
virtual TYSourcePonctuelle srcPonctEquiv() const
virtual TYTabPoint getContour(int n=-1) const
bool operator==(const TYAcousticSemiCircle &other) const
Operateur ==.
virtual OVector3D normal() const
TYAcousticSurface & operator=(const TYAcousticSurface &other)
Operateur =.
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
virtual TYTabSourcePonctuelleGeoNode getSrcs() const
LPTYRectangle _pBoundingRect
Rectangle englobant.
virtual bool setSrcsLw()
TYRectangle * getBoundingRect()
virtual DOM_Element toXML(DOM_Element &domElement)
LPTYSourceSurfacic _pSrcSurf
Source surfacique.
virtual int fromXML(DOM_Element domElement)
virtual void setColor(const OColor &color)
QString _name
Nom courant de l'element.
Definition: TYElement.h:966
void setParent(TYElement *pParent)
Definition: TYElement.h:692
virtual void setIsGeometryModified(bool isModified)
Definition: TYElement.cpp:253
OMatrix localToGlobal() const
QString generateName(const char *classname)
Retourne le nom de la classe associe a un nombre.
static TYNameManager * get()
Retourne l'instance singleton.
ORepere3D getORepere3D() const
virtual int intersects(const TYSurfaceInterface *pSurf, OSegment3D &seg) const
double getDiagSize()
TYPoint _pts[4]
Sommets.
Definition: TYRectangle.h:274
virtual OVector3D normal() const
void setDirectivity(TYDirectivity *directivity_)
: Get/Set directivity to source
void setTypeRaynt(TYTypeRaynt type)
double getDensiteSrcsH() const
bool addSrc(LPTYSourcePonctuelle pSrcPonct)
double getDensiteSrcsV() const
virtual int intersects(const OPoint3D &pt) const =0
#define M_PI
Pi.
Definition: color.cpp:25