geodesique.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775
  1. /*************************************/
  2. /* Auteur : Rémi Synave */
  3. /* Date de création : 25/01/08 */
  4. /* Date de modification : 15/03/15 */
  5. /* Version : 0.4 */
  6. /*************************************/
  7. /***************************************************************************/
  8. /* This file is part of a2ri. */
  9. /* */
  10. /* a2ri is free software: you can redistribute it and/or modify it */
  11. /* under the terms of the GNU Lesser General Public License as published */
  12. /* by the Free Software Foundation, either version 3 of the License, or */
  13. /* (at your option) any later version. */
  14. /* */
  15. /* a2ri is distributed in the hope that it will be useful, */
  16. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  17. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  18. /* GNU Lesser General Public License for more details. */
  19. /* */
  20. /* You should have received a copy of the GNU Lesser General Public */
  21. /* License along with a2ri. */
  22. /* If not, see <http://www.gnu.org/licenses/>. */
  23. /***************************************************************************/
  24. #include "geodesique.h"
  25. /********** INTERMEDIATE TYPES AND FUNCTIONS **********/
  26. /* Les fonctions intermédiaires sont préfixées de IF */
  27. /* et les types intermédiaires de IT */
  28. void
  29. IF_plan_lms_contraint_moyenne (
  30. point3d A,
  31. point3d B,
  32. point3d * listept,
  33. int size,
  34. point3d * C)
  35. {
  36. // calcul des trois points du plan moyen
  37. // le premier et le deuxieme sont connus : points de depart et d'arrivée
  38. point3d_init (C, 0, 0, 0);
  39. A.x = A.x;
  40. B.x = B.x;
  41. for (int i = 0; i < size; i++)
  42. {
  43. C->x += listept[i].x;
  44. C->y += listept[i].y;
  45. C->z += listept[i].z;
  46. }
  47. C->x /= (size * 1.0);
  48. C->y /= (size * 1.0);
  49. C->z /= (size * 1.0);
  50. }
  51. void
  52. IF_plan_lms_contraint_v1 (
  53. point3d A,
  54. point3d B,
  55. point3d * listept,
  56. int size,
  57. point3d * C)
  58. {
  59. // calcul des trois points du plan moyen
  60. // le premier et le deuxieme sont connus : points de depart et d'arrivée
  61. point3d_init (C, 0, 0, 0);
  62. point3d p1,
  63. p2;
  64. point3d_init (&p1, listept[0].x, listept[0].y, listept[0].z);
  65. point3d_init (&p2, listept[1].x, listept[1].y, listept[1].z);
  66. double min = distance_point_plane (&p2, &A, &B, &p1),
  67. max = distance_point_plane (&p2, &A, &B, &p1);
  68. int indexmin = 0,
  69. indexmax = 0;
  70. for (int i = 0; i < size; i++)
  71. {
  72. //à chaque tour de boucle, on selectionne un point dans la liste des points comme troisieme point du plan
  73. //on regarde les distances mini et maxi
  74. point3d_init (&p1, listept[i].x, listept[i].y, listept[i].z);
  75. for (int j = 0; j < size; j++)
  76. {
  77. if (i != j)
  78. {
  79. point3d_init (&p2, listept[j].x, listept[j].y, listept[j].z);
  80. if (min > distance_point_plane (&p2, &A, &B, &p1))
  81. {
  82. min = distance_point_plane (&p2, &A, &B, &p1);
  83. indexmin = j;
  84. }
  85. if (max < distance_point_plane (&p2, &A, &B, &p1))
  86. {
  87. max = distance_point_plane (&p2, &A, &B, &p1);
  88. indexmax = j;
  89. }
  90. }
  91. }
  92. }
  93. point3d_init (C,
  94. (listept[indexmin].x + listept[indexmax].x) / 2.0,
  95. (listept[indexmin].y + listept[indexmax].y) / 2.0,
  96. (listept[indexmin].z + listept[indexmax].z) / 2.0);
  97. }
  98. void
  99. IF_plan_lms_contraint_min_max (
  100. point3d A,
  101. point3d B,
  102. point3d * listept,
  103. int size,
  104. point3d * C)
  105. {
  106. double distancedroite = 0,
  107. distancegauche = 0;
  108. double a,
  109. b,
  110. c,
  111. d,
  112. calcul;
  113. point3d tableau[3];
  114. int indexdroite = -1,
  115. indexgauche = -1;
  116. point3d_init (&(tableau[0]), A.x, A.y, A.z);
  117. point3d_init (&(tableau[1]), B.x, B.y, B.z);
  118. for (int i = 0; i < size; i++)
  119. {
  120. point3d_init (&(tableau[2]), listept[i].x, listept[i].y, listept[i].z);
  121. equation_plan (tableau, 3, &a, &b, &c, &d);
  122. for (int j = 0; j < size; j++)
  123. {
  124. if (i != j)
  125. {
  126. calcul =
  127. a * listept[j].x + b * listept[j].y + c * listept[j].z + d;
  128. if (calcul < 0)
  129. {
  130. if (calcul < distancegauche)
  131. {
  132. indexgauche = i;
  133. distancegauche = calcul;
  134. }
  135. }
  136. else
  137. {
  138. if (calcul > distancedroite)
  139. {
  140. indexdroite = i;
  141. distancedroite = calcul;
  142. }
  143. }
  144. }
  145. }
  146. }
  147. point3d_init (C, (listept[indexdroite].x + listept[indexgauche].x) / 2.0,
  148. (listept[indexdroite].y + listept[indexgauche].y) / 2.0,
  149. (listept[indexdroite].z + listept[indexgauche].z) / 2.0);
  150. }
  151. void
  152. IF_plan_lms_contraint_vecteur (
  153. vf_model * m,
  154. point3d A,
  155. int *listept,
  156. int size,
  157. point3d * C)
  158. {
  159. vector3d moyenne,
  160. normale_sommet;
  161. hashtable *table = a2ri_vf_construction_edge_table (m, NULL, 0);
  162. vector3d_init (&moyenne, 0.0, 0.0, 0.0);
  163. for (int i = 0; i < size; i++)
  164. {
  165. normale_sommet =
  166. a2ri_vf_normal_vertex_with_hashtable (m, listept[i], table);
  167. moyenne = vector3d_add (&moyenne, &normale_sommet);
  168. }
  169. vector3d_normalize (&moyenne);
  170. point3d_init (C, A.x + moyenne.dx, A.y + moyenne.dy, A.z + moyenne.dz);
  171. hashtable_free (table);
  172. free (table);
  173. }
  174. void
  175. IF_plan_lms_contraint_intersection (
  176. point3d A,
  177. point3d B,
  178. point3d * listept,
  179. int size,
  180. point3d * C)
  181. {
  182. double distancedroite = 0,
  183. distancegauche = 0;
  184. double a,
  185. b,
  186. c,
  187. d;
  188. int nbintersection = 0,
  189. nbintersectionmax = -1;
  190. point3d tableau[3];
  191. point3d_init (&(tableau[0]), A.x, A.y, A.z);
  192. point3d_init (&(tableau[1]), B.x, B.y, B.z);
  193. for (int i = 0; i < size; i++)
  194. {
  195. point3d_init (&(tableau[2]), listept[i].x, listept[i].y, listept[i].z);
  196. equation_plan (tableau, 3, &a, &b, &c, &d);
  197. nbintersection = 0;
  198. for (int j = 0; j < size - 1; j++)
  199. {
  200. distancegauche =
  201. a * listept[j].x + b * listept[j].y + c * listept[j].z + d;
  202. distancedroite =
  203. a * listept[j + 1].x + b * listept[j + 1].y + c * listept[j +
  204. 1].z +
  205. d;
  206. if (distancedroite * distancegauche < 0)
  207. nbintersection++;
  208. }
  209. if (nbintersection > nbintersectionmax)
  210. {
  211. nbintersectionmax = nbintersection;
  212. point3d_init (C, listept[i].x, listept[i].y, listept[i].z);
  213. }
  214. }
  215. }
  216. void
  217. IFcalcul_plan_moyenne (
  218. vf_model * m,
  219. int numvedep,
  220. int numvefin,
  221. int *listve,
  222. int sizelistve,
  223. point3d * A,
  224. point3d * B,
  225. point3d * C)
  226. {
  227. point3d *listept = NULL;
  228. int sizelistept;
  229. point3d_init (A, m->ve[numvedep].x, m->ve[numvedep].y, m->ve[numvedep].z);
  230. point3d_init (B, m->ve[numvefin].x, m->ve[numvefin].y, m->ve[numvefin].z);
  231. listept = (point3d *) malloc (sizelistve * sizeof (point3d));
  232. a2ri_erreur_critique_si (listept == NULL,
  233. "erreur allocation memoire pour listept\nIFcalcul_plan_moyenne");
  234. for (int i = 0; i < sizelistve; i++)
  235. point3d_init (&(listept[i]),
  236. m->ve[listve[i]].x, m->ve[listve[i]].y, m->ve[listve[i]].z);
  237. sizelistept = sizelistve;
  238. IF_plan_lms_contraint_moyenne (*A, *B, listept, sizelistept, C);
  239. free (listept);
  240. }
  241. void
  242. IFcalcul_plan_min_max (
  243. vf_model * m,
  244. int numvedep,
  245. int numvefin,
  246. int *listve,
  247. int sizelistve,
  248. point3d * A,
  249. point3d * B,
  250. point3d * C)
  251. {
  252. point3d *listept = NULL;
  253. int sizelistept;
  254. point3d_init (A, m->ve[numvedep].x, m->ve[numvedep].y, m->ve[numvedep].z);
  255. point3d_init (B, m->ve[numvefin].x, m->ve[numvefin].y, m->ve[numvefin].z);
  256. listept = (point3d *) malloc (sizelistve * sizeof (point3d));
  257. a2ri_erreur_critique_si (listept == NULL,
  258. "erreur allocation memoire pour listept\nIFcalcul_plan_min_max");
  259. for (int i = 0; i < sizelistve; i++)
  260. point3d_init (&(listept[i]),
  261. m->ve[listve[i]].x, m->ve[listve[i]].y, m->ve[listve[i]].z);
  262. sizelistept = sizelistve;
  263. IF_plan_lms_contraint_min_max (*A, *B, listept, sizelistept, C);
  264. free (listept);
  265. }
  266. void
  267. IFcalcul_plan_vecteur (
  268. vf_model * m,
  269. int numvedep,
  270. int numvefin,
  271. int *listve,
  272. int sizelistve,
  273. point3d * A,
  274. point3d * B,
  275. point3d * C)
  276. {
  277. point3d_init (A, m->ve[numvedep].x, m->ve[numvedep].y, m->ve[numvedep].z);
  278. point3d_init (B, m->ve[numvefin].x, m->ve[numvefin].y, m->ve[numvefin].z);
  279. IF_plan_lms_contraint_vecteur (m, *A, listve, sizelistve, C);
  280. }
  281. void
  282. IFcalcul_plan_intersection (
  283. vf_model * m,
  284. int numvedep,
  285. int numvefin,
  286. int *listve,
  287. int sizelistve,
  288. point3d * A,
  289. point3d * B,
  290. point3d * C)
  291. {
  292. point3d *listept = NULL;
  293. int sizelistept;
  294. point3d_init (A, m->ve[numvedep].x, m->ve[numvedep].y, m->ve[numvedep].z);
  295. point3d_init (B, m->ve[numvefin].x, m->ve[numvefin].y, m->ve[numvefin].z);
  296. listept = (point3d *) malloc (sizelistve * sizeof (point3d));
  297. a2ri_erreur_critique_si (listept == NULL,
  298. "erreur allocation memoire pour listept\nIFcalcul_plan_min_max");
  299. for (int i = 0; i < sizelistve; i++)
  300. point3d_init (&(listept[i]),
  301. m->ve[listve[i]].x, m->ve[listve[i]].y, m->ve[listve[i]].z);
  302. sizelistept = sizelistve;
  303. IF_plan_lms_contraint_intersection (*A, *B, listept, sizelistept, C);
  304. free (listept);
  305. }
  306. double
  307. construction_chemin_lineaire_intermediaire (
  308. vf_model * m,
  309. int ve_dep,
  310. int ve_fin,
  311. point3d A,
  312. point3d B,
  313. point3d C,
  314. int v1,
  315. int v2,
  316. int **list,
  317. int *size)
  318. {
  319. double aplan,
  320. bplan,
  321. cplan,
  322. dplan,
  323. longueurtemp;
  324. point3d arete1,
  325. arete2;
  326. int vsuivant = -1;
  327. point3d tab[3];
  328. point3d_init (&(tab[0]), A.x, A.y, A.z);
  329. point3d_init (&(tab[1]), B.x, B.y, B.z);
  330. point3d_init (&(tab[2]), C.x, C.y, C.z);
  331. equation_plan (tab, 3, &aplan, &bplan, &cplan, &dplan);
  332. if (v2 == ve_fin)
  333. return 0;
  334. for (int i = 0; i < m->ve[v2].nbincidentvertices; i++)
  335. {
  336. if (egalite
  337. (aplan * m->ve[m->ve[v2].incidentvertices[i]].x +
  338. bplan * m->ve[m->ve[v2].incidentvertices[i]].y +
  339. cplan * m->ve[m->ve[v2].incidentvertices[i]].z + dplan, 0))
  340. if (m->ve[v2].incidentvertices[i] != v1)
  341. vsuivant = m->ve[v2].incidentvertices[i];
  342. }
  343. if (vsuivant == -1 || vsuivant == ve_dep)
  344. return -1;
  345. point3d_init (&arete1, m->ve[v2].x, m->ve[v2].y, m->ve[v2].z);
  346. point3d_init (&arete2, m->ve[vsuivant].x, m->ve[vsuivant].y,
  347. m->ve[vsuivant].z);
  348. list_int_add (list, size, vsuivant, WITH_REDUNDANCE);
  349. longueurtemp =
  350. construction_chemin_lineaire_intermediaire (m, ve_dep, ve_fin, A, B, C,
  351. v2, vsuivant, list, size);
  352. if (longueurtemp != -1)
  353. return point3d_length (&arete1, &arete2) + longueurtemp;
  354. else
  355. return -1;
  356. }
  357. double
  358. construction_chemin_lineaire (
  359. vf_model * m,
  360. int ve_dep,
  361. int ve_fin,
  362. point3d A,
  363. point3d B,
  364. point3d C,
  365. int **list,
  366. int *size)
  367. {
  368. double longueur1 = -1,
  369. longueur2 = -1,
  370. aplan,
  371. bplan,
  372. cplan,
  373. dplan;
  374. int v1 = -1,
  375. v2 = -1;
  376. point3d tab[3],
  377. pv1,
  378. pv2;
  379. point3d_init (&(tab[0]), A.x, A.y, A.z);
  380. point3d_init (&(tab[1]), B.x, B.y, B.z);
  381. point3d_init (&(tab[2]), C.x, C.y, C.z);
  382. int *list1 = NULL,
  383. *list2 = NULL;
  384. int size1 = 0,
  385. size2 = 0;
  386. equation_plan (tab, 3, &aplan, &bplan, &cplan, &dplan);
  387. for (int i = 0; i < m->ve[ve_dep].nbincidentvertices; i++)
  388. {
  389. if (egalite
  390. (aplan * m->ve[m->ve[ve_dep].incidentvertices[i]].x +
  391. bplan * m->ve[m->ve[ve_dep].incidentvertices[i]].y +
  392. cplan * m->ve[m->ve[ve_dep].incidentvertices[i]].z + dplan, 0))
  393. {
  394. if (v1 == -1)
  395. v1 = m->ve[ve_dep].incidentvertices[i];
  396. else
  397. v2 = m->ve[ve_dep].incidentvertices[i];
  398. }
  399. }
  400. if (v1 != -1)
  401. {
  402. list_int_add (&list1, &size1, ve_dep, WITH_REDUNDANCE);
  403. list_int_add (&list1, &size1, v1, WITH_REDUNDANCE);
  404. }
  405. if (v2 != -1)
  406. {
  407. list_int_add (&list2, &size2, ve_dep, WITH_REDUNDANCE);
  408. list_int_add (&list2, &size2, v2, WITH_REDUNDANCE);
  409. }
  410. if (v1 != -1)
  411. longueur1 =
  412. construction_chemin_lineaire_intermediaire (m, ve_dep, ve_fin, A, B, C,
  413. ve_dep, v1, &list1, &size1);
  414. if (v2 != -1)
  415. longueur2 =
  416. construction_chemin_lineaire_intermediaire (m, ve_dep, ve_fin, A, B, C,
  417. ve_dep, v2, &list2, &size2);
  418. if (longueur1 == -1 && longueur2 == -1)
  419. return -1;
  420. if (longueur1 == -1)
  421. longueur1 = longueur2 + 1;
  422. if (longueur2 == -1)
  423. longueur2 = longueur1 + 1;
  424. if (longueur1 < longueur2)
  425. {
  426. *list = list1;
  427. *size = size1;
  428. point3d_init (&pv1, m->ve[ve_dep].x, m->ve[ve_dep].y, m->ve[ve_dep].z);
  429. point3d_init (&pv2, m->ve[v1].x, m->ve[v1].y, m->ve[v1].z);
  430. return longueur1 + point3d_length (&pv1, &pv2);
  431. }
  432. else
  433. {
  434. *list = list2;
  435. *size = size2;
  436. point3d_init (&pv1, m->ve[ve_dep].x, m->ve[ve_dep].y, m->ve[ve_dep].z);
  437. point3d_init (&pv2, m->ve[v2].x, m->ve[v2].y, m->ve[v2].z);
  438. return longueur2 + point3d_length (&pv1, &pv2);
  439. }
  440. }
  441. /********** MAIN FUNCTIONS **********/
  442. /**
  443. Calcul du chemin le plus court entre deux sommets du modele
  444. @param m le modèle
  445. @param ve_dep sommet de départ
  446. @param ve_fin sommet d'arrivée
  447. @param list liste des sommets parcourus
  448. @param size taille du tableau contenant les sommets parcourus
  449. @return la longueur du chemin
  450. */
  451. double
  452. a2ri_vf_dijkstra (
  453. const vf_model * const m,
  454. int ve_dep,
  455. int ve_fin,
  456. int **list,
  457. int *size)
  458. {
  459. double *parcouru = NULL;
  460. int *precedent = NULL;
  461. int *pasencorevu = NULL,
  462. size_pasencorevu = 0;
  463. double distance;
  464. int index = 0,
  465. n1 = 0,
  466. n2;
  467. vf_edge *e;
  468. ptf_func_hashtable func[1];
  469. func[0] = a2ri_vf_update_length_edge;
  470. hashtable *table = a2ri_vf_construction_edge_table (m, func, 1);
  471. //initialisation des tableaux parcouru, precedent et pasencorevu
  472. precedent=(int*)malloc(m->nbvertex*sizeof(int));
  473. parcouru=(double*)malloc(m->nbvertex*sizeof(double));
  474. pasencorevu=(int*)malloc(m->nbvertex*sizeof(int));
  475. for(int i=0;i<m->nbvertex;i++)
  476. {
  477. precedent[i]=-1;
  478. parcouru[i]=-1;
  479. pasencorevu[i]=i;
  480. }
  481. size_pasencorevu=m->nbvertex;
  482. parcouru[ve_dep] = 0;
  483. while (size_pasencorevu != 0)
  484. {
  485. double dist_min = -1;
  486. for (int i = 0; i < size_pasencorevu; i++)
  487. {
  488. if (parcouru[pasencorevu[i]] >= 0
  489. && (parcouru[pasencorevu[i]] < dist_min || dist_min < 0))
  490. {
  491. index = i;
  492. n1 = pasencorevu[i];
  493. dist_min = parcouru[n1];
  494. }
  495. }
  496. list_int_remove (&pasencorevu, &size_pasencorevu, index);
  497. for (int i = 0; i < m->ve[n1].nbincidentvertices; i++)
  498. {
  499. n2 = m->ve[n1].incidentvertices[i];
  500. e = hashtable_look_for (table, n1, n2);
  501. distance = e->att_double;
  502. if (parcouru[n2] > parcouru[n1] + distance || parcouru[n2] == -1)
  503. {
  504. parcouru[n2] = parcouru[n1] + distance;
  505. precedent[n2] = n1;
  506. }
  507. }
  508. }
  509. index = ve_fin;
  510. while (index != ve_dep)
  511. {
  512. point3d p1,
  513. p2;
  514. point3d_init (&p1, m->ve[ve_dep].x, m->ve[ve_dep].y, m->ve[ve_dep].z);
  515. point3d_init (&p2, m->ve[precedent[index]].x, m->ve[precedent[index]].y,
  516. m->ve[precedent[index]].z);
  517. double distance = point3d_length (&p1, &p2);
  518. for (int i = 0; i < m->ve[index].nbincidentvertices; i++)
  519. {
  520. if (parcouru[precedent[index]] ==
  521. parcouru[m->ve[index].incidentvertices[i]])
  522. {
  523. point3d_init (&p2, m->ve[m->ve[index].incidentvertices[i]].x,
  524. m->ve[m->ve[index].incidentvertices[i]].y,
  525. m->ve[m->ve[index].incidentvertices[i]].z);
  526. if (distance > point3d_length (&p1, &p2))
  527. {
  528. distance = point3d_length (&p1, &p2);
  529. precedent[index] = m->ve[index].incidentvertices[i];
  530. }
  531. }
  532. }
  533. list_int_add (list, size, index, WITH_REDUNDANCE);
  534. index = precedent[index];
  535. }
  536. list_int_add (list, size, ve_dep, WITH_REDUNDANCE);
  537. list_int_reverse (*list, *size);
  538. hashtable_free (table);
  539. return parcouru[ve_fin];
  540. }
  541. /**
  542. Calcul du chemin le plus court entre deux sommets du modele
  543. @param m le modèle
  544. @param ve_dep sommet de départ
  545. @param ve_fin sommet d'arrivée
  546. @param list liste des sommets parcourus
  547. @param size taille du tableau contenant les sommets parcourus
  548. @return la longueur du chemin
  549. */
  550. double
  551. a2ri_vf_A_star (
  552. const vf_model * const m,
  553. int ve_dep,
  554. int ve_fin,
  555. int **list,
  556. int *size)
  557. {
  558. int *liste_ouverte=NULL,size_liste_ouverte=0,*liste_fermee=NULL,size_liste_fermee=0;
  559. double *parcouru=NULL,*distance_fin=NULL;
  560. int *precedent=NULL;
  561. int courant;
  562. point3d pcourant,pvoisin,pfin;
  563. int index;
  564. point3d_init(&pfin,m->ve[ve_fin].x,m->ve[ve_fin].y,m->ve[ve_fin].z);
  565. precedent=(int*)malloc(m->nbvertex*sizeof(int));
  566. parcouru=(double*)malloc(m->nbvertex*sizeof(double));
  567. distance_fin=(double*)malloc(m->nbvertex*sizeof(double));
  568. for(int i=0;i<m->nbvertex;i++)
  569. {
  570. precedent[i]=-1;
  571. parcouru[i]=-1;
  572. distance_fin[i]=-1;
  573. }
  574. list_int_add(&liste_ouverte,&size_liste_ouverte,ve_dep,WITH_REDUNDANCE);
  575. parcouru[ve_dep]=0;
  576. courant=ve_dep;
  577. //boucle principale de l'algorithme
  578. while(courant!=ve_fin && size_liste_ouverte!=0)
  579. {
  580. index=0;
  581. if(distance_fin[liste_ouverte[0]]<0)
  582. {
  583. point3d_init(&pcourant,m->ve[liste_ouverte[0]].x,m->ve[liste_ouverte[0]].y,m->ve[liste_ouverte[0]].z);
  584. distance_fin[liste_ouverte[0]]=point3d_length(&pcourant,&pfin);
  585. }
  586. //on cherche le meilleur dans liste_ouverte
  587. for(int i=1;i<size_liste_ouverte;i++)
  588. {
  589. if(distance_fin[liste_ouverte[i]]<0)
  590. {
  591. point3d_init(&pcourant,m->ve[liste_ouverte[i]].x,m->ve[liste_ouverte[i]].y,m->ve[liste_ouverte[i]].z);
  592. distance_fin[liste_ouverte[i]]=point3d_length(&pcourant,&pfin);
  593. }
  594. if(distance_fin[liste_ouverte[i]]<distance_fin[liste_ouverte[index]])
  595. index=i;
  596. }
  597. courant=liste_ouverte[index];
  598. if(courant!=ve_fin)
  599. {
  600. list_int_remove(&liste_ouverte,&size_liste_ouverte,index);
  601. list_int_add(&liste_fermee,&size_liste_fermee,courant,WITH_REDUNDANCE);
  602. //ajout des voisins du sommet courant dans la liste ouverte
  603. point3d_init(&pcourant,m->ve[courant].x,m->ve[courant].y,m->ve[courant].z);
  604. for(int i=0;i<m->ve[courant].nbincidentvertices;i++)
  605. {
  606. if(list_int_contains(liste_fermee,size_liste_fermee,m->ve[courant].incidentvertices[i])==-1)
  607. {
  608. point3d_init(&pvoisin,
  609. m->ve[m->ve[courant].incidentvertices[i]].x,
  610. m->ve[m->ve[courant].incidentvertices[i]].y,
  611. m->ve[m->ve[courant].incidentvertices[i]].z);
  612. if(list_int_contains(liste_ouverte,
  613. size_liste_ouverte,
  614. m->ve[courant].incidentvertices[i])!=-1)
  615. {
  616. if(parcouru[m->ve[courant].incidentvertices[i]]>parcouru[courant]+point3d_length(&pcourant,&pvoisin))
  617. {
  618. precedent[m->ve[courant].incidentvertices[i]]=courant;
  619. parcouru[m->ve[courant].incidentvertices[i]]=parcouru[courant]+point3d_length(&pcourant,&pvoisin);
  620. }
  621. }
  622. else
  623. {
  624. precedent[m->ve[courant].incidentvertices[i]]=courant;
  625. parcouru[m->ve[courant].incidentvertices[i]]=parcouru[courant]+point3d_length(&pcourant,&pvoisin);
  626. list_int_add(&liste_ouverte,&size_liste_ouverte,m->ve[courant].incidentvertices[i],WITH_REDUNDANCE);
  627. }
  628. }
  629. }
  630. }
  631. }
  632. if(size_liste_ouverte==0)
  633. {
  634. *list=NULL;
  635. *size=0;
  636. return -1;
  637. }
  638. courant=ve_fin;
  639. while(courant!=ve_dep)
  640. {
  641. list_int_add(list,size,courant,WITH_REDUNDANCE);
  642. courant=precedent[courant];
  643. }
  644. list_int_add(list,size,ve_dep,WITH_REDUNDANCE);
  645. list_int_reverse (*list, *size);
  646. return parcouru[ve_fin];
  647. }
  648. /**
  649. Calcul du chemin le plus court entre deux sommets du modele
  650. @param m le modèle
  651. @param ve_dep sommet de départ
  652. @param ve_fin sommet d'arrivée
  653. @param list liste des sommets parcourus
  654. @param size taille du tableau contenant les sommets parcourus
  655. @return la longueur du chemin
  656. */
  657. double
  658. a2ri_vf_approche (
  659. const vf_model * const m,
  660. int ve_dep,
  661. int ve_fin,
  662. int **list,
  663. int *size)
  664. {
  665. int fin = 0,
  666. index = ve_dep,
  667. a_ajouter = ve_dep;
  668. double distance = 0;
  669. point3d p1,
  670. p2,
  671. p3;
  672. double length = 0;
  673. list_int_add (list, size, a_ajouter, WITH_REDUNDANCE);
  674. point3d_init (&p2, m->ve[ve_fin].x, m->ve[ve_fin].y, m->ve[ve_fin].z);
  675. while (!fin && index != ve_fin)
  676. {
  677. for (int i = 0; i < m->ve[index].nbincidentvertices; i++)
  678. {
  679. point3d_init (&p1, m->ve[m->ve[index].incidentvertices[i]].x,
  680. m->ve[m->ve[index].incidentvertices[i]].y,
  681. m->ve[m->ve[index].incidentvertices[i]].z);
  682. if (i == 0)
  683. {
  684. distance = point3d_length (&p1, &p2);
  685. a_ajouter = m->ve[index].incidentvertices[0];
  686. }
  687. else
  688. {
  689. if (distance > point3d_length (&p1, &p2))
  690. {
  691. distance = point3d_length (&p1, &p2);
  692. a_ajouter = m->ve[index].incidentvertices[i];
  693. }
  694. }
  695. }
  696. point3d_init (&p1, m->ve[(*list)[(*size) - 1]].x,
  697. m->ve[(*list)[(*size) - 1]].y,
  698. m->ve[(*list)[(*size) - 1]].z);
  699. point3d_init (&p3, m->ve[a_ajouter].x, m->ve[a_ajouter].y,
  700. m->ve[a_ajouter].z);
  701. if (list_int_contains (*list, *size, a_ajouter) != -1)
  702. fin = 1;
  703. index = a_ajouter;
  704. list_int_add (list, size, a_ajouter, WITH_REDUNDANCE);
  705. length = length + point3d_length (&p1, &p3);
  706. if (fin)
  707. {
  708. length = -1;
  709. free (*list);
  710. *list = NULL;
  711. *size = 0;
  712. }
  713. }
  714. return length;
  715. }
  716. /**
  717. Calcul du chemin le plus court entre deux sommets du modele
  718. @param m le modèle
  719. @param ve_dep sommet de départ
  720. @param ve_fin sommet d'arrivée
  721. @param list liste des sommets parcourus
  722. @param size taille du tableau contenant les sommets parcourus
  723. @return la longueur du chemin
  724. */
  725. double
  726. a2ri_vef_dijkstra (
  727. const vef_model * const m,
  728. int ve_dep,
  729. int ve_fin,
  730. int **list,
  731. int *size)
  732. {
  733. double *parcouru = NULL;
  734. int size_parcouru = 0;
  735. int *precedent = NULL,
  736. size_precedent = 0;
  737. int *pasencorevu = NULL,
  738. size_pasencorevu = 0;
  739. double *distance = NULL;
  740. int size_distance = 0;
  741. point3d p1,
  742. p2;
  743. int index = 0,
  744. n1 = 0,
  745. n2;
  746. //initialisation des longueurs des aretes
  747. for (int i = 0; i < m->nbedge; i++)
  748. {
  749. point3d_init (&p1, m->ve[m->ed[i].ve1].x, m->ve[m->ed[i].ve1].y,
  750. m->ve[m->ed[i].ve1].z);
  751. point3d_init (&p2, m->ve[m->ed[i].ve2].x, m->ve[m->ed[i].ve2].y,
  752. m->ve[m->ed[i].ve2].z);
  753. list_double_add (&distance, &size_distance, point3d_length (&p1, &p2),
  754. WITH_REDUNDANCE);
  755. }
  756. //initialisation des tableaux parcouru, precedent et pasencorevu
  757. for (int i = 0; i < m->nbvertex; i++)
  758. {
  759. list_double_add (&parcouru, &size_parcouru, -1, WITH_REDUNDANCE);
  760. list_int_add (&precedent, &size_precedent, -1, WITH_REDUNDANCE);
  761. list_int_add (&pasencorevu, &size_pasencorevu, i, WITH_REDUNDANCE);
  762. }
  763. parcouru[ve_dep] = 0;
  764. while (size_pasencorevu != 0)
  765. {
  766. double dist_min = -1;
  767. for (int i = 0; i < size_pasencorevu; i++)
  768. {
  769. if (parcouru[pasencorevu[i]] >= 0
  770. && (parcouru[pasencorevu[i]] < dist_min || dist_min < 0))
  771. {
  772. index = i;
  773. n1 = pasencorevu[i];
  774. dist_min = parcouru[n1];
  775. }
  776. }
  777. list_int_remove (&pasencorevu, &size_pasencorevu, index);
  778. for (int i = 0; i < m->ve[n1].nbsharededges; i++)
  779. {
  780. if (m->ed[m->ve[n1].sharededges[i]].ve1 == n1)
  781. n2 = m->ed[m->ve[n1].sharededges[i]].ve2;
  782. else
  783. n2 = m->ed[m->ve[n1].sharededges[i]].ve1;
  784. if (parcouru[n2] >
  785. parcouru[n1] + distance[a2ri_vef_search_edge (m, n1, n2)]
  786. || parcouru[n2] == -1)
  787. {
  788. parcouru[n2] =
  789. parcouru[n1] + distance[a2ri_vef_search_edge (m, n1, n2)];
  790. precedent[n2] = n1;
  791. }
  792. }
  793. }
  794. index = ve_fin;
  795. while (index != ve_dep)
  796. {
  797. list_int_add (list, size, index, WITH_REDUNDANCE);
  798. index = precedent[index];
  799. }
  800. list_int_add (list, size, ve_dep, WITH_REDUNDANCE);
  801. return parcouru[ve_fin];
  802. }
  803. /**
  804. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  805. @param m le modèle
  806. @param ve_dep sommet de départ
  807. @param ve_fin sommet d'arrivée
  808. @param list liste des sommets parcourus
  809. @param size taille du tableau contenant les sommets parcourus
  810. @param length longueur totale parcouru
  811. @return aucun
  812. **/
  813. int
  814. a2ri_vf_geodesic_path_approche_plan_moyen (
  815. vf_model * m,
  816. int ve_dep,
  817. int ve_fin,
  818. int **list,
  819. int *size,
  820. double *length,
  821. int nbsubdiv)
  822. {
  823. int *listtemp1 = NULL,
  824. size_listtemp1 = 0;
  825. int *listtemp2 = NULL,
  826. size_listtemp2 = 0;
  827. point3d A,
  828. B,
  829. C;
  830. vf_model *temp = a2ri_vf_clone (m);
  831. a2ri_vf_6_subdivision (temp, nbsubdiv);
  832. a2ri_vf_approche (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  833. if (size_listtemp1 == 0)
  834. {
  835. *length = -1;
  836. *size = 0;
  837. *list = NULL;
  838. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  839. }
  840. a2ri_vf_approche (temp, ve_fin, ve_dep, &listtemp2, &size_listtemp2);
  841. if (size_listtemp2 == 0)
  842. {
  843. *length = -1;
  844. *size = 0;
  845. *list = NULL;
  846. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  847. }
  848. list_int_remove (&listtemp1, &size_listtemp1, size_listtemp1 - 1);
  849. list_int_remove (&listtemp2, &size_listtemp2, size_listtemp2 - 1);
  850. list_int_reverse (listtemp2, size_listtemp2);
  851. for (int i = 0; i < size_listtemp2; i++)
  852. list_int_add (&listtemp1, &size_listtemp1, listtemp2[i], WITH_REDUNDANCE);
  853. free (listtemp2);
  854. IFcalcul_plan_moyenne (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  855. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  856. a2ri_vf_free (temp);
  857. free (temp);
  858. if (trois_points_alignes (&A, &B, &C))
  859. {
  860. *length = -1;
  861. *size = 0;
  862. *list = NULL;
  863. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  864. }
  865. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  866. free (listtemp1);
  867. *list = NULL;
  868. *size = 0;
  869. *length =
  870. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  871. return 1;
  872. }
  873. /**
  874. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  875. @param m le modèle
  876. @param ve_dep sommet de départ
  877. @param ve_fin sommet d'arrivée
  878. @param list liste des sommets parcourus
  879. @param size taille du tableau contenant les sommets parcourus
  880. @param length longueur totale parcouru
  881. @return aucun
  882. **/
  883. int
  884. a2ri_vf_geodesic_path_A_star_plan_moyen (
  885. vf_model * m,
  886. int ve_dep,
  887. int ve_fin,
  888. int **list,
  889. int *size,
  890. double *length,
  891. int nbsubdiv)
  892. {
  893. int *listtemp1 = NULL,
  894. size_listtemp1 = 0;
  895. int *listtemp2 = NULL,
  896. size_listtemp2 = 0;
  897. point3d A,
  898. B,
  899. C;
  900. vf_model *temp = a2ri_vf_clone (m);
  901. a2ri_vf_6_subdivision (temp, nbsubdiv);
  902. a2ri_vf_A_star (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  903. if (size_listtemp1 == 0)
  904. {
  905. *length = -1;
  906. *size = 0;
  907. *list = NULL;
  908. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  909. }
  910. a2ri_vf_A_star (temp, ve_fin, ve_dep, &listtemp2, &size_listtemp2);
  911. if (size_listtemp2 == 0)
  912. {
  913. *length = -1;
  914. *size = 0;
  915. *list = NULL;
  916. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  917. }
  918. list_int_remove (&listtemp1, &size_listtemp1, size_listtemp1 - 1);
  919. list_int_remove (&listtemp2, &size_listtemp2, size_listtemp2 - 1);
  920. list_int_reverse (listtemp2, size_listtemp2);
  921. for (int i = 0; i < size_listtemp2; i++)
  922. list_int_add (&listtemp1, &size_listtemp1, listtemp2[i], WITH_REDUNDANCE);
  923. free (listtemp2);
  924. IFcalcul_plan_moyenne (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  925. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  926. a2ri_vf_free (temp);
  927. free (temp);
  928. if (trois_points_alignes (&A, &B, &C))
  929. {
  930. *length = -1;
  931. *size = 0;
  932. *list = NULL;
  933. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  934. }
  935. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  936. free (listtemp1);
  937. *list = NULL;
  938. *size = 0;
  939. *length =
  940. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  941. return 1;
  942. }
  943. /**
  944. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  945. @param m le modèle
  946. @param ve_dep sommet de départ
  947. @param ve_fin sommet d'arrivée
  948. @param list liste des sommets parcourus
  949. @param size taille du tableau contenant les sommets parcourus
  950. @param length longueur totale parcouru
  951. @return aucun
  952. **/
  953. int
  954. a2ri_vf_geodesic_path_approche_plan_minmax (
  955. vf_model * m,
  956. int ve_dep,
  957. int ve_fin,
  958. int **list,
  959. int *size,
  960. double *length,
  961. int nbsubdiv)
  962. {
  963. int *listtemp1 = NULL,
  964. size_listtemp1 = 0;
  965. int *listtemp2 = NULL,
  966. size_listtemp2 = 0;
  967. point3d A,
  968. B,
  969. C;
  970. vf_model *temp = a2ri_vf_clone (m);
  971. a2ri_vf_6_subdivision (temp, nbsubdiv);
  972. a2ri_vf_approche (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  973. if (size_listtemp1 == 0)
  974. {
  975. *length = -1;
  976. *size = 0;
  977. *list = NULL;
  978. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  979. }
  980. a2ri_vf_approche (temp, ve_fin, ve_dep, &listtemp2, &size_listtemp2);
  981. if (size_listtemp2 == 0)
  982. {
  983. *length = -1;
  984. *size = 0;
  985. *list = NULL;
  986. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  987. }
  988. list_int_remove (&listtemp1, &size_listtemp1, size_listtemp1 - 1);
  989. list_int_remove (&listtemp2, &size_listtemp2, size_listtemp2 - 1);
  990. list_int_reverse (listtemp2, size_listtemp2);
  991. for (int i = 0; i < size_listtemp2; i++)
  992. list_int_add (&listtemp1, &size_listtemp1, listtemp2[i], WITH_REDUNDANCE);
  993. free (listtemp2);
  994. IFcalcul_plan_min_max (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  995. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  996. a2ri_vf_free (temp);
  997. free (temp);
  998. if (trois_points_alignes (&A, &B, &C))
  999. {
  1000. *length = -1;
  1001. *size = 0;
  1002. *list = NULL;
  1003. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  1004. }
  1005. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  1006. free (listtemp1);
  1007. *list = NULL;
  1008. *size = 0;
  1009. *length =
  1010. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  1011. return 1;
  1012. }
  1013. /**
  1014. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  1015. @param m le modèle
  1016. @param ve_dep sommet de départ
  1017. @param ve_fin sommet d'arrivée
  1018. @param list liste des sommets parcourus
  1019. @param size taille du tableau contenant les sommets parcourus
  1020. @param length longueur totale parcouru
  1021. @return aucun
  1022. **/
  1023. int
  1024. a2ri_vf_geodesic_path_A_star_plan_minmax (
  1025. vf_model * m,
  1026. int ve_dep,
  1027. int ve_fin,
  1028. int **list,
  1029. int *size,
  1030. double *length,
  1031. int nbsubdiv)
  1032. {
  1033. int *listtemp1 = NULL,
  1034. size_listtemp1 = 0;
  1035. int *listtemp2 = NULL,
  1036. size_listtemp2 = 0;
  1037. point3d A,
  1038. B,
  1039. C;
  1040. vf_model *temp = a2ri_vf_clone (m);
  1041. a2ri_vf_6_subdivision (temp, nbsubdiv);
  1042. a2ri_vf_A_star (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  1043. if (size_listtemp1 == 0)
  1044. {
  1045. *length = -1;
  1046. *size = 0;
  1047. *list = NULL;
  1048. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  1049. }
  1050. a2ri_vf_A_star (temp, ve_fin, ve_dep, &listtemp2, &size_listtemp2);
  1051. if (size_listtemp2 == 0)
  1052. {
  1053. *length = -1;
  1054. *size = 0;
  1055. *list = NULL;
  1056. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  1057. }
  1058. list_int_remove (&listtemp1, &size_listtemp1, size_listtemp1 - 1);
  1059. list_int_remove (&listtemp2, &size_listtemp2, size_listtemp2 - 1);
  1060. list_int_reverse (listtemp2, size_listtemp2);
  1061. for (int i = 0; i < size_listtemp2; i++)
  1062. list_int_add (&listtemp1, &size_listtemp1, listtemp2[i], WITH_REDUNDANCE);
  1063. free (listtemp2);
  1064. IFcalcul_plan_min_max (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  1065. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  1066. a2ri_vf_free (temp);
  1067. free (temp);
  1068. if (trois_points_alignes (&A, &B, &C))
  1069. {
  1070. *length = -1;
  1071. *size = 0;
  1072. *list = NULL;
  1073. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  1074. }
  1075. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  1076. free (listtemp1);
  1077. *list = NULL;
  1078. *size = 0;
  1079. *length =
  1080. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  1081. return 1;
  1082. }
  1083. /**
  1084. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  1085. @param m le modèle
  1086. @param ve_dep sommet de départ
  1087. @param ve_fin sommet d'arrivée
  1088. @param list liste des sommets parcourus
  1089. @param size taille du tableau contenant les sommets parcourus
  1090. @param length longueur totale parcouru
  1091. @return aucun
  1092. **/
  1093. int
  1094. a2ri_vf_geodesic_path_approche_plan_vecteur (
  1095. vf_model * m,
  1096. int ve_dep,
  1097. int ve_fin,
  1098. int **list,
  1099. int *size,
  1100. double *length,
  1101. int nbsubdiv)
  1102. {
  1103. int *listtemp1 = NULL,
  1104. size_listtemp1 = 0;
  1105. int *listtemp2 = NULL,
  1106. size_listtemp2 = 0;
  1107. point3d A,
  1108. B,
  1109. C;
  1110. vf_model *temp = a2ri_vf_clone (m);
  1111. a2ri_vf_6_subdivision (temp, nbsubdiv);
  1112. a2ri_vf_approche (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  1113. if (size_listtemp1 == 0)
  1114. {
  1115. *length = -1;
  1116. *size = 0;
  1117. *list = NULL;
  1118. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  1119. }
  1120. a2ri_vf_approche (temp, ve_fin, ve_dep, &listtemp2, &size_listtemp2);
  1121. if (size_listtemp2 == 0)
  1122. {
  1123. *length = -1;
  1124. *size = 0;
  1125. *list = NULL;
  1126. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  1127. }
  1128. list_int_remove (&listtemp1, &size_listtemp1, size_listtemp1 - 1);
  1129. list_int_remove (&listtemp2, &size_listtemp2, size_listtemp2 - 1);
  1130. list_int_reverse (listtemp2, size_listtemp2);
  1131. for (int i = 0; i < size_listtemp2; i++)
  1132. list_int_add (&listtemp1, &size_listtemp1, listtemp2[i], WITH_REDUNDANCE);
  1133. free (listtemp2);
  1134. IFcalcul_plan_vecteur (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  1135. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  1136. a2ri_vf_free (temp);
  1137. free (temp);
  1138. if (trois_points_alignes (&A, &B, &C))
  1139. {
  1140. *length = -1;
  1141. *size = 0;
  1142. *list = NULL;
  1143. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  1144. }
  1145. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  1146. free (listtemp1);
  1147. free (*list);
  1148. *list = NULL;
  1149. *size = 0;
  1150. *length =
  1151. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  1152. return 1;
  1153. }
  1154. /**
  1155. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  1156. @param m le modèle
  1157. @param ve_dep sommet de départ
  1158. @param ve_fin sommet d'arrivée
  1159. @param list liste des sommets parcourus
  1160. @param size taille du tableau contenant les sommets parcourus
  1161. @param length longueur totale parcouru
  1162. @return aucun
  1163. **/
  1164. int
  1165. a2ri_vf_geodesic_path_A_star_plan_vecteur (
  1166. vf_model * m,
  1167. int ve_dep,
  1168. int ve_fin,
  1169. int **list,
  1170. int *size,
  1171. double *length,
  1172. int nbsubdiv)
  1173. {
  1174. int *listtemp1 = NULL,
  1175. size_listtemp1 = 0;
  1176. int *listtemp2 = NULL,
  1177. size_listtemp2 = 0;
  1178. point3d A,
  1179. B,
  1180. C;
  1181. vf_model *temp = a2ri_vf_clone (m);
  1182. a2ri_vf_6_subdivision (temp, nbsubdiv);
  1183. a2ri_vf_A_star (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  1184. if (size_listtemp1 == 0)
  1185. {
  1186. *length = -1;
  1187. *size = 0;
  1188. *list = NULL;
  1189. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  1190. }
  1191. a2ri_vf_A_star (temp, ve_fin, ve_dep, &listtemp2, &size_listtemp2);
  1192. if (size_listtemp2 == 0)
  1193. {
  1194. *length = -1;
  1195. *size = 0;
  1196. *list = NULL;
  1197. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  1198. }
  1199. list_int_remove (&listtemp1, &size_listtemp1, size_listtemp1 - 1);
  1200. list_int_remove (&listtemp2, &size_listtemp2, size_listtemp2 - 1);
  1201. list_int_reverse (listtemp2, size_listtemp2);
  1202. for (int i = 0; i < size_listtemp2; i++)
  1203. list_int_add (&listtemp1, &size_listtemp1, listtemp2[i], WITH_REDUNDANCE);
  1204. free (listtemp2);
  1205. IFcalcul_plan_vecteur (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  1206. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  1207. a2ri_vf_free (temp);
  1208. free (temp);
  1209. if (trois_points_alignes (&A, &B, &C))
  1210. {
  1211. *length = -1;
  1212. *size = 0;
  1213. *list = NULL;
  1214. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  1215. }
  1216. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  1217. free (listtemp1);
  1218. free (*list);
  1219. *list = NULL;
  1220. *size = 0;
  1221. *length =
  1222. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  1223. return 1;
  1224. }
  1225. /**
  1226. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  1227. @param m le modèle
  1228. @param ve_dep sommet de départ
  1229. @param ve_fin sommet d'arrivée
  1230. @param list liste des sommets parcourus
  1231. @param size taille du tableau contenant les sommets parcourus
  1232. @param length longueur totale parcouru
  1233. @return aucun
  1234. **/
  1235. int
  1236. a2ri_vf_geodesic_path_approche_plan_intersection (
  1237. vf_model * m,
  1238. int ve_dep,
  1239. int ve_fin,
  1240. int **list,
  1241. int *size,
  1242. double *length,
  1243. int nbsubdiv)
  1244. {
  1245. int *listtemp1 = NULL,
  1246. size_listtemp1 = 0;
  1247. int *listtemp2 = NULL,
  1248. size_listtemp2 = 0;
  1249. point3d A,
  1250. B,
  1251. C;
  1252. vf_model *temp = a2ri_vf_clone (m);
  1253. a2ri_vf_6_subdivision (temp, nbsubdiv);
  1254. a2ri_vf_approche (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  1255. if (size_listtemp1 == 0)
  1256. {
  1257. *length = -1;
  1258. *size = 0;
  1259. *list = NULL;
  1260. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  1261. }
  1262. a2ri_vf_approche (temp, ve_fin, ve_dep, &listtemp2, &size_listtemp2);
  1263. if (size_listtemp2 == 0)
  1264. {
  1265. *length = -1;
  1266. *size = 0;
  1267. *list = NULL;
  1268. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  1269. }
  1270. list_int_remove (&listtemp1, &size_listtemp1, size_listtemp1 - 1);
  1271. list_int_remove (&listtemp2, &size_listtemp2, size_listtemp2 - 1);
  1272. list_int_reverse (listtemp2, size_listtemp2);
  1273. for (int i = 0; i < size_listtemp2; i++)
  1274. list_int_add (&listtemp1, &size_listtemp1, listtemp2[i], WITH_REDUNDANCE);
  1275. free (listtemp2);
  1276. IFcalcul_plan_intersection (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  1277. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  1278. a2ri_vf_free (temp);
  1279. free (temp);
  1280. if (trois_points_alignes (&A, &B, &C))
  1281. {
  1282. *length = -1;
  1283. *size = 0;
  1284. *list = NULL;
  1285. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  1286. }
  1287. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  1288. free (listtemp1);
  1289. *list = NULL;
  1290. *size = 0;
  1291. *length =
  1292. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  1293. return 1;
  1294. }
  1295. /**
  1296. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  1297. @param m le modèle
  1298. @param ve_dep sommet de départ
  1299. @param ve_fin sommet d'arrivée
  1300. @param list liste des sommets parcourus
  1301. @param size taille du tableau contenant les sommets parcourus
  1302. @param length longueur totale parcouru
  1303. @return aucun
  1304. **/
  1305. int
  1306. a2ri_vf_geodesic_path_A_star_plan_intersection (
  1307. vf_model * m,
  1308. int ve_dep,
  1309. int ve_fin,
  1310. int **list,
  1311. int *size,
  1312. double *length,
  1313. int nbsubdiv)
  1314. {
  1315. int *listtemp1 = NULL,
  1316. size_listtemp1 = 0;
  1317. int *listtemp2 = NULL,
  1318. size_listtemp2 = 0;
  1319. point3d A,
  1320. B,
  1321. C;
  1322. vf_model *temp = a2ri_vf_clone (m);
  1323. a2ri_vf_6_subdivision (temp, nbsubdiv);
  1324. a2ri_vf_A_star (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  1325. if (size_listtemp1 == 0)
  1326. {
  1327. *length = -1;
  1328. *size = 0;
  1329. *list = NULL;
  1330. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  1331. }
  1332. a2ri_vf_A_star (temp, ve_fin, ve_dep, &listtemp2, &size_listtemp2);
  1333. if (size_listtemp2 == 0)
  1334. {
  1335. *length = -1;
  1336. *size = 0;
  1337. *list = NULL;
  1338. return A2RI_GEODESIQUE_CHEMIN_INTROUVABLE;
  1339. }
  1340. list_int_remove (&listtemp1, &size_listtemp1, size_listtemp1 - 1);
  1341. list_int_remove (&listtemp2, &size_listtemp2, size_listtemp2 - 1);
  1342. list_int_reverse (listtemp2, size_listtemp2);
  1343. for (int i = 0; i < size_listtemp2; i++)
  1344. list_int_add (&listtemp1, &size_listtemp1, listtemp2[i], WITH_REDUNDANCE);
  1345. free (listtemp2);
  1346. IFcalcul_plan_intersection (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  1347. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  1348. a2ri_vf_free (temp);
  1349. free (temp);
  1350. if (trois_points_alignes (&A, &B, &C))
  1351. {
  1352. *length = -1;
  1353. *size = 0;
  1354. *list = NULL;
  1355. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  1356. }
  1357. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  1358. free (listtemp1);
  1359. *list = NULL;
  1360. *size = 0;
  1361. *length =
  1362. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  1363. return 1;
  1364. }
  1365. /**
  1366. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  1367. @param m le modèle
  1368. @param ve_dep sommet de départ
  1369. @param ve_fin sommet d'arrivée
  1370. @param list liste des sommets parcourus
  1371. @param size taille du tableau contenant les sommets parcourus
  1372. @param length longueur totale parcouru
  1373. @return aucun
  1374. **/
  1375. int
  1376. a2ri_vf_geodesic_path_dijkstra_plan_minmax (
  1377. vf_model * m,
  1378. int ve_dep,
  1379. int ve_fin,
  1380. int **list,
  1381. int *size,
  1382. double *length,
  1383. int nbsubdiv)
  1384. {
  1385. int *listtemp1 = NULL,
  1386. size_listtemp1 = 0;
  1387. point3d A,
  1388. B,
  1389. C;
  1390. vf_model *temp = a2ri_vf_clone (m);
  1391. a2ri_vf_6_subdivision (temp, nbsubdiv);
  1392. a2ri_vf_dijkstra (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  1393. IFcalcul_plan_min_max (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  1394. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  1395. a2ri_vf_free (temp);
  1396. free (temp);
  1397. if (trois_points_alignes (&A, &B, &C))
  1398. {
  1399. *length = -1;
  1400. *size = 0;
  1401. *list = NULL;
  1402. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  1403. }
  1404. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  1405. free (listtemp1);
  1406. *list = NULL;
  1407. *size = 0;
  1408. *length =
  1409. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  1410. return 1;
  1411. }
  1412. /**
  1413. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  1414. @param m le modèle
  1415. @param ve_dep sommet de départ
  1416. @param ve_fin sommet d'arrivée
  1417. @param list liste des sommets parcourus
  1418. @param size taille du tableau contenant les sommets parcourus
  1419. @param length longueur totale parcouru
  1420. @return aucun
  1421. **/
  1422. int
  1423. a2ri_vf_geodesic_path_dijkstra_plan_vecteur (
  1424. vf_model * m,
  1425. int ve_dep,
  1426. int ve_fin,
  1427. int **list,
  1428. int *size,
  1429. double *length,
  1430. int nbsubdiv)
  1431. {
  1432. int *listtemp1 = NULL,
  1433. size_listtemp1 = 0;
  1434. point3d A,
  1435. B,
  1436. C;
  1437. vf_model *temp = a2ri_vf_clone (m);
  1438. a2ri_vf_6_subdivision (temp, nbsubdiv);
  1439. a2ri_vf_dijkstra (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  1440. IFcalcul_plan_vecteur (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  1441. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  1442. a2ri_vf_free (temp);
  1443. free (temp);
  1444. if (trois_points_alignes (&A, &B, &C))
  1445. {
  1446. *length = -1;
  1447. *size = 0;
  1448. *list = NULL;
  1449. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  1450. }
  1451. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  1452. free (listtemp1);
  1453. *list = NULL;
  1454. *size = 0;
  1455. *length =
  1456. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  1457. return 1;
  1458. }
  1459. /**
  1460. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  1461. @param m le modèle
  1462. @param ve_dep sommet de départ
  1463. @param ve_fin sommet d'arrivée
  1464. @param list liste des sommets parcourus
  1465. @param size taille du tableau contenant les sommets parcourus
  1466. @param length longueur totale parcouru
  1467. @return aucun
  1468. **/
  1469. int
  1470. a2ri_vf_geodesic_path_dijkstra_plan_intersection (
  1471. vf_model * m,
  1472. int ve_dep,
  1473. int ve_fin,
  1474. int **list,
  1475. int *size,
  1476. double *length,
  1477. int nbsubdiv)
  1478. {
  1479. int *listtemp1 = NULL,
  1480. size_listtemp1 = 0;
  1481. point3d A,
  1482. B,
  1483. C;
  1484. vf_model *temp = a2ri_vf_clone (m);
  1485. a2ri_vf_6_subdivision (temp, nbsubdiv);
  1486. a2ri_vf_dijkstra (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  1487. IFcalcul_plan_intersection (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  1488. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  1489. a2ri_vf_free (temp);
  1490. free (temp);
  1491. if (trois_points_alignes (&A, &B, &C))
  1492. {
  1493. *length = -1;
  1494. *size = 0;
  1495. *list = NULL;
  1496. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  1497. }
  1498. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  1499. free (listtemp1);
  1500. *list = NULL;
  1501. *size = 0;
  1502. *length =
  1503. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  1504. return 1;
  1505. }
  1506. /**
  1507. Calcul le chemin géodésique entre deux sommets. Le maillage sera subdivisé et le chemin entre des deux sommets retournés
  1508. @param m le modèle
  1509. @param ve_dep sommet de départ
  1510. @param ve_fin sommet d'arrivée
  1511. @param list liste des sommets parcourus
  1512. @param size taille du tableau contenant les sommets parcourus
  1513. @param length longueur totale parcouru
  1514. @return aucun
  1515. **/
  1516. int
  1517. a2ri_vf_geodesic_path_dijkstra_plan_moyen (
  1518. vf_model * m,
  1519. int ve_dep,
  1520. int ve_fin,
  1521. int **list,
  1522. int *size,
  1523. double *length,
  1524. int nbsubdiv)
  1525. {
  1526. int *listtemp1 = NULL,
  1527. size_listtemp1 = 0;
  1528. point3d A,
  1529. B,
  1530. C;
  1531. vf_model *temp = a2ri_vf_clone (m);
  1532. a2ri_vf_6_subdivision (temp, nbsubdiv);
  1533. a2ri_vf_dijkstra (temp, ve_dep, ve_fin, &listtemp1, &size_listtemp1);
  1534. IFcalcul_plan_moyenne (temp, listtemp1[0], listtemp1[size_listtemp1 - 1],
  1535. listtemp1 + 1, size_listtemp1 - 2, &A, &B, &C);
  1536. a2ri_vf_free (temp);
  1537. free (temp);
  1538. if (trois_points_alignes (&A, &B, &C))
  1539. {
  1540. *length = -1;
  1541. *size = 0;
  1542. *list = NULL;
  1543. return A2RI_GEODESIQUE_POINTS_ALIGNES;
  1544. }
  1545. a2ri_vf_subdivision_by_plane (m, &A, &B, &C);
  1546. free (listtemp1);
  1547. *list = NULL;
  1548. *size = 0;
  1549. *length =
  1550. construction_chemin_lineaire (m, ve_dep, ve_fin, A, B, C, list, size);
  1551. return 1;
  1552. }