xgraph.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include <stdlib.h>
  2. #include <grass/gis.h>
  3. #include <grass/raster.h>
  4. #include <grass/calc.h>
  5. /****************************************************************
  6. graph(x, x1,y1, x2,y2, ... xn,yn) returns y value based on graph
  7. described by the x,y pairs.
  8. ****************************************************************/
  9. int c_graph(int argc, int *argt)
  10. {
  11. int i;
  12. if (argc < 3)
  13. return E_ARG_LO;
  14. if (argc % 2 == 0)
  15. return E_ARG_NUM;
  16. for (i = 0; i <= argc; i++)
  17. argt[i] = DCELL_TYPE;
  18. return 0;
  19. }
  20. int f_graph(int argc, const int *argt, void **args)
  21. {
  22. DCELL **argz = (DCELL **) args;
  23. DCELL *res = argz[0];
  24. int n = (argc - 1) / 2;
  25. int i, j;
  26. if (argc < 3)
  27. return E_ARG_LO;
  28. if (argc % 2 == 0)
  29. return E_ARG_NUM;
  30. if (argt[0] != DCELL_TYPE)
  31. return E_RES_TYPE;
  32. for (i = 1; i <= argc; i++)
  33. if (argt[i] != DCELL_TYPE)
  34. return E_ARG_TYPE;
  35. for (i = 0; i < columns; i++) {
  36. #define X(j) (argz[2 + 2 * (j) + 0][i])
  37. #define Y(j) (argz[2 + 2 * (j) + 1][i])
  38. #define x (argz[1][i])
  39. if (IS_NULL_D(&x))
  40. goto null;
  41. for (j = 0; j < n; j++)
  42. if (IS_NULL_D(&X(j)))
  43. goto null;
  44. for (j = 0; j < n - 1; j++)
  45. if (X(j + 1) <= X(j))
  46. goto null;
  47. if (x <= X(0)) {
  48. if (IS_NULL_D(&Y(0)))
  49. goto null;
  50. res[i] = Y(0);
  51. continue;
  52. }
  53. if (x >= X(n - 1)) {
  54. if (IS_NULL_D(&Y(n - 1)))
  55. goto null;
  56. res[i] = Y(n - 1);
  57. continue;
  58. }
  59. for (j = 0; j < n - 1; j++) {
  60. if (x > X(j + 1))
  61. continue;
  62. if (IS_NULL_D(&Y(j)) || IS_NULL_D(&Y(j + 1)))
  63. goto null;
  64. res[i] =
  65. Y(j) + (x - X(j)) * (Y(j + 1) - Y(j)) / (X(j + 1) - X(j));
  66. break;
  67. }
  68. #undef X
  69. #undef Y
  70. #undef x
  71. continue;
  72. null:
  73. SET_NULL_D(&res[i]);
  74. }
  75. return 0;
  76. }
  77. int f_graph2(int argc, const int *argt, void **args)
  78. {
  79. DCELL **argz = (DCELL **) args;
  80. DCELL *res = argz[0];
  81. int n = (argc - 1) / 2;
  82. int i, j;
  83. if (argc < 3)
  84. return E_ARG_LO;
  85. if (argc % 2 == 0)
  86. return E_ARG_NUM;
  87. if (argt[0] != DCELL_TYPE)
  88. return E_RES_TYPE;
  89. for (i = 1; i <= argc; i++)
  90. if (argt[i] != DCELL_TYPE)
  91. return E_ARG_TYPE;
  92. for (i = 0; i < columns; i++) {
  93. #define X(j) (argz[2 + (j) + 0][i])
  94. #define Y(j) (argz[2 + (j) + n][i])
  95. #define x (argz[1][i])
  96. if (IS_NULL_D(&x))
  97. goto null;
  98. for (j = 0; j < n; j++)
  99. if (IS_NULL_D(&X(j)))
  100. goto null;
  101. for (j = 0; j < n - 1; j++)
  102. if (X(j + 1) <= X(j))
  103. goto null;
  104. if (x <= X(0)) {
  105. if (IS_NULL_D(&Y(0)))
  106. goto null;
  107. res[i] = Y(0);
  108. continue;
  109. }
  110. if (x >= X(n - 1)) {
  111. if (IS_NULL_D(&Y(n - 1)))
  112. goto null;
  113. res[i] = Y(n - 1);
  114. continue;
  115. }
  116. for (j = 0; j < n - 1; j++) {
  117. if (x > X(j + 1))
  118. continue;
  119. if (IS_NULL_D(&Y(j)) || IS_NULL_D(&Y(j + 1)))
  120. goto null;
  121. res[i] =
  122. Y(j) + (x - X(j)) * (Y(j + 1) - Y(j)) / (X(j + 1) - X(j));
  123. break;
  124. }
  125. #undef X
  126. #undef Y
  127. #undef x
  128. continue;
  129. null:
  130. SET_NULL_D(&res[i]);
  131. }
  132. return 0;
  133. }