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