Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYSetGeometriqueParcours.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 /*
17  *
18  */
19 
20 #include <math.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <math.h>
24 
27 #include "TYPointParcours.h"
28 #include <assert.h>
29 #include <algorithm>
30 
35 
36 // Return Value Description for Qsort compare
37 //< 0 elem1 less than elem2
38 // 0 elem1 equivalent to elem2
39 //> 0 elem1 greater than elem2
40 int compareTYPolyligneParcours(const void* p1, const void* p2)
41 {
44  int indexPointPoly1 = P1->indexePoint1();
45  int indexPointPoly2 = P2->indexePoint1();
46  assert(indexPointPoly1 >= 0);
47  assert(indexPointPoly2 >= 0);
48  // Si les 2 premiers indexes sont egaux, on regarde les suivants:
49  if (indexPointPoly1 == indexPointPoly2)
50  {
51  indexPointPoly1 = P1->indexePoint2();
52  indexPointPoly2 = P2->indexePoint2();
53  }
54  return (indexPointPoly1 - indexPointPoly2);
55 }
56 
58 {
59  // Copie des points
62  int i = 0, j = 0;
63  for (i = 0; i < _nNbPointTotal; i++)
64  {
65  _ListePoint[i] = geoIn._ListePoint[i];
66  }
67  // Copie des polylignes
70  for (i = 0; i < _nNbPolylines; i++)
71  {
73  for (j = 0; j < geoIn._ListePolylines[i].nombreDePoint(); j++)
74  {
75  // Indexe du point dans la liste de point:
76  int indexePoint = geoIn._ListePolylines[i].indexePoint(j);
77  // Copie de la reference:
78  _ListePolylines[i].ajoutePoint(j, &(_ListePoint[indexePoint]));
79  }
80  }
81 }
82 
84 {
86  tmp = _ListePolylines[i];
88  _ListePolylines[j] = tmp;
89 }
90 
92 {
93  int nNbDoublons = 0;
94  // Cette methode elimine 2 sortes de segments:
95  // 1. segments bouclant sur le meme point
96  // 2. segments doubles (Ex: [P1,P2] & [P2,P1])
97  // Pour ce traitement, on trie la liste de polyligne de 2 facons:
98  // 1. l'indice du premier point doit etre le plus faible (swap au besoin dans chaque polyligne)
99  // 2. suivant la valeur du premier indice
100 
101  // 1. Swap des indexes de points si necessaire
102  int indexPoint1 = 0, indexPoint2 = 0, i = 0, j = 0;
103  for (i = 0; i < _nNbPolylines; i++)
104  {
105  assert(_ListePolylines[i].nombreDePoint() == 2);
106  indexPoint1 = _ListePolylines[i].indexePoint1();
107  indexPoint2 = _ListePolylines[i].indexePoint2();
108  assert(indexPoint1 >= 0);
109  assert(indexPoint2 >= 0);
110  if (indexPoint1 > indexPoint2)
111  {
112  // Swap
113  _ListePolylines[i].setPoint(0, &(_ListePoint[indexPoint2]));
114  _ListePolylines[i].setPoint(1, &(_ListePoint[indexPoint1]));
115  }
116  }
117  // 2. QSort sur les polylignes (base sur le fait que toutes les polylignes contiennent 2 points
118  // exactement)
119  qsort((void*)_ListePolylines, (size_t)_nNbPolylines, sizeof(TYPolyligneParcours),
121 
122  // 3."Suppression" des segments ayant les memes indexes
123  i = 0;
124  j = 1;
125  int nOldNbPolylines = _nNbPolylines;
126  while (i < _nNbPolylines)
127  {
128  indexPoint1 = _ListePolylines[i].indexePoint1();
129  indexPoint2 = _ListePolylines[i].indexePoint2();
130  while (j < nOldNbPolylines && indexPoint1 == _ListePolylines[j].indexePoint1() &&
131  indexPoint2 == _ListePolylines[j].indexePoint2())
132  {
133  _nNbPolylines--;
134  nNbDoublons++;
135  j++;
136  }
137  i++;
138  if (i != j && j < nOldNbPolylines)
139  {
141  }
142  j++;
143  }
144 
145  // 4."Suppression" des segments bouclant sur le meme point
146  for (i = 0; i < _nNbPolylines; i++)
147  {
148  indexPoint1 = _ListePolylines[i].indexePoint1();
149  indexPoint2 = _ListePolylines[i].indexePoint2();
150  if (indexPoint1 == indexPoint2)
151  {
152  if (i != (_nNbPolylines - 1))
153  {
155  }
156  i--; // reverifier si la nouvelle n'est pas redondante
157  _nNbPolylines--;
158  nNbDoublons++;
159  }
160  }
161 
162  return nNbDoublons;
163 }
164 
166 {
167  int i = 0, j = 0, index = 0, doublons = 0;
168  // 1. On modifie les identifiants des points doubles (on suppose qu'ils sont dans l'ordre):
169  for (i = 0; i < _nNbPointTotal; i++)
170  {
171  for (j = i; j < _nNbPointTotal; j++)
172  {
173  // Ne pas merger les points appartenant a 2 types de courbes (infra & topo)
174  bool bPointAppartenantAuMemeType = ((_ListePoint[i].isEcran == _ListePoint[j].isEcran) &&
175  (_ListePoint[i].isInfra == _ListePoint[j].isInfra));
176  if ((bPointAppartenantAuMemeType) && (_ListePoint[j].Identifiant > i) &&
178  {
179  _ListePoint[j].Identifiant = -i; // les points inutilises ont des indexes negatifs
180  doublons++;
181  }
182  }
183  }
184  // 2. On modifie les ptr sur points des polylignes:
185  for (i = 0; i < _nNbPolylines; i++)
186  {
187  for (j = 0; j < _ListePolylines[i].nombreDePoint(); j++)
188  {
189  index = _ListePolylines[i].indexePoint(j);
190  do // attention, le point peut faire reference a un point lui-meme doublon (donc ayant un id
191  // negatif)
192  {
193  index = abs(index);
194  index = _ListePoint[index].Identifiant;
195  } while (index < 0);
196  _ListePolylines[i].setPoint(j, &(_ListePoint[index]));
197  }
198  }
199  return doublons;
200 }
201 
203  TYPointParcours& Srce, TYPointParcours& Dest, int* IndexePointsFrontiere, int& NbPointsFrontiere,
204  std::vector<bool>& pEstUnPointIntersectant, bool bCoteGauche, bool* PointsAGauche, bool* PointsADroite)
205 {
206  int i = 0, indexePoint = 0, indexePoint1 = 0, indexePoint2 = 0;
207  int nAncienNbPointTotal = _nNbPointTotal / 2; // cf SeparationDroiteGauche
208  // Initialisation
209  NbPointsFrontiere = 0;
210  pEstUnPointIntersectant.clear();
211  for (i = 0; i < _nNbPointTotal; i++)
212  {
213  pEstUnPointIntersectant.push_back(false);
214  }
215  for (i = 0; i < _nNbPolylines; i++)
216  {
217  // 1. Recherche des segments traversant [SR]
218  // Attention !! On considere que les polylignes ne sont que des segments (nb point = 2).
219  assert(2 == _ListePolylines[i].nombreDePoint());
220  // Indexe du point dans la liste de point:
221  indexePoint1 = _ListePolylines[i].indexePoint1();
222  indexePoint2 = _ListePolylines[i].indexePoint2();
223  // Est-ce qu'un des points est des deux cotes ?
224  if (PointsAGauche[indexePoint1] == PointsADroite[indexePoint1])
225  {
226  // Oui le marquer
227  pEstUnPointIntersectant[indexePoint1] = true;
228  IndexePointsFrontiere[NbPointsFrontiere] = indexePoint1;
229  NbPointsFrontiere++;
230  continue;
231  }
232  if (PointsAGauche[indexePoint2] == PointsADroite[indexePoint2])
233  {
234  // Oui le marquer
235  pEstUnPointIntersectant[indexePoint2] = true;
236  IndexePointsFrontiere[NbPointsFrontiere] = indexePoint2;
237  NbPointsFrontiere++;
238  continue;
239  }
240  // Y a-t-il passage de frontiere ?
241  bool b2PointsAGauche = PointsAGauche[indexePoint1] && PointsAGauche[indexePoint2];
242  bool b2PointsADroite = PointsADroite[indexePoint1] && PointsADroite[indexePoint2];
243  if (b2PointsAGauche || b2PointsADroite)
244  {
245  continue; // non
246  }
247  int nIndexePointFrontiereDansSegment = 0;
248  if (bCoteGauche)
249  {
250  nIndexePointFrontiereDansSegment = PointsADroite[indexePoint1] ? 0 : 1;
251  }
252  else
253  {
254  nIndexePointFrontiereDansSegment = PointsAGauche[indexePoint1] ? 0 : 1;
255  }
256  indexePoint = _ListePolylines[i].indexePoint(nIndexePointFrontiereDansSegment);
257  // Retenir l'autre point
258  // 2. Modification du point donnant lieu a un point frontiere
259  // Ce passage de frontiere peut donner lieu a 2 points d'intersections sur SR,
260  // si une autre polyligne rejoint ce point (indexePoint) de l'autre ci��te
261  //=> on cree un nouveau point ayant les memes coordonnees:
262  _ListePoint[nAncienNbPointTotal] = _ListePoint[indexePoint];
263  _ListePoint[nAncienNbPointTotal].Identifiant = nAncienNbPointTotal;
264  // Modifier la reference dans la polyligne
265  _ListePolylines[i].setPoint(nIndexePointFrontiereDansSegment, &(_ListePoint[nAncienNbPointTotal]));
266  indexePoint = nAncienNbPointTotal;
267  nAncienNbPointTotal++;
268 
269  // Marquer le point frontiere:
270  IndexePointsFrontiere[NbPointsFrontiere] = indexePoint;
271  pEstUnPointIntersectant[indexePoint] = true;
272  // Calculer l'intersection avec [SR]:
273  TYPointParcours::IntersectionDroites(Srce, Dest, _ListePoint[indexePoint1], _ListePoint[indexePoint2],
274  _ListePoint[indexePoint]);
275  NbPointsFrontiere++;
276  }
277 }
278 
280  bool*& PointsAGauche, bool*& PointsADroite)
281 {
282  // 1. Etablir une liste des points a droite, une autre de ceux a gauche
283  // Rq: on a 2 listes car on prend aussi les points sur la frontiere
284  // Inversion S-R si necessaire
285  // bool bSAGaucheDeR = ListePointSR[0].x < ListePointSR[1].x;
286  // Signe de l'angle
287  // sign = (vec1.cross(vec2)._z > 0) ? -1 : 1;
288  PointsAGauche = new bool[_nNbPointTotal];
289  PointsADroite = new bool[_nNbPointTotal];
290  TYPointParcours SR = Dest;
291  SR.x -= Srce.x;
292  SR.y -= Srce.y;
293  for (int i = 0; i < _nNbPointTotal; i++)
294  {
295  // Est-ce un point racine ?
296  if (_ListePoint[i].Identifiant == i)
297  {
299  SP.x -= Srce.x;
300  SP.y -= Srce.y;
301  PointsAGauche[i] = TYPointParcours::ZCross(SR, SP) > 0;
302  PointsADroite[i] = TYPointParcours::ZCross(SR, SP) < 0;
303  }
304  else
305  {
306  PointsAGauche[i] = false;
307  PointsADroite[i] = false;
308  }
309  }
310 }
311 
312 void TYSetGeometriqueParcours::SeparationDroiteGauche(bool* PointsAGauche, bool* PointsADroite,
313  TYSetGeometriqueParcours& geoGauche,
314  TYSetGeometriqueParcours& geoDroite)
315 {
316  int i = 0, j = 0, indexePoint = 0;
317  // 2. Marquer les polylignes oi�� au moins un point est a gauche (idem pour la droite)
318  bool* bAuMoinsUnPointAGauche = new bool[_nNbPolylines];
319  bool* bAuMoinsUnPointADroite = new bool[_nNbPolylines];
320  for (i = 0; i < _nNbPolylines; i++)
321  {
322  bAuMoinsUnPointAGauche[i] = false;
323  bAuMoinsUnPointADroite[i] = false;
324  // Cette polyligne a-t-elle au moins un point a gauche (/ droite)?
325  for (j = 0; j < _ListePolylines[i].nombreDePoint() &&
326  (!bAuMoinsUnPointADroite[i] || !bAuMoinsUnPointAGauche[i]);
327  j++)
328  {
329  indexePoint = _ListePolylines[i].indexePoint(j);
330  if (indexePoint < _nNbPointTotal)
331  {
332  bAuMoinsUnPointAGauche[i] = bAuMoinsUnPointAGauche[i] || PointsAGauche[indexePoint];
333  bAuMoinsUnPointADroite[i] = bAuMoinsUnPointADroite[i] || PointsADroite[indexePoint];
334  }
335  }
336  }
337  // 3. Les listes (geo) gauche, doite et principale doivent etre independantes
338  //=>on en cree de nouvelles
339  // Copie des points
340  // facteur 2 : precaution due au fait que les points a ramener a la frontiere peuvent donner 2 points
341  // d'intersection
342  geoGauche._ListePoint = new TYPointParcours[2 * _nNbPointTotal];
343  geoDroite._ListePoint = new TYPointParcours[2 * _nNbPointTotal];
344  for (i = 0; i < _nNbPointTotal; i++)
345  {
346  geoGauche._ListePoint[i] = _ListePoint[i];
347  geoDroite._ListePoint[i] = _ListePoint[i];
348  }
349  geoGauche._nNbPointTotal = 2 * _nNbPointTotal;
350  geoDroite._nNbPointTotal = 2 * _nNbPointTotal;
351  // Copie des polylignes
352  geoGauche.AllouerPolylignes(_nNbPolylines);
353  geoDroite.AllouerPolylignes(_nNbPolylines);
354  geoGauche._nNbPolylines = 0;
355  geoDroite._nNbPolylines = 0;
356 
357  for (i = 0; i < _nNbPolylines; i++)
358  {
359  // Fix issue #139
360  // Source and receptor have indexes of MAX_INT and MAX_INT-1
361  // They must not be processed here because it's useless and provokes outofbound access on static
362  // arrays
363  if (polyligneContientSouR(i))
364  {
365  continue;
366  }
367 
368  if (bAuMoinsUnPointAGauche[i])
369  {
370  // On ajoute cette polyligne
371  geoGauche._ListePolylines[geoGauche._nNbPolylines].allouer(_ListePolylines[i].nombreDePoint());
372  // Copie des references de point
373  for (j = 0; j < _ListePolylines[i].nombreDePoint(); j++)
374  {
375  // Indexe du point dans la liste de point:
376  indexePoint = _ListePolylines[i].indexePoint(j);
377  // Copie de la reference:
378  geoGauche._ListePolylines[geoGauche._nNbPolylines].ajoutePoint(
379  j, &(geoGauche._ListePoint[indexePoint]));
380  }
381  geoGauche._nNbPolylines++;
382  }
383  if (bAuMoinsUnPointADroite[i])
384  {
385  // On ajoute cette polyligne
386  geoDroite._ListePolylines[geoDroite._nNbPolylines].allouer(_ListePolylines[i].nombreDePoint());
387  // Copie des references de point
388  for (j = 0; j < _ListePolylines[i].nombreDePoint(); j++)
389  {
390  // Indexe du point dans la liste de point:
391  indexePoint = _ListePolylines[i].indexePoint(j);
392  // Copie de la reference:
393  geoDroite._ListePolylines[geoDroite._nNbPolylines].ajoutePoint(
394  j, &(geoDroite._ListePoint[indexePoint]));
395  }
396  geoDroite._nNbPolylines++;
397  }
398  }
399  // CherchePointsAGauche(PointsAGauche, geoGauche._ListePolylines, geoGauche._nNbPolylines,
400  // geoGauche._ListePoint, geoGauche._nNbPointTotal);
401  SAFE_DELETE_LIST(bAuMoinsUnPointAGauche);
402  SAFE_DELETE_LIST(bAuMoinsUnPointADroite);
403 }
404 
406 {
407  bool ret = false;
408  for (int j = 0; j < _ListePolylines[i].nombreDePoint(); j++)
409  {
410  if (_ListePolylines[i].indexePoint(j) >= _nNbPointTotal)
411  {
412  ret = true;
413  break;
414  }
415  }
416  return ret;
417 }
418 
419 // Return Value Description for Qsort compare
420 //< 0 elem1 less than elem2
421 // 0 elem1 equivalent to elem2
422 //> 0 elem1 greater than elem2
423 int compareAbscissesCurvilignes(const void* p1, const void* p2)
424 {
428  int e1 = *((int*)(p1));
429  int e2 = *((int*)(p2));
430  TYPointParcours& P1 = ListePoint[e1];
431  TYPointParcours& P2 = ListePoint[e2];
432 
433  double dAbscisseCurviligneCP1 = TYPointParcours::AbscisseCurviligneCarreSurSR(P1, *Srce, *Dest);
434  double dAbscisseCurviligneCP2 = TYPointParcours::AbscisseCurviligneCarreSurSR(P2, *Srce, *Dest);
435 
436  if (dAbscisseCurviligneCP1 < dAbscisseCurviligneCP2)
437  {
438  return -1;
439  }
440  if (dAbscisseCurviligneCP1 > dAbscisseCurviligneCP2)
441  {
442  return 1;
443  }
444  return 0;
445 }
446 
448  int* IndexePointsFrontiere,
449  int NbPointsFrontiere)
450 {
451  // int i;
452  // TYPointParcours* P;
453  // double PDist;
454 
455  if (NbPointsFrontiere == 0)
456  {
457  return;
458  }
459 
460  /*
461  for(i=0; i < NbPointsFrontiere;i++)
462  {
463  P = &(_ListePoint[IndexePointsFrontiere[i]]);
464  if (P != NULL)
465  PDist = fabs(P->x - Srce.x) + fabs(P->y-Srce.y);
466  }
467  */
468  // Quick Sort
473  qsort((void*)IndexePointsFrontiere, (size_t)NbPointsFrontiere, sizeof(int), compareAbscissesCurvilignes);
475  // qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void
476  // *elem2 ) );
477 
478  /*
479  for(i=0; i < NbPointsFrontiere;i++)
480  {
481  P = &(_ListePoint[IndexePointsFrontiere[i]]);
482  if (P != NULL)
483  PDist = fabs(P->x - Srce.x) + fabs(P->y-Srce.y);
484  }
485  */
486 }
487 
489 {
490  assert(_ListePolylines);
491  assert(_ListePoint);
492  // Enregistrement du point:
494  _ListePolylines[indexPolyligne].ajoutePoint(_ListePolylines[indexPolyligne].nombreDePoint(),
496  _nNbPointTotal++;
497  return true;
498 }
499 
501  TYPolyligneParcours*& PolyligneRacine,
502  std::vector<bool>& pEstUnPointIntersectant,
503  TYSetGeometriqueParcours& geoPremierePasse)
504 {
505  int IndexPoint = IndexPointRacine;
506  int IndexPointSuivant = 0;
507  // Cette methode ajoute les points rencontres sur la polyligne racine, dans le sens impose par le point
508  // racine Le point racine est-il le premier ou le second point de la polyligne racine ?
509  TYPolyligneParcours* PolyligneCourante = PolyligneRacine;
510  TYPolyligneParcours* PolyligneSuivante = PolyligneCourante;
511  do
512  {
513  // Memorisons la derniere polyligne non nulle:
514  PolyligneRacine = PolyligneCourante;
515  IndexPointSuivant = PolyligneCourante->indexePointSuivant(IndexPoint, PolyligneSuivante);
516  // Enregistrer l'autre point du segment
517  geoPremierePasse.AjoutePointALaPolyLigne(0, _ListePoint[IndexPointSuivant]);
518  IndexPoint = IndexPointSuivant;
519  } while (NULL != PolyligneSuivante && !pEstUnPointIntersectant[IndexPoint] &&
520  (PolyligneCourante = PolyligneSuivante));
521 
522  return IndexPoint;
523 }
524 
526 {
527  // Verifier que toutes les polylignes d'infra sont fermees, exceptees les ecrans
528  for (int i = 0; i < _nNbPolylines; i++)
529  {
530  if (_ListePolylines[i].isInfra() && !_ListePolylines[i].isEcran())
531  {
532  if (!_ListePolylines[i].estSurUnParcourFermee())
533  {
534  return false;
535  }
536  }
537  }
538  return true;
539 }
540 
542  std::vector<bool>& pEstUnPointIntersectant)
543 {
544  // Cette methode rempli la structure Connexes, attribut de chaque point:
545  int i = 0, j = 0;
546  // Initialiser la liste
547  for (i = 0; i < this->_nNbPointTotal; i++)
548  {
549  Connexes[i].IndexesSegment[0] = -1; // Premier segment incluant ce point
550  Connexes[i].IndexesSegment[1] = -1; // Second segment incluant ce point
551  Connexes[i].NbSegmentsConnexes = 0; // Nb de segment incluant ce point
552  }
553  // Pour chaque polyligne, construire une liste de points connexes :
554  // on renseigne les champs NbSegmentsConnexes & IndexesSegment
555  int indexePoint = 0;
556  for (i = 0; i < _nNbPolylines; i++)
557  {
558  assert(_ListePolylines[i].nombreDePoint() == 2);
559  for (j = 0; j < _ListePolylines[i].nombreDePoint(); j++)
560  {
561  indexePoint = _ListePolylines[i].indexePoint(j);
562  int NbSegmentsConnexes = Connexes[indexePoint].NbSegmentsConnexes;
563  // A-t-on deja 2 segments connexes pour ce point ?
564  if (NbSegmentsConnexes >= 2)
565  {
566  // Oui=>il faudrait dedoubler ce point
567  TYPointParcours* _newListePoint = new TYPointParcours[_nNbPointTotal + 1];
568  std::copy(_ListePoint, _ListePoint + _nNbPointTotal, _newListePoint);
569  for (int a = 0; a < _nNbPolylines; a++)
570  {
571  for (int b = 0; b < _ListePolylines[a].nombreDePoint(); b++)
572  {
573  int index = _ListePolylines[a].indexePoint(b);
574  _ListePolylines[a].setPoint(b, &(_newListePoint[index]));
575  }
576  }
577  delete[] _ListePoint;
578  _ListePoint = _newListePoint;
579  Connexite* newConnexes = new Connexite[_nNbPointTotal + 1];
580  std::copy(Connexes, Connexes + _nNbPointTotal, newConnexes);
581  delete[] Connexes;
582  Connexes = newConnexes;
583 
585  p->isInfra = _ListePoint[indexePoint].isInfra;
586  p->isEcran = _ListePoint[indexePoint].isEcran;
587  p->x = _ListePoint[indexePoint].x;
588  p->y = _ListePoint[indexePoint].y;
589  p->z = _ListePoint[indexePoint].z;
591  _ListePolylines[i].setPoint(j, p);
592 
593  newConnexes[_nNbPointTotal].IndexesSegment[0] = -1; // Premier segment incluant ce point
594  newConnexes[_nNbPointTotal].IndexesSegment[1] = -1; // Second segment incluant ce point
595  newConnexes[_nNbPointTotal].NbSegmentsConnexes = 0; // Nb de segment incluant ce point
596  NbSegmentsConnexes = 0;
597 
598  // Fix issue #91 : array _estUnPointIntersectant must be extended
599  pEstUnPointIntersectant.push_back(pEstUnPointIntersectant[indexePoint]);
600 
601  indexePoint = _nNbPointTotal;
602  _nNbPointTotal++;
604  assert(NbSegmentsConnexes < 2);
605  }
606  Connexes[indexePoint].IndexesSegment[NbSegmentsConnexes] = i;
607  Connexes[indexePoint].NbSegmentsConnexes++;
608  }
609  }
610  // Pour faciliter le parcours, on affecte le ptr sur les polylignes voisines de la courante
611  //=> on renseigne les champs _PolyligneP0 & _PolyligneP1
612  for (i = 0; i < _nNbPolylines; i++)
613  {
614  //_PolyligneP0 & _PolyligneP1 pointent imperativement:
615  //- sur une autre polyligne que la courante
616  //- sur 2 polylignes differentes (sauf si aucune polyligne voisine)
617  assert(_ListePolylines[i].nombreDePoint() == 2);
618  // Creons des alias de type tableau sur les voisines _PolyligneP0 & _PolyligneP1
619  TYPolyligneParcours** pPolylignesVoisines[2];
620  pPolylignesVoisines[0] = &(_ListePolylines[i]._PolyligneP0);
621  pPolylignesVoisines[1] = &(_ListePolylines[i]._PolyligneP1);
622  int NbSegmentsConnexes = Connexes[indexePoint].NbSegmentsConnexes; // verification supplementaire
623 
624  for (j = 0; j < 2; j++) // test enleve pour tester que pPolylignesVoisines[j] vaut bien NULL
625  {
626  assert((*pPolylignesVoisines[j]) == NULL); // l'initialisation devrait etre deja faite
627  // On s'occupe des segments connexes au point j du segment courant
628  int IndexePj = _ListePolylines[i].indexePoint(j);
629  // Premier segment connexe
630  int indexeSegmentj = Connexes[IndexePj].IndexesSegment[0];
631  if (indexeSegmentj != i && indexeSegmentj != -1) // la voisine n'est ni la courante, ni
632  // inexistante
633  {
634  // Le premier segment connexe est un voisin acceptable
635  *(pPolylignesVoisines[j]) = &(_ListePolylines[indexeSegmentj]);
636  }
637  else
638  {
639  // Testons le second segment:
640  indexeSegmentj = Connexes[IndexePj].IndexesSegment[1];
641  if (indexeSegmentj != i && indexeSegmentj != -1)
642  // Le second segment connexe est un voisin acceptable
643  {
644  *(pPolylignesVoisines[j]) = &(_ListePolylines[indexeSegmentj]);
645  }
646  else
647  {
648  *(pPolylignesVoisines[j]) = NULL; // par securite
649  }
650  }
651  NbSegmentsConnexes--;
652  }
653  // Verifions que les voisins des 2 points du segment ne sont pas les memes!
654  bool bP0P1PointentSurMemePolyligne =
656  bool bAssert = bP0P1PointentSurMemePolyligne ? (_ListePolylines[i]._PolyligneP0 == NULL) : true;
657 
658  assert(bAssert);
659  if (!bAssert)
660  {
661  bAssert = true;
662  }
663  }
664  return true;
665 }
666 
668  int* IndexePointsFrontiere, int NbPointsFrontiere,
669  std::vector<bool>& pEstUnPointIntersectant, Connexite* Connexes,
670  TYSetGeometriqueParcours& geoPremierePasse)
671 {
672 
673  // Retourne false si on est enferme
674  // La premiere passe consiste en la creation d'un parcours longeant toutes les polylignes intersectantes
675  // 1. Ordonner les points d'intersection
676 
677  TriePointsIntersectionSuivantSR(Srce, Dest, IndexePointsFrontiere, NbPointsFrontiere);
678 
679  // 2.1 Trouver le premier point d'intersection apres S
680  int i = 0;
681  while (i < NbPointsFrontiere &&
682  TYPointParcours::Scalaire(Srce, _ListePoint[IndexePointsFrontiere[i]], Srce, Dest) < 0)
683  {
684  i++;
685  }
686  int PremierPointIntersection = i;
687  while (i < NbPointsFrontiere &&
688  TYPointParcours::Scalaire(Dest, _ListePoint[IndexePointsFrontiere[i]], Dest, Srce) > 0)
689  {
690  i++;
691  }
692  int DernierPointIntersection = i;
693 
694  // 3. Allouer de la memoire pour les points du trajet
695  geoPremierePasse._ListePolylines = new TYPolyligneParcours[1];
696  geoPremierePasse._ListePolylines[0].allouer(4 * _nNbPointTotal);
697  geoPremierePasse._ListePoint = new TYPointParcours[4 * _nNbPointTotal]; // au pire, on parcours tout 2
698  // fois
699  geoPremierePasse._nNbPointTotal = 0;
700  geoPremierePasse._nNbPolylines = 1;
701 
702  // 4. Parcourir les polylignes
703  geoPremierePasse.AjoutePointALaPolyLigne(0, Srce);
704  for (i = PremierPointIntersection; i < DernierPointIntersection; i++)
705  {
706  // Le point suivant du parcourt est la prochaine intersection:
707  int IndexPoint = IndexePointsFrontiere[i];
708  // A quelle polyligne appartient ce point ?
709  int indexPolyligne = Connexes[IndexPoint].IndexesSegment[0];
710  TYPolyligneParcours* PolyligneCourante = &(_ListePolylines[indexPolyligne]);
711  // Il faut parcourir cette polyligne et ses connexes pour en enregistrer les points
712  // Attention au sens, car le point d'intersection peut etre le second de la polyligne
713  // On enregistre pas le point racine:
714  geoPremierePasse.AjoutePointALaPolyLigne(0, _ListePoint[IndexPoint]);
715  IndexPoint = ParcourtPolyligneAPartirDe(IndexPoint, PolyligneCourante, pEstUnPointIntersectant,
716  geoPremierePasse);
717  // Le dernier point est-il un point d'intersection ?
718  if (pEstUnPointIntersectant[IndexPoint])
719  {
720  // On finit par un point d'intersection
721  // Est-il derriere S ?
722  if (TYPointParcours::Scalaire(Srce, _ListePoint[IndexPoint], Srce, Dest) < 0)
723  // Oui=>retourner faux car on est emprisonne
724  {
725  return false;
726  }
727  // Est-il devant R ?
728  if (TYPointParcours::Scalaire(Dest, _ListePoint[IndexPoint], Dest, Srce) < 0)
729  // Oui=>retourner faux car on est emprisonne
730  {
731  return false;
732  }
733  // On a peut etre passe d'autres points d'intersection: tant mieux !
734  // Mais il faut savoir oi�� on en est dans les points d'intersection:
735  while (i < NbPointsFrontiere && IndexPoint != IndexePointsFrontiere[i])
736  {
737  i++;
738  }
739  }
740  else
741  {
742  // On ne finit pas par un point d'intersection
743  if (!PolyligneCourante->isEcran())
744  {
745  return false; // on considere que le rayon est parti dans la nature
746  }
747  //=>il faut parcourir la polyligne courante dans l'autre sens
748  IndexPoint = ParcourtPolyligneAPartirDe(IndexPoint, PolyligneCourante, pEstUnPointIntersectant,
749  geoPremierePasse);
750  }
751  }
752  // Ajout du recepteur
753  geoPremierePasse.AjoutePointALaPolyLigne(0, Dest);
754  return true;
755 }
756 
758  TYSetGeometriqueParcours& geoSecondePasse,
759  bool bTrajetsAGaucheDeSR, TYPointParcours**& pTableauEC,
760  int& nbPtsEC)
761 {
762  int i = 0;
763 
764  // 1. Calcul de l'EC de geoPremierePasse
765  // 1.1 Recuperer les points de la premiere passe
766  int nNbPointsPremierePasse = geoPremierePasse._nNbPointTotal;
767 
768  // XBH : 12/10/2004 - if nothing to compute, exit now!
769  if (nNbPointsPremierePasse == 0)
770  {
771  return false;
772  }
773 
774  TYPointParcours** TableauDePointsPremierePasse = new TYPointParcours*[nNbPointsPremierePasse];
775  for (i = 0; i < nNbPointsPremierePasse; i++)
776  {
777  TableauDePointsPremierePasse[i] = &(geoPremierePasse._ListePoint[i]);
778  }
779  // calcul de l'EC de cet ensemble
780  TYPointParcours** TableauDePointsEC = new TYPointParcours*[nNbPointsPremierePasse];
781  int nNbPointsEC = 0;
782 
783  // Mettons R en seconde position dans le tableau (exige pour le calcul d'EC)
784  TYPointParcours* pRecepteur = TableauDePointsPremierePasse[nNbPointsPremierePasse - 1];
785  TableauDePointsPremierePasse[nNbPointsPremierePasse - 1] = TableauDePointsPremierePasse[1];
786  TableauDePointsPremierePasse[1] = pRecepteur;
787 
788  // Sens de parcours S->R
789  int indexS = 0;
790  int indexR = 1;
791  bool bSaGaucheDeR = TableauDePointsPremierePasse[indexS]->x < TableauDePointsPremierePasse[indexR]->x;
792 
793  if (bTrajetsAGaucheDeSR)
794  {
795  if (bSaGaucheDeR)
796  {
798  TableauDePointsPremierePasse, nNbPointsPremierePasse, TableauDePointsEC, false);
799  }
800  else
801  {
803  TableauDePointsPremierePasse, nNbPointsPremierePasse, TableauDePointsEC, true);
804  }
805  }
806  else
807  {
808  if (bSaGaucheDeR)
809  {
811  TableauDePointsPremierePasse, nNbPointsPremierePasse, TableauDePointsEC, true);
812  }
813  else
814  {
816  TableauDePointsPremierePasse, nNbPointsPremierePasse, TableauDePointsEC, false);
817  }
818  }
819  SAFE_DELETE_LIST(TableauDePointsPremierePasse);
820 
821  // 2. Parcours de l'EC, et choix du trajet sans intersection
822  // 2.1. Allouer de la memoire pour les points du trajet
823  int nNbPointAlloue = nNbPointsEC * nNbPointsPremierePasse;
824  geoSecondePasse._ListePolylines = new TYPolyligneParcours[1]; // 1 seule polyligne
825  geoSecondePasse._ListePolylines[0].allouer(nNbPointAlloue); // allouer assez de points!
826  geoSecondePasse._ListePoint = new TYPointParcours[nNbPointAlloue];
827  geoSecondePasse._nNbPointTotal = 0;
828  geoSecondePasse._nNbPolylines = 1;
829  // 2.2. Ajouter les points de S vers R
830  // Les points doivent etre ordonnes de S vers R
831  bool bOrdonneDeSversR =
832  (TableauDePointsEC[0]->Identifiant == geoPremierePasse._ListePolylines[0].indexePoint(0));
833  if (!bOrdonneDeSversR)
834  {
835  InverseOrdreDesPoints(TableauDePointsEC, nNbPointsEC);
836  }
837  geoSecondePasse.AjoutePointALaPolyLigne(0, *TableauDePointsEC[0]);
838  int nVerifNbPointsAjoutes = 1;
839  for (i = 1; i < nNbPointsEC; i++)
840  {
841  if (this->intersects(*TableauDePointsEC[i - 1], *TableauDePointsEC[i]))
842  {
843  // Il y a un obstacle sur cette portion d'enveloppe convexe;
844  // contournons-le en prenant l'itineraire de la premiere passe:
845  // xbh: S'il y a un obstacle entre deux points successifs de l'enveloppe convexe, on insere entre
846  // les deux un contournement de l'obstacle calcule a la premier passe.
847  nVerifNbPointsAjoutes += geoSecondePasse.AjouteLesPointsComprisEntre(
848  geoPremierePasse, 0, TableauDePointsEC[i - 1]->Identifiant,
849  TableauDePointsEC[i]->Identifiant);
850  }
851  else
852  {
853  geoSecondePasse.AjoutePointALaPolyLigne(0, *TableauDePointsEC[i]);
854  nVerifNbPointsAjoutes++;
855  }
856  }
857 
858  pTableauEC = TableauDePointsEC;
859  nbPtsEC = nNbPointsEC;
860  // xbh: do not delete here as long as we returned the pointer outside this function
861  // delete [] TableauDePointsEC;
862  return true;
863 }
864 
866  int nNbPointsDeLaListe)
867 {
868  for (int i = 0; i < nNbPointsDeLaListe / 2; i++)
869  {
870  TYPointParcours* pTmp = ListeDePointsAInverser[nNbPointsDeLaListe - 1 - i];
871  ListeDePointsAInverser[nNbPointsDeLaListe - 1 - i] = ListeDePointsAInverser[i];
872  ListeDePointsAInverser[i] = pTmp;
873  }
874 }
875 
877  int nIndexePoly, int nIndexeNbPremierPointAAjouter,
878  int nIndexeDernierPointAAjouter)
879 {
880  int nNbPointsAjoutes = 0;
881  // 1 Parcourir la polyligne source jusqu'a se positionner sur le premier point
882  TYPolyligneParcours* PolyligneSource = &(geoPolySource._ListePolylines[nIndexePoly]);
883 
884  int i = 0;
885  for (i = 0; i < PolyligneSource->nombreDePoint() &&
886  PolyligneSource->indexePoint(i) != nIndexeNbPremierPointAAjouter;
887  i++)
888  {
889  ;
890  }
891  for (i = i + 1; i < PolyligneSource->nombreDePoint(); i++)
892  {
893  TYPointParcours aTYPointParcours = PolyligneSource->point(i);
894  AjoutePointALaPolyLigne(0, aTYPointParcours);
895  nNbPointsAjoutes++;
896  if (PolyligneSource->indexePoint(i) == nIndexeDernierPointAAjouter)
897  {
898  break;
899  }
900  }
901  return nNbPointsAjoutes;
902 }
903 
905 {
906  // On regarde les intersections avec tous les segments du set
907  TYPointParcours P;
908  int indexPoint1In = P1.Identifiant;
909  int indexPoint2In = P2.Identifiant;
910  for (int i = 0; i < _nNbPolylines; i++)
911  {
912  assert(_ListePolylines[i].nombreDePoint() == 2);
913  int indexPoint1 = _ListePolylines[i].indexePoint1();
914  int indexPoint2 = _ListePolylines[i].indexePoint2();
915 
916  // les 2 segments ont ils au moins un point en commun ?
917  bool bMemePoint1 = (indexPoint1 == indexPoint1In) || (indexPoint1 == indexPoint2In);
918  bool bMemePoint2 = (indexPoint2 == indexPoint2In) || (indexPoint2 == indexPoint1In);
919  bool bMemePoints = bMemePoint1 || bMemePoint2;
920 
921  if (!bMemePoints)
922  {
923  // Non => on peut faire le test
924  TYPointParcours& P3 = _ListePoint[indexPoint1];
925  TYPointParcours& P4 = _ListePoint[indexPoint2];
926  if (TYPointParcours::IntersectionSegments(P1, P2, P3, P4, P))
927  // if(TYPointParcours::IntersectionSegments(P1, P2, _ListePoint[indexPoint1],
928  // _ListePoint[indexPoint2], P))
929  {
930  return true;
931  }
932  }
933  }
934  return false;
935 }
936 
937 // indexePointADroite=>indexePointDuBonCote
938 // test du bon cote : a gauche => det >0 a droite det < 0
939 // texte de debug : en dessous <-> au dessus
941 {
942  determinant = TYPointParcours::ZCross(V1, V2);
943  return (determinant < 0);
944 }
945 
947 {
948  determinant = TYPointParcours::ZCross(V1, V2);
949  return (determinant > 0);
950 }
951 
953  int nNbPoints,
954  TYPointParcours** TableauDePointsECOut,
955  bool bPremiersPointsLesPlusHauts)
956 {
957  bool (*pDuBonCote)(TYPointParcours & V1, TYPointParcours & V2, double& determinant);
958  pDuBonCote =
959  bPremiersPointsLesPlusHauts ? &SecondVecteurADroiteDuPremier : &SecondVecteurAGaucheDuPremier;
960 
961  int nNbPointsEC = 0;
962  // On teste chaque point pour voir s'il est a gauche de SP courant (en fait, si l'angle est inferieur a
963  // PI) Le calcul d'enveloppe convexe suppose que les 2 premiers points sont sur l'EC, et qu'ils sont les
964  // plus bas Si le premier n'est pas le plus a gauche, on swap avec le second
965  bool bSaGaucheDeR = TableauDePoints[0]->x < TableauDePoints[1]->x;
966  int indexS = bSaGaucheDeR ? 0 : 1;
967  int indexR = bSaGaucheDeR ? 1 : 0;
968 
969  // Vecteur SR:
970  TYPointParcours S = *(TableauDePoints[indexS]);
971  TYPointParcours R = *(TableauDePoints[indexR]);
972 
973  // S est le premier point de l'EC:
974  TableauDePointsECOut[nNbPointsEC] = TableauDePoints[indexS];
975 
976  nNbPointsEC++;
977 
978  TYPointParcours P = S;
979  TYPointParcours P1 = R;
980 
981  int i = 0;
982  TYPointParcours P2;
983  TYPointParcours PP1;
984  TYPointParcours PP2;
985  int indexePointDuBonCote = -1;
986  do
987  {
988  // On calcule PP1
989  PP1 = TYPointParcours::vecteur2D(P, P1);
990 
991  // Cherchons le point le plus a gauche de PP1
992  indexePointDuBonCote = -1; // on ne l'a pas encore trouve
993  for (i = 2; i < nNbPoints; i++)
994  {
995  P2 = (*TableauDePoints[i]);
996  PP2 = TYPointParcours::vecteur2D(P, P2);
997  // Ne pas tester le meme point
998  if (P1.Identifiant != P2.Identifiant)
999  {
1000  double determinant = NAN; // = TYPointParcours::ZCross(PP1, PP2);
1001  bool bDuBonCote = (*pDuBonCote)(PP1, PP2, determinant);
1002  // Attention ! Lorsque les vecteurs sont colineaires, le determinant peut etre non nul mais
1003  // tres proche de 0.
1004  //=> seuil epsilon pour le determinant
1005  // static const double epsilonDeterminant = 1E-10;
1006  bool bColineraires = (fabs(determinant) < SEUIL_DETERMNANT_COLINEAIRE);
1007  bool bBonCandidatPourRemplacement = false;
1008  if (bColineraires)
1009  {
1010  // Verifions que P2 est du meme ci��te que P1
1011  if (TYPointParcours::Scalaire(PP1, PP2) <
1012  0) // xbh: A koi sert ce test si les vecteurs sont colineaires ???
1013  {
1014  bBonCandidatPourRemplacement = false;
1015  }
1016  else
1017  {
1018  bBonCandidatPourRemplacement = PP2.normeCarree() > PP1.normeCarree();
1019  }
1020  }
1021  else
1022  {
1023  bBonCandidatPourRemplacement = bDuBonCote;
1024  }
1025  if (bBonCandidatPourRemplacement)
1026  {
1027  // P2 a gauche de P1 => on remplace P1 par P2
1028  P1 = P2;
1029  indexePointDuBonCote = i;
1030  // On recalcule PP1
1031  PP1 = TYPointParcours::vecteur2D(P, P1);
1032  }
1033  }
1034  }
1035  TYPointParcours* pNouveauPointEC = NULL;
1036  if (indexePointDuBonCote >= 0)
1037  {
1038  // On a trouve un point plus a gauche
1039  pNouveauPointEC = TableauDePoints[indexePointDuBonCote];
1040  // Cherchons le point suivant de l'EC
1041  P = P1;
1042  P1 = R;
1043  }
1044  else
1045  {
1046  // le dernier point de l'EC est R:
1047  pNouveauPointEC = TableauDePoints[indexR];
1048  }
1049  // Ajoutons-le a EC
1050  TableauDePointsECOut[nNbPointsEC] = pNouveauPointEC;
1051  nNbPointsEC++;
1052  } while (nNbPointsEC < nNbPoints && indexePointDuBonCote >= 0);
1053 
1054  return nNbPointsEC;
1055 }
1056 
1058  TYPointParcours** TableauDePoints,
1059  int nNbPoints)
1060 {
1061  if (NULL == TableauDePoints || 0 == nNbPoints)
1062  {
1063  return 0;
1064  }
1065  int nNbPointsSelectiones = 2;
1066 
1067  // on ajoute les points S & R en premier:
1068  // ajout de S
1069  TableauDePoints[0] = geoSR->_ListePolylines[0].pointPtr(0);
1070 
1071  // ajout de R
1072  TableauDePoints[1] = geoSR->_ListePolylines[0].pointPtr(1);
1073 
1074  // Limites en X: quel est le point le plus a gauche entre S & R ?
1075  bool bSaGaucheDeR = TableauDePoints[0]->x < TableauDePoints[1]->x;
1076  TYPointParcours G, D;
1077  if (bSaGaucheDeR)
1078  {
1079  G = *TableauDePoints[0];
1080  D = *TableauDePoints[1];
1081  }
1082  else
1083  {
1084  G = *TableauDePoints[1];
1085  D = *TableauDePoints[0];
1086  }
1087  // Vecteur GD (Point limite Gauche & Point limite Droit)
1089 
1090  int i = 0;
1091  TYPointParcours *p1 = nullptr, *p2 = nullptr;
1092  TYPointParcours p;
1093  int nbPts = 0;
1094 
1095  // 1. GD intersecte une des polylignes...
1096  bool noIntersection = true;
1097  for (i = 0; (i < _nNbPolylines) && (noIntersection); i++)
1098  {
1099  nbPts = _ListePolylines[i].nombreDePoint();
1100  for (int j = 0; (j < nbPts - 1) && (noIntersection); j++)
1101  {
1102  p1 = _ListePolylines[i].pointPtr(j);
1103  p2 = _ListePolylines[i].pointPtr(j + 1);
1104 
1105  if (TYPointParcours::IntersectionSegments(G, D, *p1, *p2, p))
1106  {
1107  noIntersection = false;
1108  }
1109  }
1110  }
1111 
1112  // Si on n'a trouve aucune intersection, il existe un trajet direct.
1113  if (noIntersection)
1114  {
1115  return nNbPointsSelectiones;
1116  }
1117 
1118  // 2. On selectionne les points interessants...
1119  // MinMax en largeur
1120  double MaxX = D.x;
1121  double MinX = G.x;
1122 
1123  // Comme le merge des points doubles a consistes a marquer en negatifs les points inutiles, on les ecartes
1124  int racine = 0;
1125  bool bEntreSetR = false;
1126  TYPointParcours GP;
1127 
1128  for (i = 0; i < nNbPoints; i++)
1129  {
1130  // Est-ce un doublon ?
1131  int nIdentifiantRacine = _ListePoint[racine].Identifiant;
1132  while (i != 0 && i < nNbPoints && _ListePoint[i].Identifiant <= nIdentifiantRacine)
1133  {
1134  i++;
1135  }
1136  if (i >= nNbPoints)
1137  {
1138  break;
1139  }
1140  racine = i;
1141 
1142  bEntreSetR = (_ListePoint[i].x >= MinX && _ListePoint[i].x <= MaxX);
1143 
1144  // A gauche ?
1146  if (bEntreSetR && (TYPointParcours::ZCross(GD, GP) >= 0))
1147  {
1148  TableauDePoints[nNbPointsSelectiones] = &(_ListePoint[i]);
1149  nNbPointsSelectiones++;
1150  }
1151  }
1152 
1153  return nNbPointsSelectiones;
1154 }
1155 
1157  int nNbPoints, bool bSens,
1158  bool bGardeIdentifiant)
1159 {
1160  if (NULL == TableauDePoints || 0 == nNbPoints)
1161  {
1162  return;
1163  }
1164  assert(_ListePolylines == NULL);
1165  assert(_ListePoint == NULL);
1166  assert(_nNbPolylines == 0);
1167  assert(_nNbPointTotal == 0);
1168 
1169  // 1. Creer les points
1170  _ListePoint = new TYPointParcours[nNbPoints];
1171  _nNbPointTotal = nNbPoints;
1172 
1173  // 2. Creer la polyligne
1175  _nNbPolylines = 1;
1176  _ListePolylines[0].allouer(nNbPoints);
1177 
1178  // Copie des points
1179  int i = 0;
1180  if (bSens)
1181  {
1182  for (i = 0; i < nNbPoints; i++)
1183  {
1184  _ListePoint[i] = *TableauDePoints[i];
1186  }
1187  if (!bGardeIdentifiant) // a l'exterieur, on ne fait qu'un seul test...
1188  {
1189  for (i = 0; i < nNbPoints; i++)
1190  {
1191  _ListePoint[i].Identifiant = i;
1192  }
1193  }
1194  }
1195  else
1196  {
1197  for (i = 0; i < nNbPoints; i++)
1198  {
1199  _ListePoint[i] = *TableauDePoints[nNbPoints - i - 1];
1200  _ListePolylines[0].ajoutePoint(i, &(_ListePoint[nNbPoints - i - 1]));
1201  }
1202  if (!bGardeIdentifiant)
1203  {
1204  for (i = 0; i < nNbPoints; i++)
1205  {
1206  _ListePoint[i].Identifiant = nNbPoints - i - 1;
1207  }
1208  }
1209  }
1210 }
1211 
1213  TYPointParcours* c)
1214 {
1215  OVector3D v1(b->x - a->x, b->y - a->y, 0.0f);
1216  OVector3D v2(c->x - b->x, c->y - b->y, 0.0f);
1217  TYPointParcours *p = nullptr, *pp = nullptr, *pn = nullptr;
1218  int nbPts = 0;
1219  double norme1 = NAN;
1220  double norme2 = NAN;
1221  double cosVal1 = NAN;
1222  double cosVal2 = NAN;
1223 
1224  bool t1 = false, t2 = false;
1225  t1 = t2 = false;
1226 
1227  // 1. on regarde si b appartienne a une polyligne
1228  for (int i = 0; i < _nNbPolylines; i++)
1229  {
1230  nbPts = _ListePolylines[i].nombreDePoint();
1231  for (int j = 0; j < nbPts; j++)
1232  {
1233  p = _ListePolylines[i].pointPtr(j);
1234 
1235  if (TYPointParcours::Confondus(p, b))
1236  {
1237  // On regarde si les vecteurs ab et bc sont colineaires aux segments prec et suiv
1238  // de la polyligne
1239 
1240  if (j > 0)
1241  {
1242  pp = _ListePolylines[i].pointPtr(j - 1);
1243  OVector3D v3(p->x - pp->x, p->y - pp->y, 0.0f);
1244 
1245  norme1 = (v1.norme() * v3.norme());
1246  cosVal1 = v1.scalar(v3) / norme1; // should be > 0
1247  if (ABS(cosVal1 - 1.0f) < EPSILON_13)
1248  {
1249  t1 = true;
1250  }
1251 
1252  v3._x = -v3._x;
1253  v3._y = -v3._y;
1254 
1255  norme2 = (v2.norme() * v3.norme());
1256  cosVal2 = v2.scalar(v3) / norme2; // should be > 0
1257  if (ABS(cosVal2 - 1.0f) < EPSILON_13)
1258  {
1259  t2 = true;
1260  }
1261  }
1262  if (j < nbPts - 1)
1263  {
1264  pn = _ListePolylines[i].pointPtr(j + 1);
1265  OVector3D v4(pn->x - p->x, pn->y - p->y, 0.0f);
1266 
1267  norme2 = (v2.norme() * v4.norme());
1268  cosVal2 = v2.scalar(v4) / norme2; // should be > 0
1269  if (ABS(cosVal2 - 1.0f) < EPSILON_13)
1270  {
1271  t2 = true;
1272  }
1273 
1274  v4._x = -v4._x;
1275  v4._y = -v4._y;
1276 
1277  norme1 = (v1.norme() * v4.norme());
1278  cosVal1 = v1.scalar(v4) / norme1; // should be > 0
1279  if (ABS(cosVal1 - 1.0f) < EPSILON_13)
1280  {
1281  t1 = true;
1282  }
1283  }
1284  }
1285  }
1286 
1287  if (t1 && t2)
1288  {
1289  break;
1290  }
1291  }
1292 
1293  return (t1 && t2);
1294 }
All base classes related to 3D manipulation.
#define EPSILON_13
Definition: 3d.h:41
double ABS(double a)
Return the absolute value.
Definition: 3d.h:67
NxReal c
Definition: NxVec3.cpp:317
#define SEUIL_DETERMNANT_COLINEAIRE
of two vectors
The 3D vector class.
Definition: 3d.h:298
Polylines path class used by the TYSetGeometriqueParcours class.
void ajoutePoint(int indexe, TYPointParcours *p)
Add a point.
TYPointParcours point(int indexe)
Return a copy the point Pi.
TYPolyligneParcours * _PolyligneP1
Pointer to the next polyline (from P1 point)
bool allouer(int nNbPoint)
Allocate nNbPoint points to the polyline.
int indexePoint2()
Return point id of point P1.
int indexePoint1()
Return point id of point P0.
void setPoint(int indexe, TYPointParcours *p)
Change a point.
int indexePointSuivant(int IndexPoint, TYPolyligneParcours *&PolyligneSuivante)
Return the point id of the next point given by IndexPoint id.
int nombreDePoint()
Return the number of points.
TYPointParcours * pointPtr(int indexe)
Return a pointer on the point Pi.
bool isEcran()
Return true if P0 and P1 are Ecran.
TYPolyligneParcours * _PolyligneP0
Pointer to the previous polyline (from P0 point)
void Copy(TYPolyligneParcours &p)
Copy operator.
int indexePoint(int i)
Return point id of point i of the polyline.
Class to build a geometric path used by the TYCalculParcours class.
void MarquePointsADroiteEtAGauche(TYPointParcours &Srce, TYPointParcours &Dest, bool *&PointsAGauche, bool *&PointsADroite)
Mark points on the left and on the right of the current geometric path.
int ParcourtPolyligneAPartirDe(int IndexPointRacine, TYPolyligneParcours *&PolyligneRacine, std::vector< bool > &pEstUnPointIntersectant, TYSetGeometriqueParcours &geoPremierePasse)
To be commented.
bool intersects(TYPointParcours &P1, TYPointParcours &P2)
Check if [P1P2] segment can intersect the geometric path.
bool SecondePasse(TYSetGeometriqueParcours &geoPremierePasse, TYSetGeometriqueParcours &geoSecondePasse, bool bTrajetsAGaucheDeSR, TYPointParcours **&pTableauEC, int &nbPtsEC, int compteurIter=0, bool bIsLastSecondePasse=false)
Second pass.
bool polyligneContientSouR(int i)
Returns true if polyligne of index i contains Source or Receptor.
void RamenerPointsTraversantLaFrontiere(TYPointParcours &Srce, TYPointParcours &Dest, int *IndexePointsFrontiere, int &NbPointsFrontiere, std::vector< bool > &pEstUnPointIntersectant, bool bCoteGauche, bool *PointsAGauche, bool *PointsADroite)
To be commented.
void SwapPolyligne(int i, int j)
Swap polylines i and j.
static int EnveloppeConvexeLes2PremiersPointsEtant(TYPointParcours **TableauDePoints, int nNbPoints, TYPointParcours **TableauDePointsECOut, bool bPremiersPointsLesPlusHauts)
Compute the convex hull (arrays should be allocated before the call)
int SupressionPolylignesRedondantes()
Suppress useless polylines.
TYPolyligneParcours * _ListePolylines
Geometric path as a polylines.
void TriePointsIntersectionSuivantSR(TYPointParcours &Srce, TYPointParcours &Dest, int *IndexePointsFrontiere, int NbPointsFrontiere)
To be commented.
static TYPointParcours * _DestQSort
static access to the C function of quicksort
int SelectionnePointsEntreSetRetDuCoteDeSR(TYSetGeometriqueParcours *geoSR, TYPointParcours **TableauDePoints, int nNbPoints)
Select points from the current geometric path which are between source and receptor of the geoSR geom...
bool PolylignesInfraFermees()
Return true if all polylines from infrastructure are closed.
void CreerTrajetAPartirDuneListeDePointsTriee(TYPointParcours **TableauDePoints, int nNbPoints, bool bSens, bool bGardeIdentifiant)
Create paths from a sorted points list (Used only for vertical paths)
static TYPointParcours * _SrceQSort
static access to the C function of quicksort
void SeparationDroiteGauche(bool *PointsAGauche, bool *PointsADroite, TYSetGeometriqueParcours &geoGauche, TYSetGeometriqueParcours &geoDroite, int compteurIter=0)
Separate left and right polylines with two geometric paths.
static void InverseOrdreDesPoints(TYPointParcours **ListeDePointsAInverser, int nNbPointsDeLaListe)
Invert a list of points.
int _nNbPolylines
Polylines number.
TYPointParcours * _ListePoint
List of points on the path.
void Copy(TYSetGeometriqueParcours &geoIn)
Copy operator.
int _nNbPointTotal
Total number of points.
static TYPointParcours * _ListePointQSort
static access to the C function of quicksort
bool AjoutePointALaPolyLigne(int indexPolyligne, TYPointParcours &P)
Add a point P to the polyline indexPolyligne.
void AllouerPolylignes(int nNbPolylineAllouee)
Allocation of the polylines list.
bool PremierePasse(TYPointParcours &Srce, TYPointParcours &Dest, int *IndexePointsFrontiere, int NbPointsFrontiere, std::vector< bool > &pEstUnPointIntersectant, Connexite *Connexes, TYSetGeometriqueParcours &geoPremierePasse, int compteurIter=0)
First pass to build a path along all the intersecting polylines.
bool ListerPointsConnexes(Connexite *&Connexes, std::vector< bool > &pEstUnPointIntersectant)
Fill for each point the connectivity with segments.
int MergePointsDoubles()
Detect and fix double points.
bool AppartienneMemePolyligne(TYPointParcours *a, TYPointParcours *b, TYPointParcours *c)
Check if the points a, b, c belong to the same polyline.
int AjouteLesPointsComprisEntre(TYSetGeometriqueParcours &geoPolySource, int nIndexePoly, int nIndexeNbPremierPointAAjouter, int nIndexeDernierPointAAjouter)
Add some points of the nIndexePoly polyline from the geoPolySource geometric path.
int compareTYPolyligneParcours(const void *p1, const void *p2)
bool SecondVecteurAGaucheDuPremier(TYPointParcours &V1, TYPointParcours &V2, double &determinant)
bool SecondVecteurADroiteDuPremier(TYPointParcours &V1, TYPointParcours &V2, double &determinant)
int compareAbscissesCurvilignes(const void *p1, const void *p2)
#define SAFE_DELETE_LIST(_p)
Definition: macros.h:239
Connectivity between points and segments.
int IndexesSegment[2]
Two indexes of the segment.
int NbSegmentsConnexes
Related segments number.
Point of a path.
double z
z coordinate of the point
bool isInfra
Flag set to indicate if the point is an infrastructure.
int Identifiant
Point id.
static bool Confondus(TYPointParcours *P1, TYPointParcours *P2)
static bool IntersectionSegments(TYPointParcours &P1, TYPointParcours &P2, TYPointParcours &P3, TYPointParcours &P4, TYPointParcours &P, bool bP3OrP4MustNotCoincideWithP=false)
Return true if [P1P2] intersects [P3P4] if P1 or P2 coincide with the intersection point P,...
static double ZCross(TYPointParcours SR, TYPointParcours SP)
Return cross product applied to SR and SP points.
double y
y coordinate of the point
static double Scalaire(TYPointParcours &P1, TYPointParcours &P2, TYPointParcours &P3, TYPointParcours &P4)
Compute the scalar product of the vector P1P2 and P3P4.
double x
x coordinate of the point
bool isEcran
Flag set to indicate if the point is a screen.
static bool IntersectionDroites(TYPointParcours &P1, TYPointParcours &P2, TYPointParcours &P3, TYPointParcours &P4, TYPointParcours &P)
static double AbscisseCurviligneCarreSurSR(TYPointParcours &P, TYPointParcours &S, TYPointParcours &R)
Return the square of the curvilinear abscissa of point P on [SR].
static TYPointParcours vecteur2D(TYPointParcours &P1, TYPointParcours &P2)
Compute the 2 dimensional vector P1P2 in the XY plane.