Graphics_surface.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /* Graphics_surface.cpp
  2. *
  3. * Copyright (C) 1992-2011,2017 Paul Boersma
  4. *
  5. * This code is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This code is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. * See the GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "Graphics.h"
  19. void Graphics_surface (Graphics me, double **z,
  20. integer ix1, integer ix2, double x1, double x2,
  21. integer iy1, integer iy2, double y1, double y2,
  22. double minimum, double maximum,
  23. double elevation, double azimuth)
  24. {
  25. double dx, dy;
  26. /* 'sum' is the running sum of the x and y indices of the back corner of each tetragon.
  27. * The x and y indices of the back corner of the backmost tetragon are ix2 and iy2,
  28. * The x and y indices of the front corner of the frontmost tetragon are ix1 and iy1,
  29. * so that the x and y indices of its back corner are ix1 + 1 and iy1 + 1.
  30. */
  31. integer maxsum = ix2 + iy2, minsum = (ix1 + 1) + (iy1 + 1), sum;
  32. (void) elevation; /* BUG */
  33. (void) azimuth; /* BUG */
  34. if (ix2 <= ix1 || iy2 <= iy1) return;
  35. dx = (x2 - x1) / (ix2 - ix1);
  36. dy = (y2 - y1) / (iy2 - iy1);
  37. /* We start at the back of the surface plot.
  38. * This part of the picture may be overdrawn by points more forward.
  39. */
  40. for (sum = maxsum; sum >= minsum; sum --) {
  41. /* We are going to cycle over a diagonal sequence of points.
  42. * Compute the row boundaries of this sequence.
  43. */
  44. integer iymin = iy1 + 1, iymax = iy2, iy;
  45. if (iymin < sum - ix2) iymin = sum - ix2;
  46. if (iymax > sum - (ix1 + 1)) iymax = sum - (ix1 + 1);
  47. for (iy = iymin; iy <= iymax; iy ++) {
  48. /* Compute the indices of all four points.
  49. */
  50. integer ix = sum - iy;
  51. integer ixback = ix, ixfront = ix - 1, ixleft = ix - 1, ixright = ix;
  52. integer iyback = iy, iyfront = iy - 1, iyleft = iy, iyright = iy - 1;
  53. /* Compute the world coordinates of all four points.
  54. */
  55. double xback = x1 + (ixback - ix1) * dx, xright = xback;
  56. double xfront = x1 + (ixfront - ix1) * dx, xleft = xfront;
  57. double yback = y1 + (iyback - iy1) * dy, yleft = yback;
  58. double yfront = y1 + (iyfront - iy1) * dy, yright = yfront;
  59. double zback = z [iyback] [ixback], zfront = z [iyfront] [ixfront];
  60. double zleft = z [iyleft] [ixleft], zright = z [iyright] [ixright];
  61. /* The Graphics library uses a two-dimensional world, so we have to convert
  62. * to 2-D world coordinates, which we call x [0..3] and y [0..3].
  63. * We suppose that world coordinate "x" = 0 is in the centre of the figure,
  64. * and that the left and right borders of the figure have world coordinates -1 and +1.
  65. * Also, we suppose that the bottom and top are around 'minimum' and 'maximum'.
  66. */
  67. double x [5], y [5];
  68. /* Elevation and azimuth fixed???
  69. */
  70. double up = 0.3 * (maximum - minimum), xscale = 1 / (x2 - x1), yscale = 1 / (y2 - y1);
  71. /* The back point.
  72. */
  73. x [0] = (xback - x1) * xscale - (yback - y1) * yscale;
  74. y [0] = up * ((xback - x1) * xscale + (yback - y1) * yscale) + zback;
  75. /* The right point.
  76. */
  77. x [1] = (xright - x1) * xscale - (yright - y1) * yscale;
  78. y [1] = up * ((xright - x1) * xscale + (yright - y1) * yscale) + zright;
  79. /* The front point.
  80. */
  81. x [2] = (xfront - x1) * xscale - (yfront - y1) * yscale;
  82. y [2] = up * ((xfront - x1) * xscale + (yfront - y1) * yscale) + zfront;
  83. /* The left point.
  84. */
  85. x [3] = (xleft - x1) * xscale - (yleft - y1) * yscale;
  86. y [3] = up * ((xleft - x1) * xscale + (yleft - y1) * yscale) + zleft;
  87. /* Paint the tetragon in the average grey value, white at the top.
  88. * This gives the idea of height.
  89. */
  90. Graphics_setGrey (me, (0.25 * (zback + zright + zfront + zleft) - minimum) / (maximum - minimum));
  91. Graphics_fillArea (me, 4, & x [0], & y [0]);
  92. /* Draw the borders of the tetragon in black.
  93. * This gives the idea of steepness and viewing angle.
  94. */
  95. Graphics_setGrey (me, 0);
  96. x [4] = x [0]; y [4] = y [0]; /* Close polygon. */
  97. Graphics_polyline (me, 5, & x [0], & y [0]);
  98. }
  99. }
  100. }
  101. /* End of file Graphics_surface.cpp */