packing.c~ 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include "packing.h"
  5. // read file and set node values
  6. Node *load_file(char *filename){
  7. // open file for reading
  8. FILE *fptr = NULL;
  9. fptr = fopen(filename, "r");
  10. if (fptr == NULL){ // check for error
  11. printf("File name error.\n");
  12. return NULL;
  13. }
  14. // initialize variables and pointers
  15. Stack *stack = NULL; // used to store nodes and determine their order
  16. char curr = 0;
  17. // read values for each node
  18. while(!feof(fptr)){
  19. if(fscanf(fptr, "%c", &curr) == EOF){}
  20. else{
  21. Node *node = malloc(sizeof(Node));
  22. // check if parent or child node
  23. if(curr == '('){
  24. // child node
  25. // read values
  26. if(fscanf(fptr, "%le,%le)", &node->width, &node->height) == EOF){
  27. printf("Error reading file.\n");
  28. free(node);
  29. return NULL;
  30. }
  31. // initialize remaining values
  32. node->cutline = '-';
  33. node->xcord = 0;
  34. node->ycord = 0;
  35. node->left = NULL;
  36. node->right = NULL;
  37. }
  38. else{
  39. // parent node
  40. // initialize values
  41. node->cutline = curr; // already read
  42. node->width = '-';
  43. node->height = '-';
  44. node->xcord = 0;
  45. node->ycord = 0;
  46. node->right = pop(stack);
  47. node->left = pop(stack);
  48. }
  49. push(stack, node);
  50. }
  51. Node *root = pop(stack);
  52. // clean up
  53. if(!fclose(fptr) == 0){
  54. printf("File close error.");
  55. return NULL;
  56. }
  57. return root;
  58. }
  59. void push(Stack *stack, Node *node){
  60. Stack *new = malloc(sizeof(Stack));
  61. new->node = node;
  62. new->next = stack;
  63. }
  64. Node *pop(Stack *stack){
  65. if(stack == NULL){
  66. return NULL;
  67. }
  68. Node *temp = stack->node;
  69. free(stack);
  70. return temp;
  71. }
  72. void free_stack(Stack *stack)
  73. {
  74. Stack *temp = NULL;
  75. while(stack != NULL){
  76. free(stack->node);
  77. temp = stack;
  78. stack = stack->next;
  79. free(temp);
  80. }
  81. }
  82. // calculate dimensions based on binary tree structure
  83. void set_dimensions(Node *root){
  84. // end recursion
  85. if(root->left == NULL && root->right == NULL){
  86. return;
  87. }
  88. // recurse
  89. set_dimensions(root->left);
  90. set_dimensions(root->right);
  91. if(root->cutline == 'V'){
  92. // add widths for vertzical cut
  93. root->width = root->left->width + root->right->width;
  94. if(root->left->height >= root->right->height){
  95. root->height = root->left->height;
  96. }
  97. else{
  98. root->height = root->right->height;
  99. }
  100. }
  101. if(root->cutline == 'H'){
  102. // add heights for horizontal cut
  103. root->height = root->left->height + root->right->height;
  104. if(root->left->width >= root->right->width){
  105. root->width = root->left->width;
  106. }
  107. else{
  108. root->width = root->right->width;
  109. }
  110. }
  111. }
  112. // calculate coordinates based on binary tree structure
  113. void set_coordinates(Node *root){
  114. // end recursion
  115. if(root->left == NULL && root->right == NULL){
  116. return;
  117. }
  118. if(root->cutline == 'V'){
  119. // left stays, right moves
  120. root->left->xcord = root->xcord;
  121. root->left->ycord = root->ycord;
  122. root->right->xcord = root->xcord + root->left->width;
  123. root->right->ycord = root->ycord;
  124. }
  125. if(root->cutline == 'H'){
  126. // right stays, left moves
  127. root->left->xcord = root->xcord;
  128. root->left->ycord = root->ycord + root->right->height;;
  129. root->right->xcord = root->xcord;
  130. root->right->ycord = root->ycord;
  131. }
  132. // recurse
  133. set_coordinates(root->left);
  134. set_coordinates(root->right);
  135. }
  136. // recursively reroot tree
  137. void find_best_fit(Node *root, double *best_width, double *best_height){
  138. if(root == NULL){
  139. return;
  140. }
  141. set_dimensions(root);
  142. set_coordinates(root);
  143. if((((*best_width * *best_height) < (root->width * root->height))
  144. || (((*best_width * *best_height) == (root->width * root->height)
  145. && (*best_width < root->width)))) && root->cutline != '-'){
  146. *best_width = root->width;
  147. *best_height = root->height;
  148. }
  149. find_best_fit(root->left, best_width, best_height);
  150. find_best_fit(root->right, best_width, best_height);
  151. }
  152. // print nodes
  153. void print_nodes_preorder(Node *root){
  154. if(root == NULL){
  155. return;
  156. }
  157. if(root->cutline == '-'){
  158. printf("(%le,%le)", root->width, root->height);
  159. }
  160. else{
  161. printf("%c", root->cutline);
  162. }
  163. print_nodes_preorder(root->left);
  164. print_nodes_preorder(root->right);
  165. }
  166. void print_nodes_inorder(Node *root){
  167. if(root == NULL){
  168. return;
  169. }
  170. print_nodes_inorder(root->left);
  171. if(root->cutline == '-'){
  172. printf("(%le,%le)", root->width, root->height);
  173. }
  174. else{
  175. printf("%c", root->cutline);
  176. }
  177. print_nodes_inorder(root->right);
  178. }
  179. void print_nodes_postorder(Node *root){
  180. if(root == NULL){
  181. return;
  182. }
  183. print_nodes_postorder(root->left);
  184. print_nodes_postorder(root->right);
  185. if(root->cutline == '-'){
  186. printf("(%le,%le)", root->width, root->height);
  187. }
  188. else{
  189. printf("%c", root->cutline);
  190. }
  191. }
  192. // recurse through tree and save each node that represents a box
  193. void save_boxes(char *filename, Node *root){
  194. // end recursion
  195. if(root == NULL){
  196. return;
  197. }
  198. // write to file
  199. FILE *fptr = fopen(filename, "w");
  200. if(root->cutline == '-'){
  201. fprintf(fptr, "%le %le %le %le\n",
  202. root->width,
  203. root->height,
  204. root->xcord,
  205. root->ycord);
  206. }
  207. // close file
  208. if(!fclose(fptr) == 0){
  209. printf("File close error.");
  210. return;
  211. }
  212. save_boxes(filename, root->left);
  213. save_boxes(filename, root->right);
  214. }
  215. // recursively free tree from memory
  216. void free_tree(Node *root){
  217. // end recursion
  218. if(root == NULL){
  219. return;
  220. }
  221. // recurse
  222. free_tree(root->left);
  223. free_tree(root->right);
  224. // clean up
  225. free(root);
  226. }