/branches/cygwin/src/graphics/qplot.c

# · C · 249 lines · 211 code · 29 blank · 9 comment · 57 complexity · ffb10b6e094d37fcc953480e6ba6cbed MD5 · raw file

  1. /*
  2. * $Id: qplot.c 1221 2000-10-17 02:41:15Z gcw $
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <math.h>
  7. #include <signal.h>
  8. #include "grxlib.h"
  9. #define Real float
  10. #ifndef GRX_SCALE
  11. # define GRX_SCALE 10000
  12. #endif
  13. #define DEFAULT_DATA_FILE "data"
  14. static void
  15. axis_round(Real * min, Real * max, Real * grid_spacing)
  16. {
  17. int logspace;
  18. logspace = (int)(log10((*max - *min) / 10.0) + 0.5);
  19. *grid_spacing = pow(10, (double)logspace);
  20. *min = (Real) ((int)(*min / (*grid_spacing))) * (*grid_spacing);
  21. *max = (Real) ((int)(*max / (*grid_spacing)) + 1) * (*grid_spacing);
  22. }
  23. static int
  24. nice_end(int junk)
  25. {
  26. CloseGraphics();
  27. putchar('\n');
  28. exit(EXIT_SUCCESS);
  29. return 0;
  30. }
  31. int
  32. main(int argc, char **argv)
  33. {
  34. char *file = NULL;
  35. int Do_Start = 1, tmp;
  36. int m, p, i, j, n, nchars, theight, twidth, xclick, yclick;
  37. int downx = 1000, downy = 1000, upx, upy;
  38. long id, winclick;
  39. Real xmax, xmin, ymax, ymin, xdiff, ydiff, xgrid_spacing,
  40. ygrid_spacing;
  41. Real *x, *y, *nls;
  42. LineFunction linetype = StartLine;
  43. char axis[100], line[256];
  44. FILE *fd;
  45. x = (Real *)malloc(1000000 * sizeof(Real));
  46. y = (Real *)malloc(1000000 * sizeof(Real));
  47. nls = (Real *)malloc(1000 * sizeof(Real));
  48. if (x == NULL || y == NULL || nls == NULL) {
  49. fprintf(stderr, "Can't allocate initial memory\n");
  50. exit(1);
  51. }
  52. ymax = xmax = -HUGE_VAL;
  53. ymin = xmin = HUGE_VAL;
  54. for (i = 1; i < argc; i++) {
  55. if (*argv[i] == '-') {
  56. if (!strcmp(argv[i], "-nl"))
  57. linetype = StartPoint;
  58. else if (argv[i][1] == '\0') /* use stdin */
  59. file = argv[i];
  60. else {
  61. fprintf(stderr, "Usage:\n\t %s [options] [file]\n\n", argv[0]);
  62. fprintf(stderr,
  63. "where options include:\n"
  64. " -pt plot with points instead of lines\n\n");
  65. fprintf(stderr,
  66. "file name `-' specifies stdin\n"
  67. "if no file name is specified, "
  68. "the default is \"%s\"\n\n", DEFAULT_DATA_FILE);
  69. return EXIT_FAILURE;
  70. }
  71. } else
  72. file = argv[i];
  73. }
  74. if (file && !strcmp(file, "-")) {
  75. fd = stdin;
  76. file = "stdin";
  77. } else {
  78. if (file == NULL)
  79. file = DEFAULT_DATA_FILE;
  80. if ((fd = fopen(file, "r")) == NULL) {
  81. fprintf(stderr, "%s: can't open file \"%s\"\n", argv[0], file);
  82. return EXIT_FAILURE;
  83. }
  84. }
  85. m = 0;
  86. p = 0;
  87. while (fgets(line, sizeof(line), fd) != NULL) {
  88. if (sscanf(line, "%f %f", &x[m], &y[m]) == 2) {
  89. if (x[m] > xmax)
  90. xmax = x[m];
  91. else if (x[m] < xmin)
  92. xmin = x[m];
  93. if (y[m] > ymax)
  94. ymax = y[m];
  95. else if (y[m] < ymin)
  96. ymin = y[m];
  97. m++;
  98. } else {
  99. nls[p] = m;
  100. p++;
  101. }
  102. }
  103. nls[p++] = m;
  104. if (m == 0)
  105. return;
  106. signal(SIGTERM, nice_end);
  107. signal(SIGSTOP, nice_end);
  108. signal(SIGTSTP, nice_end);
  109. signal(SIGINT, nice_end);
  110. signal(SIGQUIT, nice_end);
  111. if (!InitializeGraphics(1))
  112. return EXIT_FAILURE;
  113. n = 1;
  114. do {
  115. axis_round(&xmin, &xmax, &xgrid_spacing);
  116. axis_round(&ymin, &ymax, &ygrid_spacing);
  117. id = CreateWin(0, 0, GRX_SCALE, GRX_SCALE);
  118. if (id == 0) {
  119. fprintf(stderr, "Help id = 0\n");
  120. return EXIT_FAILURE;
  121. }
  122. /* Fill the window in black for real eye-catching graphics! */
  123. ForeColor(0);
  124. StartFill(id);
  125. FillArea(0, 0, GRX_SCALE, GRX_SCALE);
  126. Done();
  127. /* draw outline box in white */
  128. ForeColor(7);
  129. /* Draw outline box */
  130. StartLine(id);
  131. Extend(1000, 1000);
  132. Extend(1000, 9000);
  133. Extend(9000, 9000);
  134. Extend(9000, 1000);
  135. Extend(1000, 1000);
  136. Done();
  137. /* Draw the data - either lines or dots */
  138. xdiff = 8000 / (xmax - xmin);
  139. ydiff = 8000 / (ymax - ymin);
  140. for (i = j = 0; j < p; j++) {
  141. int n = 0;
  142. ForeColor(j % 6 + 1);
  143. while (((x[i] < xmin) || (x[i] > xmax) ||
  144. (y[i] < ymin) || (y[i] > ymax)) && (i < nls[j]))
  145. i++;
  146. while (i < nls[j]) {
  147. if (n == 0)
  148. linetype(id);
  149. Extend(1000 + (x[i] - xmin) * xdiff,
  150. 9000 - (y[i] - ymin) * ydiff);
  151. n++;
  152. if (n > 450) {
  153. Done();
  154. n = 0;
  155. continue;
  156. }
  157. i++;
  158. while ((i < nls[j]) &&
  159. ((x[i] < xmin) || (x[i] > xmax) ||
  160. (y[i] < ymin) || (y[i] > ymax)))
  161. i++;
  162. }
  163. if (n > 0)
  164. Done();
  165. }
  166. /* Do axis labels in black */
  167. ForeColor(7);
  168. QueryWin(id, &twidth, &theight);
  169. PlaceText(id, GRX_SCALE / 2, 0, HCENTER_TEXT | TOP_TEXT, file);
  170. PlaceText(id, GRX_SCALE / 2, GRX_SCALE, HCENTER_TEXT | BOTTOM_TEXT,
  171. "X");
  172. PlaceText(id, 0, GRX_SCALE / 2, LEFT_TEXT | VCENTER_TEXT, "Y");
  173. sprintf(axis, "%f", ymax);
  174. nchars = 1000 / twidth;
  175. axis[nchars] = 0;
  176. PlaceText(id, GRX_SCALE / 10, GRX_SCALE / 10,
  177. RIGHT_TEXT | TOP_TEXT, axis);
  178. sprintf(axis, "%f", ymin);
  179. axis[nchars] = 0;
  180. PlaceText(id, GRX_SCALE / 10, 9 * GRX_SCALE / 10,
  181. RIGHT_TEXT | BOTTOM_TEXT, axis);
  182. sprintf(axis, "%f", xmax);
  183. PlaceText(id, 9 * GRX_SCALE / 10, 9 * GRX_SCALE / 10,
  184. HCENTER_TEXT | TOP_TEXT, axis);
  185. sprintf(axis, "%f", xmin);
  186. PlaceText(id, GRX_SCALE / 10, 9 * GRX_SCALE / 10,
  187. HCENTER_TEXT | TOP_TEXT, axis);
  188. fflush(stdout);
  189. do {
  190. n = WaitForCarriageReturn(&winclick, &xclick, &yclick);
  191. switch (n) {
  192. case 1:
  193. downx = xclick;
  194. downy = yclick;
  195. break;
  196. case 2:
  197. upx = xclick;
  198. upy = yclick;
  199. if (upx < downx) {
  200. tmp = downx;
  201. downx = upx;
  202. upx = tmp;
  203. }
  204. if (upy < downy) {
  205. tmp = downy;
  206. downy = upy;
  207. upy = tmp;
  208. }
  209. xmin = (xmax - xmin) * (downx - 1000) / (8000) + xmin;
  210. xmax = (xmax - xmin) * (upx - 1000) / (8000) + xmin;
  211. ymax = ymax - (ymax - ymin) * (downy - 1000) / (8000);
  212. ymin = ymax - (ymax - ymin) * (upy - 1000) / (8000);
  213. break;
  214. }
  215. } while (n && (n != 2));
  216. } while (n);
  217. nice_end(EXIT_SUCCESS);
  218. return EXIT_SUCCESS;
  219. }
  220. /*----------------------- end-of-file (C source) -----------------------*/