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