You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

cIGraph_layout.c 8.0 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. #include "igraph.h"
  2. #include "ruby.h"
  3. #include "cIGraph.h"
  4. /* call-seq:
  5. * graph.layout_random -> IGraphMatrix
  6. *
  7. * Returns a random layout
  8. */
  9. VALUE cIGraph_layout_random(VALUE self){
  10. igraph_t *graph;
  11. igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
  12. Data_Get_Struct(self, igraph_t, graph);
  13. igraph_matrix_init(res,0,0);
  14. igraph_layout_random(graph,res);
  15. return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
  16. }
  17. /* call-seq:
  18. * graph.layout_circle -> IGraphMatrix
  19. *
  20. * Returns a layout with nodes laid out around a circle.
  21. */
  22. VALUE cIGraph_layout_circle(VALUE self){
  23. igraph_t *graph;
  24. igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
  25. Data_Get_Struct(self, igraph_t, graph);
  26. igraph_matrix_init(res,0,0);
  27. igraph_layout_circle(graph,res);
  28. return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
  29. }
  30. /* call-seq:
  31. * graph.layout_fruchterman_reingold -> IGraphMatrix
  32. *
  33. * Places the vertices on a plane according to the Fruchterman-Reingold
  34. * algorithm.
  35. *
  36. * This is a force-directed layout, see Fruchterman, T.M.J. and Reingold,
  37. * E.M.: Graph Drawing by Force-directed Placement. Software -- Practice and
  38. * Experience, 21/11, 1129--1164, 1991.
  39. */
  40. VALUE cIGraph_layout_fruchterman_reingold(VALUE self,
  41. VALUE niter,
  42. VALUE maxdelta,
  43. VALUE area,
  44. VALUE coolexp,
  45. VALUE repulserad,
  46. VALUE use_seed){
  47. igraph_t *graph;
  48. igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
  49. Data_Get_Struct(self, igraph_t, graph);
  50. igraph_matrix_init(res,0,0);
  51. igraph_layout_fruchterman_reingold(graph,res,
  52. NUM2INT(niter),
  53. NUM2DBL(maxdelta),
  54. NUM2DBL(area),
  55. NUM2DBL(coolexp),
  56. NUM2DBL(repulserad),
  57. use_seed == Qtrue ? 1: 0, NULL);
  58. return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
  59. }
  60. /* call-seq:
  61. * graph.layout_kamada_kawai -> IGraphMatrix
  62. *
  63. * Places the vertices on a plane according the Kamada-Kawai algorithm.
  64. *
  65. * This is a force directed layout, see Kamada, T. and Kawai, S.: An
  66. * Algorithm for Drawing General Undirected Graphs. Information Processing
  67. * Letters, 31/1, 7--15, 1989.
  68. */
  69. VALUE cIGraph_layout_kamada_kawai(VALUE self,
  70. VALUE niter,
  71. VALUE sigma,
  72. VALUE initemp,
  73. VALUE coolexp,
  74. VALUE kkconst){
  75. igraph_t *graph;
  76. igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
  77. Data_Get_Struct(self, igraph_t, graph);
  78. igraph_matrix_init(res,0,0);
  79. igraph_layout_kamada_kawai(graph,res,
  80. NUM2INT(niter),
  81. NUM2DBL(sigma),
  82. NUM2DBL(initemp),
  83. NUM2DBL(coolexp),
  84. NUM2DBL(kkconst),0);
  85. return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
  86. }
  87. /* call-seq:
  88. * graph.layout_reingold_tilford -> IGraphMatrix
  89. *
  90. * Reingold-Tilford layout for tree graphs
  91. *
  92. * Arranges the nodes in a tree where the given node is used as the root.
  93. * The tree is directed downwards and the parents are centered above its
  94. * children. For the exact algorithm, see:
  95. *
  96. * Reingold, E and Tilford, J: Tidier drawing of trees. IEEE Trans. Softw.
  97. * Eng., SE-7(2):223--228, 1981
  98. *
  99. * If the given graph is not a tree, a breadth-first search is executed
  100. * first to obtain a possible spanning tree.
  101. */
  102. VALUE cIGraph_layout_reingold_tilford(VALUE self,
  103. VALUE root){
  104. igraph_t *graph;
  105. igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
  106. Data_Get_Struct(self, igraph_t, graph);
  107. igraph_matrix_init(res,0,0);
  108. igraph_layout_reingold_tilford(graph,res,
  109. cIGraph_get_vertex_id(self, root));
  110. return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
  111. }
  112. /* call-seq:
  113. * graph.layout_reingold_tilford_circular -> IGraphMatrix
  114. *
  115. * Reingold-Tilford layout for tree graphs, drawn in a circular style
  116. *
  117. * Arranges the nodes in a tree where the given node is used as the root.
  118. * The tree is directed downwards and the parents are centered above its
  119. * children. For the exact algorithm, see:
  120. *
  121. * Reingold, E and Tilford, J: Tidier drawing of trees. IEEE Trans. Softw.
  122. * Eng., SE-7(2):223--228, 1981
  123. *
  124. * If the given graph is not a tree, a breadth-first search is executed
  125. * first to obtain a possible spanning tree.
  126. */
  127. VALUE cIGraph_layout_reingold_tilford_circular(VALUE self,
  128. VALUE root){
  129. igraph_t *graph;
  130. igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
  131. Data_Get_Struct(self, igraph_t, graph);
  132. igraph_matrix_init(res,0,0);
  133. igraph_layout_reingold_tilford_circular(graph,res,
  134. cIGraph_get_vertex_id(self, root));
  135. return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
  136. }
  137. /* call-seq:
  138. * graph.layout_grid_fruchterman_reingold -> IGraphMatrix
  139. *
  140. * Places the vertices on a plane according to the Fruchterman-Reingold
  141. * algorithm.
  142. *
  143. * This is a force-directed layout, see Fruchterman, T.M.J. and Reingold,
  144. * E.M.: Graph Drawing by Force-directed Placement. Software -- Practice and
  145. * Experience, 21/11, 1129--1164, 1991.
  146. */
  147. VALUE cIGraph_layout_grid_fruchterman_reingold(VALUE self,
  148. VALUE niter,
  149. VALUE maxdelta,
  150. VALUE area,
  151. VALUE coolexp,
  152. VALUE repulserad,
  153. VALUE cellsize,
  154. VALUE use_seed){
  155. igraph_t *graph;
  156. igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
  157. Data_Get_Struct(self, igraph_t, graph);
  158. igraph_matrix_init(res,0,0);
  159. igraph_layout_grid_fruchterman_reingold(graph,res,
  160. NUM2INT(niter),
  161. NUM2DBL(maxdelta),
  162. NUM2DBL(area),
  163. NUM2DBL(coolexp),
  164. NUM2DBL(repulserad),
  165. NUM2DBL(cellsize),
  166. use_seed == Qtrue ? 1: 0);
  167. return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
  168. }
  169. /* call-seq:
  170. * graph.layout_lgl -> IGraphMatrix
  171. *
  172. * Places the vertices on a plane according to the Fruchterman-Reingold
  173. * algorithm.
  174. *
  175. * This is a force-directed layout, see Fruchterman, T.M.J. and Reingold,
  176. * E.M.: Graph Drawing by Force-directed Placement. Software -- Practice and
  177. * Experience, 21/11, 1129--1164, 1991.
  178. */
  179. VALUE cIGraph_layout_lgl(VALUE self,
  180. VALUE maxit,
  181. VALUE maxdelta,
  182. VALUE area,
  183. VALUE coolexp,
  184. VALUE repulserad,
  185. VALUE cellsize,
  186. VALUE proot){
  187. igraph_t *graph;
  188. igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
  189. Data_Get_Struct(self, igraph_t, graph);
  190. igraph_matrix_init(res,0,0);
  191. igraph_layout_lgl(graph,res,
  192. NUM2INT(maxit),
  193. NUM2DBL(maxdelta),
  194. NUM2DBL(area),
  195. NUM2DBL(coolexp),
  196. NUM2DBL(repulserad),
  197. NUM2DBL(cellsize),
  198. cIGraph_get_vertex_id(self, proot));
  199. return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
  200. }
  201. /* call-seq:
  202. * graph.layout_merge_dla(graphs,layouts) -> IGraphMatrix
  203. *
  204. * Merge multiple layouts by using a DLA algorithm
  205. *
  206. * First each layout is covered by a circle. Then the layout of the largest
  207. * graph is placed at the origin. Then the other layouts are placed by the
  208. * DLA algorithm, larger ones first and smaller ones last.
  209. *
  210. * graphs: Array of IGraph objects
  211. *
  212. * layouts: Array of IGraphMatrix layouts
  213. */
  214. VALUE cIGraph_layout_merge_dla(VALUE self, VALUE graphs, VALUE layouts){
  215. igraph_vector_ptr_t thegraphs;
  216. igraph_vector_ptr_t coords;
  217. int i;
  218. igraph_t *graph;
  219. igraph_matrix_t *coord;
  220. igraph_matrix_t *res = malloc(sizeof(igraph_matrix_t));
  221. igraph_vector_ptr_init(&thegraphs,0);
  222. igraph_vector_ptr_init(&coords,0);
  223. igraph_matrix_init(res,0,0);
  224. for(i=0;i<RARRAY_LEN(graphs);i++){
  225. Data_Get_Struct(RARRAY_PTR(graphs)[i], igraph_t, graph);
  226. igraph_vector_ptr_push_back(&thegraphs,graph);
  227. }
  228. for(i=0;i<RARRAY_LEN(layouts);i++){
  229. Data_Get_Struct(RARRAY_PTR(layouts)[i], igraph_matrix_t, coord);
  230. igraph_vector_ptr_push_back(&coords,coord);
  231. }
  232. igraph_layout_merge_dla(&thegraphs, &coords, res);
  233. igraph_vector_ptr_destroy(&thegraphs);
  234. igraph_vector_ptr_destroy(&coords);
  235. return Data_Wrap_Struct(cIGraphMatrix, 0, cIGraph_matrix_free, res);
  236. }