GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
xgraph.c
Go to the documentation of this file.
1 
2 #include <stdlib.h>
3 
4 #include <grass/gis.h>
5 #include <grass/raster.h>
6 #include <grass/calc.h>
7 
8 /****************************************************************
9 graph(x, x1,y1, x2,y2, ... xn,yn) returns y value based on graph
10 described by the x,y pairs.
11 ****************************************************************/
12 
13 int c_graph(int argc, int *argt)
14 {
15  int i;
16 
17  if (argc < 3)
18  return E_ARG_LO;
19 
20  if (argc % 2 == 0)
21  return E_ARG_NUM;
22 
23  for (i = 0; i <= argc; i++)
24  argt[i] = DCELL_TYPE;
25 
26  return 0;
27 }
28 
29 int f_graph(int argc, const int *argt, void **args)
30 {
31  DCELL **argz = (DCELL **) args;
32  DCELL *res = argz[0];
33  int n = (argc - 1) / 2;
34  int i, j;
35 
36  if (argc < 3)
37  return E_ARG_LO;
38 
39  if (argc % 2 == 0)
40  return E_ARG_NUM;
41 
42  if (argt[0] != DCELL_TYPE)
43  return E_RES_TYPE;
44 
45  for (i = 1; i <= argc; i++)
46  if (argt[i] != DCELL_TYPE)
47  return E_ARG_TYPE;
48 
49  for (i = 0; i < columns; i++) {
50 #define X(j) (argz[2 + 2 * (j) + 0][i])
51 #define Y(j) (argz[2 + 2 * (j) + 1][i])
52 #define x (argz[1][i])
53 
54  if (IS_NULL_D(&x))
55  goto null;
56 
57  for (j = 0; j < n; j++)
58  if (IS_NULL_D(&X(j)))
59  goto null;
60 
61  for (j = 0; j < n - 1; j++)
62  if (X(j + 1) <= X(j))
63  goto null;
64 
65  if (x <= X(0)) {
66  if (IS_NULL_D(&Y(0)))
67  goto null;
68  res[i] = Y(0);
69  continue;
70  }
71 
72  if (x >= X(n - 1)) {
73  if (IS_NULL_D(&Y(n - 1)))
74  goto null;
75  res[i] = Y(n - 1);
76  continue;
77  }
78 
79  for (j = 0; j < n - 1; j++) {
80  if (x > X(j + 1))
81  continue;
82 
83  if (IS_NULL_D(&Y(j)) || IS_NULL_D(&Y(j + 1)))
84  goto null;
85 
86  res[i] =
87  Y(j) + (x - X(j)) * (Y(j + 1) - Y(j)) / (X(j + 1) - X(j));
88 
89  break;
90  }
91 #undef X
92 #undef Y
93 #undef x
94 
95  continue;
96 
97  null:
98  SET_NULL_D(&res[i]);
99  }
100 
101  return 0;
102 }
103 
104 int f_graph2(int argc, const int *argt, void **args)
105 {
106  DCELL **argz = (DCELL **) args;
107  DCELL *res = argz[0];
108  int n = (argc - 1) / 2;
109  int i, j;
110 
111  if (argc < 3)
112  return E_ARG_LO;
113 
114  if (argc % 2 == 0)
115  return E_ARG_NUM;
116 
117  if (argt[0] != DCELL_TYPE)
118  return E_RES_TYPE;
119 
120  for (i = 1; i <= argc; i++)
121  if (argt[i] != DCELL_TYPE)
122  return E_ARG_TYPE;
123 
124  for (i = 0; i < columns; i++) {
125 #define X(j) (argz[2 + (j) + 0][i])
126 #define Y(j) (argz[2 + (j) + n][i])
127 #define x (argz[1][i])
128 
129  if (IS_NULL_D(&x))
130  goto null;
131 
132  for (j = 0; j < n; j++)
133  if (IS_NULL_D(&X(j)))
134  goto null;
135 
136  for (j = 0; j < n - 1; j++)
137  if (X(j + 1) <= X(j))
138  goto null;
139 
140  if (x <= X(0)) {
141  if (IS_NULL_D(&Y(0)))
142  goto null;
143  res[i] = Y(0);
144  continue;
145  }
146 
147  if (x >= X(n - 1)) {
148  if (IS_NULL_D(&Y(n - 1)))
149  goto null;
150  res[i] = Y(n - 1);
151  continue;
152  }
153 
154  for (j = 0; j < n - 1; j++) {
155  if (x > X(j + 1))
156  continue;
157 
158  if (IS_NULL_D(&Y(j)) || IS_NULL_D(&Y(j + 1)))
159  goto null;
160 
161  res[i] =
162  Y(j) + (x - X(j)) * (Y(j + 1) - Y(j)) / (X(j + 1) - X(j));
163 
164  break;
165  }
166 #undef X
167 #undef Y
168 #undef x
169 
170  continue;
171 
172  null:
173  SET_NULL_D(&res[i]);
174  }
175 
176  return 0;
177 }
178 
int f_graph2(int argc, const int *argt, void **args)
Definition: xgraph.c:104
double DCELL
Definition: gis.h:614
#define Y(j)
#define X(j)
#define x
int columns
Definition: calc.c:12
int c_graph(int argc, int *argt)
Definition: xgraph.c:13
#define DCELL_TYPE
Definition: raster.h:13
int f_graph(int argc, const int *argt, void **args)
Definition: xgraph.c:29
Definition: calc.h:12
#define IS_NULL_D(x)
Definition: calc.h:30
#define SET_NULL_D(x)
Definition: calc.h:34
Definition: calc.h:17