skeleton.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. /*************************************/
  2. /* Auteur : Rémi Synave */
  3. /* Date de création : 17/03/15 */
  4. /* Date de modification : 18/09/16 */
  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 "skeleton.h"
  25. /**
  26. Initialisation d'un squelette avec un maillage vide
  27. @param m pointeur sur le squelette
  28. @return aucun
  29. */
  30. void a2ri_skeleton_init (
  31. skeleton * s)
  32. {
  33. s->ve=NULL;
  34. s->ed=NULL;
  35. s->nbvertex=0;
  36. s->nbedge=0;
  37. }
  38. /**
  39. Libération de l'espace mémoire utilisé
  40. @param m pointeur sur le squelette
  41. */
  42. void a2ri_skeleton_free (
  43. skeleton * s)
  44. {
  45. for (int i = 0; i < s->nbvertex; i++)
  46. {
  47. free (s->ve[i].sharededges);
  48. }
  49. free (s->ve);
  50. free (s->ed);
  51. }
  52. /**
  53. Affichage des caractéristiques générales d'un squelette (sommets et arêtes)
  54. @param m le squelette
  55. @return aucun
  56. */
  57. void a2ri_skeleton_display (
  58. const skeleton * const s)
  59. {
  60. printf ("********************\nSkeleton :");
  61. printf ("\n\t%d vertices\n", s->nbvertex);
  62. printf ("\t%d faces\n", s->nbedge);
  63. printf ("********************\n");
  64. }
  65. /**
  66. Affichage des caractéristiques détaillées d'un squelette (sommets et arêtes et leurs adjacences)
  67. @param m le squelette
  68. @return aucun
  69. */
  70. void a2ri_skeleton_display_detail (
  71. const skeleton * const s)
  72. {
  73. printf ("********************\nSkeleton :");
  74. if (s->nbvertex)
  75. {
  76. printf ("\n\t%d vertices\n", s->nbvertex);
  77. for (int i = 0; i < s->nbvertex; i++)
  78. {
  79. printf ("\t\t%5d - ", i);
  80. vef_vertex_display_detail (&(s->ve[i]));
  81. printf ("\n");
  82. }
  83. }
  84. if (s->nbedge)
  85. {
  86. printf ("\n\t%d edges\n", s->nbedge);
  87. for (int i = 0; i < s->nbedge; i++)
  88. {
  89. printf ("\t\t%5d - (%d , %d) ",
  90. i, s->ed[i].ve1, s->ed[i].ve2);
  91. printf ("\n\n");
  92. }
  93. }
  94. }
  95. /**
  96. Ajout d'un vertex (x,y,z) au squelette
  97. @param m pointeur sur le squelette
  98. @param x coordonnée x du vertex
  99. @param y coordonnée y
  100. @param z coordonnée z
  101. @return 1 si succès, 0 sinon
  102. */
  103. int a2ri_skeleton_add_vertex (
  104. skeleton * s,
  105. double x,
  106. double y,
  107. double z)
  108. {
  109. if (s->ve == NULL)
  110. {
  111. s->ve = (skeleton_vertex *) malloc (sizeof (skeleton_vertex));
  112. a2ri_erreur_critique_si (s->ve == NULL,
  113. "erreur allocation memoire pour s->ve\na2ri_skeleton_add_vertex");
  114. }
  115. else
  116. {
  117. skeleton_vertex *tempve;
  118. tempve =
  119. (skeleton_vertex *) realloc (s->ve, (s->nbvertex + 1) * sizeof (skeleton_vertex));
  120. a2ri_erreur_critique_si (tempve == NULL,
  121. "erreur allocation memoire pour s->ve\na2ri_skeleton_add_vertex");
  122. s->ve=tempve;
  123. }
  124. s->ve[s->nbvertex].x = x;
  125. s->ve[s->nbvertex].y = y;
  126. s->ve[s->nbvertex].z = z;
  127. s->ve[s->nbvertex].sharededges = NULL;
  128. s->ve[s->nbvertex].nbsharededges = 0;
  129. (s->nbvertex)++;
  130. return 1;
  131. }
  132. /**
  133. Ajout d'une arête défini par trois points (numéros d'index dans la liste de points) au squelette
  134. @param m pointeur sur le squelette
  135. @param ve1 index du premier point
  136. @param ve2 index du second point
  137. @return 1 si succès, 0 sinon
  138. */
  139. int a2ri_skeleton_add_edge (
  140. skeleton * s,
  141. int ve1,
  142. int ve2)
  143. {
  144. //allocation ou reallocatin de l'espace memoire
  145. if (s->ed == NULL)
  146. {
  147. s->ed = (skeleton_edge *) malloc (sizeof (skeleton_edge));
  148. a2ri_erreur_critique_si (s->ed == NULL,
  149. "erreur allocation memoire pour m->ed\na2ri_skeleton_add_edge");
  150. }
  151. else
  152. {
  153. skeleton_edge *temped;
  154. temped =
  155. (skeleton_edge *) realloc (s->ed, (s->nbedge + 1) * sizeof (skeleton_edge));
  156. a2ri_erreur_critique_si (temped == NULL,
  157. "erreur allocation memoire pour m->ed\na2ri_skeleton_add_vertex");
  158. s->ed=temped;
  159. }
  160. s->ed[s->nbedge].ve1 = ve1;
  161. s->ed[s->nbedge].ve2 = ve2;
  162. (s->nbedge)++;
  163. list_int_add (&(s->ve[ve1].sharededges),
  164. &(s->ve[ve1].nbsharededges),
  165. (s->nbedge) - 1, WITH_REDUNDANCE);
  166. list_int_add (&(s->ve[ve2].sharededges),
  167. &(s->ve[ve2].nbsharededges),
  168. (s->nbedge) - 1, WITH_REDUNDANCE);
  169. return 1;
  170. }
  171. /**
  172. Translation du squelette
  173. @param m pointeur sur le squelette à translater
  174. @param delta pointeur sur le vecteur de translation
  175. @return aucun
  176. */
  177. void a2ri_skeleton_translate (
  178. skeleton * s,
  179. const vector3d * const delta)
  180. {
  181. //translation de tous les sommets
  182. for (int i = 0; i < s->nbvertex; i++)
  183. vef_vertex_translate (&(s->ve[i]), delta);
  184. }
  185. /**
  186. Rotation d'un squelette en radian autour de l'axe X
  187. @param v pointeur sur le squelette
  188. @param angle angle de rotation du squelette en radian
  189. @return aucun
  190. */
  191. void a2ri_skeleton_rotateX_radian (
  192. skeleton * s,
  193. double angle)
  194. {
  195. //rotation de tous les sommets
  196. for (int i = 0; i < s->nbvertex; i++)
  197. vef_vertex_rotateX_radian (&(s->ve[i]), angle);
  198. }
  199. /**
  200. Rotation d'un squelette en degré autour de l'axe X
  201. @param v pointeur sur le squelette
  202. @param angle angle de rotation du squelette en degré
  203. @return aucun
  204. */
  205. void a2ri_skeleton_rotateX_degre (
  206. skeleton * s,
  207. double angle)
  208. {
  209. //rotation de tous les sommets
  210. for (int i = 0; i < s->nbvertex; i++)
  211. vef_vertex_rotateX_degre (&(s->ve[i]), angle);
  212. }
  213. /**
  214. Rotation d'un squelette en radian suivant l'axe X de centre (cx,cy,cz)
  215. @param v pointeur sur le squelette
  216. @param angle angle de rotation du squelette en radian
  217. @param centre pointeur sur le point3d servant de centre à la rotation
  218. @return aucun
  219. */
  220. void a2ri_skeleton_rotateX_center_radian (
  221. skeleton * s,
  222. double angle,
  223. const point3d * const centre)
  224. {
  225. //rotation de tous les sommets
  226. for (int i = 0; i < s->nbvertex; i++)
  227. vef_vertex_rotateX_center_radian (&(s->ve[i]), angle, centre);
  228. }
  229. /**
  230. Rotation d'un squelette en degre suivant l'axe X de centre (cx,cy,cz)
  231. @param v pointeur sur le squelette
  232. @param angle angle de rotation du squelette en degre
  233. @param centre pointeur sur le point3d servant de centre à la rotation
  234. @return aucun
  235. */
  236. void a2ri_skeleton_rotateX_center_degre (
  237. skeleton * s,
  238. double angle,
  239. const point3d * const centre)
  240. {
  241. //rotation de tous les sommets
  242. for (int i = 0; i < s->nbvertex; i++)
  243. vef_vertex_rotateX_center_degre (&(s->ve[i]), angle, centre);
  244. }
  245. /**
  246. Rotation d'un squelette en radian autour de l'axe Y
  247. @param v pointeur sur le squelette
  248. @param angle angle de rotation du squelette en radian
  249. @return aucun
  250. */
  251. void a2ri_skeleton_rotateY_radian (
  252. skeleton * s,
  253. double angle)
  254. {
  255. //rotation de tous les sommets
  256. for (int i = 0; i < s->nbvertex; i++)
  257. vef_vertex_rotateY_radian (&(s->ve[i]), angle);
  258. }
  259. /**
  260. Rotation d'un squelette en degré autour de l'axe Y
  261. @param v pointeur sur le squelette
  262. @param angle angle de rotation du squelette en degré
  263. @return aucun
  264. */
  265. void a2ri_skeleton_rotateY_degre (
  266. skeleton * s,
  267. double angle)
  268. {
  269. //rotation de tous les sommets
  270. for (int i = 0; i < s->nbvertex; i++)
  271. vef_vertex_rotateY_degre (&(s->ve[i]), angle);
  272. }
  273. /**
  274. Rotation d'un squelette en radian suivant l'axe Y de centre (cx,cy,cz)
  275. @param v pointeur sur le squelette
  276. @param angle angle de rotation du squelette en radian
  277. @param centre pointeur sur le point3d servant de centre à la rotation
  278. @return aucun
  279. */
  280. void a2ri_skeleton_rotateY_center_radian (
  281. skeleton * s,
  282. double angle,
  283. const point3d * const centre)
  284. {
  285. //rotation de tous les sommets
  286. for (int i = 0; i < s->nbvertex; i++)
  287. vef_vertex_rotateY_center_radian (&(s->ve[i]), angle, centre);
  288. }
  289. /**
  290. Rotation d'un squelette en degre suivant l'axe Y de centre (cx,cy,cz)
  291. @param v pointeur sur le squelette
  292. @param angle angle de rotation du squelette en degre
  293. @param centre pointeur sur le point3d servant de centre à la rotation
  294. @return aucun
  295. */
  296. void a2ri_skeleton_rotateY_center_degre (
  297. skeleton * s,
  298. double angle,
  299. const point3d * const centre)
  300. {
  301. //rotation de tous les sommets
  302. for (int i = 0; i < s->nbvertex; i++)
  303. vef_vertex_rotateY_center_degre (&(s->ve[i]), angle, centre);
  304. }
  305. /**
  306. Rotation d'un squelette en radian autour de l'axe Z
  307. @param v pointeur sur le squelette
  308. @param angle angle de rotation du squelette en radian
  309. @return aucun
  310. */
  311. void a2ri_skeleton_rotateZ_radian (
  312. skeleton * s,
  313. double angle)
  314. {
  315. //rotation de tous les sommets
  316. for (int i = 0; i < s->nbvertex; i++)
  317. vef_vertex_rotateZ_radian (&(s->ve[i]), angle);
  318. }
  319. /**
  320. Rotation d'un squelette en degré autour de l'axe Z
  321. @param v pointeur sur le squelette
  322. @param angle angle de rotation du squelette en degré
  323. @return aucun
  324. */
  325. void a2ri_skeleton_rotateZ_degre (
  326. skeleton * s,
  327. double angle)
  328. {
  329. //rotation de tous les sommets
  330. for (int i = 0; i < s->nbvertex; i++)
  331. vef_vertex_rotateZ_degre (&(s->ve[i]), angle);
  332. }
  333. /**
  334. Rotation d'un squelette en radian suivant l'axe Z de centre (cx,cy,cz)
  335. @param v pointeur sur le squelette
  336. @param angle angle de rotation du squelette en radian
  337. @param centre pointeur sur le point3d servant de centre à la rotation
  338. @return aucun
  339. */
  340. void a2ri_skeleton_rotateZ_center_radian (
  341. skeleton * s,
  342. double angle,
  343. const point3d * const centre)
  344. {
  345. //rotation de tous les sommets
  346. for (int i = 0; i < s->nbvertex; i++)
  347. vef_vertex_rotateZ_center_radian (&(s->ve[i]), angle, centre);
  348. }
  349. /**
  350. Rotation d'un squelette en degre suivant l'axe Z de centre (cx,cy,cz)
  351. @param v pointeur sur le squelette
  352. @param angle angle de rotation du squelette en degre
  353. @param centre pointeur sur le point3d servant de centre à la rotation
  354. @return aucun
  355. */
  356. void a2ri_skeleton_rotateZ_center_degre (
  357. skeleton * s,
  358. double angle,
  359. const point3d * const centre)
  360. {
  361. //rotation de tous les sommets
  362. for (int i = 0; i < s->nbvertex; i++)
  363. vef_vertex_rotateZ_center_degre (&(s->ve[i]), angle, centre);
  364. }
  365. /**
  366. Rotation d'un squelette en degre suivant l'axe donnée
  367. @param m pointeur sur le squelette
  368. @param angle angle de rotation du squelette en degre
  369. @param axe l'axe de rotation
  370. @return aucun
  371. */
  372. void a2ri_skeleton_rotate_axe_radian (
  373. skeleton * s,
  374. double angle,
  375. const vector3d * const axe)
  376. {
  377. gsl_matrix *identity3,
  378. *A,
  379. *B,
  380. *M;
  381. double x = axe->dx;
  382. double y = axe->dy;
  383. double z = axe->dz;
  384. identity3 = gsl_matrix_alloc (3, 3);
  385. gsl_matrix_set_identity (identity3);
  386. A = gsl_matrix_alloc (3, 3);
  387. gsl_matrix_set (A, 0, 0, x * x);
  388. gsl_matrix_set (A, 0, 1, x * y);
  389. gsl_matrix_set (A, 0, 2, x * z);
  390. gsl_matrix_set (A, 1, 0, x * y);
  391. gsl_matrix_set (A, 1, 1, y * y);
  392. gsl_matrix_set (A, 1, 2, y * z);
  393. gsl_matrix_set (A, 2, 0, x * z);
  394. gsl_matrix_set (A, 2, 1, y * z);
  395. gsl_matrix_set (A, 2, 2, z * z);
  396. B = gsl_matrix_alloc (3, 3);
  397. gsl_matrix_set (B, 0, 0, 0);
  398. gsl_matrix_set (B, 0, 1, -z);
  399. gsl_matrix_set (B, 0, 2, y);
  400. gsl_matrix_set (B, 1, 0, z);
  401. gsl_matrix_set (B, 1, 1, 0);
  402. gsl_matrix_set (B, 1, 2, -x);
  403. gsl_matrix_set (B, 2, 0, -y);
  404. gsl_matrix_set (B, 2, 1, x);
  405. gsl_matrix_set (B, 2, 2, 0);
  406. M =
  407. matrix_add (matrix_add
  408. (matrix_mul_scale (identity3, cos (angle)),
  409. matrix_mul_scale (A, 1 - cos (angle))), matrix_mul_scale (B,
  410. sin
  411. (angle)));
  412. //rotation de tous les sommets
  413. for (int i = 0; i < s->nbvertex; i++)
  414. vef_vertex_rotate_axe_radian (&(s->ve[i]), M);
  415. }
  416. /**
  417. Ajout des points d'un skeleton dans une partition de l'espace
  418. @param m le squelette
  419. @param sp la partition de l'espace
  420. @return aucun
  421. */
  422. void a2ri_skeleton_space_partition (
  423. const skeleton * const s,
  424. space_partition * sp)
  425. {
  426. point3d p;
  427. for (int i = 0; i < s->nbvertex; i++)
  428. {
  429. point3d_init (&p, s->ve[i].x, s->ve[i].y, s->ve[i].z);
  430. p.att_int = i;
  431. space_partition_add_point (sp, &p);
  432. }
  433. }