Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYAcousticCircle.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"
21 #if TY_USE_IHM
25 #endif
26 #include "TYAcousticCircle.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 
49  OColor color;
50  color.r = r / 255;
51  color.g = g / 255;
52  color.b = b / 255;
53 
54  setColor(color);
55 }
56 
58 {
59  *this = other;
60 }
61 
63 
65 {
66  if (this != &other)
67  {
69  }
70  return *this;
71 }
72 
74 {
75  if (this != &other)
76  {
77  if (TYAcousticSurface::operator!=(other))
78  {
79  return false;
80  }
81  }
82  return true;
83 }
84 
86 {
87  return !operator==(other);
88 }
89 
90 bool TYAcousticCircle::deepCopy(const TYElement* pOther, bool copyId /*=true*/, bool pUseCopyTag /*=false*/)
91 {
92  return TYAcousticSurface::deepCopy(pOther, copyId);
93 }
94 
95 std::string TYAcousticCircle::toString() const
96 {
97  return "TYAcousticCircle";
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)(2 * M_PI * rayon / _pSrcSurf->getDensiteSrcsH());
136  nbSrcsAngulaire =
137  nbSrcsAngulaire < 2 ? 2 : nbSrcsAngulaire; // Au moins deux sources diametralement opposees
138  const double distAngulaire = 2 * M_PI / nbSrcsAngulaire;
139  // Distance radiale
140  const int nbSrcsRadiale = (int)(rayon / _pSrcSurf->getDensiteSrcsV());
141  double distRayon = 0;
142  if (nbSrcsRadiale > 0)
143  {
144  distRayon = rayon / (nbSrcsRadiale + 1);
145  }
146 
147  OMatrix matrix;
148  OPoint3D pt;
149  double angle = 0.0;
150  double posCercle = distRayon;
151 
152  // On recupere le repere local au plan du cercle
154  // On place l'origine au centre du cercle pour simplifier les calculs
155  repere._origin = getCenter();
156  // Matrice de changement de repere
157  matrix = repere.asMatrix();
158 
159  // On ajoute une source au centre dans tous les cas, on s'assure ainsi
160  // d'avoir toujours au moins une source sur la surface si les densites
161  // ne sont pas nulles
162  pt._x = 0.000, pt._y = 0.000;
163  pt._z = _offsetSources;
164  // On revient dans le repere d'origine
165  pt = matrix * pt;
166  // Creation de la source
168  *pSrc->getPos() = pt;
169  pSrc->setTypeRaynt(CALCULATED);
170 
171  // To define directivity
172  double specificSize = getDiameter();
173  OVector3D faceNormal = normal();
174  faceNormal.normalize();
176 
177  // Defining directivity and source creation
178  pSrc->setDirectivity(new TYComputedDirectivity(faceNormal, type, specificSize));
179  _pSrcSurf->addSrc(pSrc);
180 
181  for (int i = 0; i < nbSrcsRadiale; i++)
182  {
183  for (int j = 0; j < nbSrcsAngulaire; j++)
184  {
185  angle = j * distAngulaire;
186  ;
187  pt._x = cos(angle) * posCercle;
188  pt._y = sin(angle) * posCercle;
189  pt._z = _offsetSources;
190 
191  // On revient dans le repere d'origine
192  pt = matrix * pt;
193 
194  // Creation d'une source ponctuelle
196  pSrc->setDirectivity(new TYComputedDirectivity(faceNormal, type, specificSize));
197 
198  // Definition de sa position
199  *pSrc->getPos() = pt;
200 
201  // Definition des sources comme sources a directivite calculee
202  pSrc->setTypeRaynt(CALCULATED);
203 
204  // Ajout de la src ponct a la src surf
205  _pSrcSurf->addSrc(pSrc);
206  }
207 
208  // Increment du rayon
209  posCercle += distRayon;
210  }
211 }
212 
214 {
215  return TYAcousticSurface::setSrcsLw(); // Appel de la methode generale
216 }
217 
219 {
220  // Pi * Ri¿½
221  double rayon = getDiameter() / 2.0;
222  return (M_PI * rayon * rayon);
223 }
224 
226 {
227  return _pBoundingRect->normal();
228 }
229 
231 {
232  return OPlan(getCenter(), normal());
233 }
234 
236 {
237  TYTabPoint tab;
238 
239  if (n == -1)
240  {
241  // Prise en compte de la precision
242  n = ROUND((getDiameter() / 2.0) / TYPRECISIONCIRCLE);
243 
244  // On veut au moins tous les Pi/2 (90i¿½)
245  n = ROUND(n / 4 * 4);
246  }
247  else if ((getDiameter() == 0) || (n < 3))
248  {
249  return tab;
250  }
251 
252  OMatrix matrix;
253  TYSegment seg;
254  double angle = 0.0;
255  double rayon = getDiameter() / 2.0;
256 
257  // On recupere le repere local au plan du cercle
259 
260  // On place l'origine au centre du cercle pour simplifier les calculs
261  repere._origin = getCenter();
262 
263  // Matrice de changement de repere
264  matrix = repere.asMatrix();
265 
266  // On connait la taille du tableau de point a retourner
267  tab.reserve(n);
268  TYPoint pt;
269 
270  // On calcul la position de chaque portion
271  // (on travaille dans le repere local au plan du cercle)
272  for (int i = 0; i < n; i++)
273  {
274  // Increment de la portion (sens horaire)
275  angle = (M_2PI * (n - i)) / n;
276 
277  // Point correspondant
278  pt._x = cos(angle) * rayon;
279  pt._y = sin(angle) * rayon;
280  pt._z = 0;
281 
282  // On revient dans le repere d'origine
283  pt = matrix * pt;
284 
285  // On ajoute ce point au tableau
286  tab.push_back(pt);
287  }
288 
289  return tab;
290 }
291 
293 {
294  // TODO This is a mere duplicate of the getContour method and
295  // needs to be factorized
296  TYTabPoint3D tab;
297 
298  if (n == -1)
299  {
300  // Prise en compte de la precision
301  n = ROUND((getDiameter() / 2.0) / TYPRECISIONCIRCLE);
302 
303  // On veut au moins tous les Pi/2 (90i¿½)
304  n = ROUND(n / 4 * 4);
305  }
306  else if ((getDiameter() == 0) || (n < 3))
307  {
308  return tab;
309  }
310 
311  OMatrix matrix;
312  double angle = 0.0;
313  double rayon = getDiameter() / 2.0;
314 
315  // On recupere le repere local au plan du cercle
317 
318  // On place l'origine au centre du cercle pour simplifier les calculs
319  repere._origin = getCenter();
320 
321  // Matrice de changement de repere
322  matrix = repere.asMatrix();
323 
324  // On connait la taille du tableau de point a retourner
325  // tab.reserve(n);
326  OPoint3D pt;
327 
328  // On calcul la position de chaque portion
329  // (on travaille dans le repere local au plan du cercle)
330  for (int i = 0; i < n; i++)
331  {
332  // Increment de la portion (sens horaire)
333  angle = (M_2PI * (n - i)) / n;
334 
335  // Point correspondant
336  pt._x = cos(angle) * rayon;
337  pt._y = sin(angle) * rayon;
338  pt._z = 0;
339 
340  // On revient dans le repere d'origine
341  pt = matrix * pt;
342 
343  // On ajoute ce point au tableau
344  tab.push_back(pt);
345  }
346 
347  return tab;
348 }
349 
351 {
352  return TYSurfaceInterface::intersects(pSurf, seg);
353 }
354 
356 {
357  int res = INTERS_NULLE;
358 
359  res = _pBoundingRect->intersects(seg, pt);
360 
361  if (res != INTERS_NULLE)
362  {
363  res = intersects(pt);
364  }
365 
366  return res;
367 }
368 
370 {
371  int res = INTERS_NULLE;
372 
373  // Pour que le point coupe le cercle, la dist [centre du cercle , pt]
374  // doit etre <= au rayon du cercle
375 
376  double distPtCentre = OVector3D(pt, getCenter()).norme();
377 
378  if (2.0 * distPtCentre <= getDiameter())
379  {
380  res = INTERS_OUI;
381  }
382 
383  return res;
384 }
385 
387 {
388  OVector3D vecDiagonale(_pBoundingRect->_pts[0], _pBoundingRect->_pts[2]);
389  OVector3D vecCentre = OVector3D(_pBoundingRect->_pts[0]) + (vecDiagonale * 0.5);
390 
391  return TYPoint(vecCentre);
392 }
393 
395 {
397 }
398 
399 void TYAcousticCircle::setDiameter(double diameter)
400 {
401  double rayon = diameter / 2.0;
402  double norm = sqrt(2.0) * rayon;
403 
404  OPoint3D ptCenter = getCenter();
405  OVector3D vecOP0(ptCenter, _pBoundingRect->_pts[0]);
406  double normOP0 = vecOP0.norme();
407  OVector3D vecOP1(ptCenter, _pBoundingRect->_pts[1]);
408  double normOP1 = vecOP1.norme();
409  OVector3D vecOP2(ptCenter, _pBoundingRect->_pts[2]);
410  double normOP2 = vecOP2.norme();
411  OVector3D vecOP3(ptCenter, _pBoundingRect->_pts[3]);
412  double normOP3 = vecOP3.norme();
413 
414  if ((normOP0 == 0) || (normOP1 == 0) || (normOP2 == 0) || (normOP3 == 0))
415  {
416  // Cercle invalide
417  return;
418  }
419 
420  OVector3D vecPtCenter = getCenter();
421 
422  _pBoundingRect->_pts[0] = vecPtCenter + (vecOP0 * (norm / normOP0));
423  _pBoundingRect->_pts[1] = vecPtCenter + (vecOP1 * (norm / normOP1));
424  _pBoundingRect->_pts[2] = vecPtCenter + (vecOP2 * (norm / normOP2));
425  _pBoundingRect->_pts[3] = vecPtCenter + (vecOP3 * (norm / normOP3));
426 
427  setIsGeometryModified(true);
428 }
429 
430 void TYAcousticCircle::exportMesh(std::deque<OPoint3D>& points, std::deque<OTriangle>& triangles,
431  const TYGeometryNode& geonode) const
432 {
433  assert(points.size() == 0 && "Output arguments 'points' is expected to be initially empty");
434  assert(triangles.size() == 0 && "Output arguments 'triangles' is expected to be initially empty");
435 
436  int resolution = TYDEFAULTRESOLUTIONIONCIRCLE;
437 #if TY_USE_IHM
438  if (TYPreferenceManager::exists(TYDIRPREFERENCEMANAGER, "ResolutionCircle"))
439  {
440  resolution = TYPreferenceManager::getInt(TYDIRPREFERENCEMANAGER, "ResolutionCircle");
441  }
442  else
443  {
444  TYPreferenceManager::setInt(TYDIRPREFERENCEMANAGER, "ResolutionCircle", resolution);
445  }
446 #endif // TY_USE_IHM
447 
448  TYTabPoint3D poly = getOContour(resolution);
449 
450  // 1. We set all points to global repere
451  // Point[0] is the center
452  OPoint3D center = geonode.localToGlobal() * getCenter();
453 
454  // Points are added inreverse order to have correct normal direction
455  for (int i = 0; i < poly.size(); ++i)
456  {
457  points.push_front(geonode.localToGlobal() * poly[i]);
458  }
459 
460  points.push_front(center);
461 
462  // 2. Now, we create triangles
463  for (int i = 1; i < resolution; ++i)
464  {
465  OTriangle tri(center, points[i], points[i + 1]);
466  tri._p1 = 0;
467  tri._p2 = i;
468  tri._p3 = i + 1;
469  triangles.push_back(tri);
470  }
471 
472  OTriangle tri(center, points[resolution], points[1]);
473  tri._p1 = 0;
474  tri._p2 = resolution;
475  tri._p3 = 1;
476  triangles.push_back(tri);
477 }
All base classes related to 3D manipulation.
#define M_2PI
2Pi.
Definition: 3d.h:55
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
Representation graphique d'un cercle accoustique (fichier header)
outil IHM pour un cercle acoustique (fichier header)
TY_EXT_GRAPHIC_INST(TYAcousticCircle)
TY_EXTENSION_INST(TYAcousticCircle)
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
virtual TYSourcePonctuelle srcPonctEquiv() const
virtual OVector3D normal() const
virtual std::string toString() const
virtual ~TYAcousticCircle()
virtual OPlan plan() const
virtual void exportMesh(std::deque< OPoint3D > &points, std::deque< OTriangle > &triangles, const TYGeometryNode &geonode) const
Export the surface as a triangular mesh.
TYAcousticCircle & operator=(const TYAcousticCircle &other)
Operateur =.
virtual double surface() const
virtual TYTabSourcePonctuelleGeoNode getSrcs() const
void setDiameter(double diameter)
bool operator==(const TYAcousticCircle &other) const
Operateur ==.
TYPoint getCenter() const
virtual TYTabPoint3D getOContour(int n=-1) const
virtual void distriSrcs()
virtual int intersects(const TYSurfaceInterface *pSurf, OSegment3D &seg) const
virtual DOM_Element toXML(DOM_Element &domElement)
virtual int fromXML(DOM_Element domElement)
bool operator!=(const TYAcousticCircle &other) const
Operateur !=.
virtual TYTabPoint getContour(int n=-1) const
double getDiameter() const
virtual bool setSrcsLw()
virtual bool deepCopy(const TYElement *pOther, bool copyId=true, bool pUseCopyTag=false)
double _offsetSources
Offset de decalage des sources ponctuelles sur les surfaces.
bool _isRayonnant
Etat courant de l'element (rayonnant ou non rayonnant)
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()
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
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
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