tioga 1.6 → 1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Tioga_README +35 -10
- data/split/Dvector/dvector.c +264 -22
- data/split/Dvector/lib/Dvector_extras.rb +30 -2
- data/split/Flate/extconf.rb +1 -1
- data/split/Function/function.c +112 -2
- data/split/Tioga/figures.c +76 -77
- data/split/Tioga/figures.h +375 -490
- data/split/Tioga/generic.c +254 -0
- data/split/Tioga/generic.h +236 -0
- data/split/Tioga/init.c +434 -320
- data/split/Tioga/lib/Creating_Paths.rb +11 -1
- data/split/Tioga/lib/FigMkr.rb +263 -65
- data/split/Tioga/lib/Legends.rb +4 -2
- data/split/Tioga/lib/Markers.rb +3 -2
- data/split/Tioga/lib/Special_Paths.rb +22 -23
- data/split/Tioga/lib/TeX_Text.rb +79 -1
- data/split/Tioga/lib/TexPreamble.rb +14 -0
- data/split/Tioga/lib/Utils.rb +5 -1
- data/split/Tioga/pdfs.h +7 -45
- data/split/Tioga/{axes.c → shared/axes.c} +210 -197
- data/split/Tioga/{makers.c → shared/makers.c} +442 -211
- data/split/Tioga/{pdf_font_dicts.c → shared/pdf_font_dicts.c} +0 -0
- data/split/Tioga/shared/pdfcolor.c +628 -0
- data/split/Tioga/shared/pdfcoords.c +443 -0
- data/split/Tioga/{pdffile.c → shared/pdffile.c} +56 -52
- data/split/Tioga/{pdfimage.c → shared/pdfimage.c} +103 -211
- data/split/Tioga/shared/pdfpath.c +766 -0
- data/split/Tioga/{pdftext.c → shared/pdftext.c} +121 -99
- data/split/Tioga/shared/texout.c +524 -0
- data/split/Tioga/wrappers.c +489 -0
- data/split/Tioga/wrappers.h +259 -0
- data/split/extconf.rb +4 -0
- data/split/mkmf2.rb +12 -1
- data/tests/benchmark_dvector_reads.rb +112 -0
- data/tests/tc_Dvector.rb +35 -3
- data/tests/tc_Function.rb +32 -0
- metadata +65 -52
- data/split/Tioga/pdfcolor.c +0 -486
- data/split/Tioga/pdfcoords.c +0 -523
- data/split/Tioga/pdfpath.c +0 -913
- data/split/Tioga/texout.c +0 -380
@@ -1,6 +1,7 @@
|
|
1
1
|
/* makers.c */
|
2
2
|
/*
|
3
3
|
Copyright (C) 2005 Bill Paxton
|
4
|
+
Copyright (C) 2007 Taro Sato
|
4
5
|
|
5
6
|
This file is part of Tioga.
|
6
7
|
|
@@ -20,101 +21,233 @@
|
|
20
21
|
*/
|
21
22
|
|
22
23
|
#include "figures.h"
|
24
|
+
#include "generic.h"
|
23
25
|
|
24
26
|
|
25
27
|
/* Lines */
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
free(Ds); free(Cs); free(Bs);
|
51
|
-
USE_P
|
29
|
+
static void create_spline_interpolant(int n_pts_data, double *Xs, double *Ys,
|
30
|
+
bool start_clamped, double start_slope, bool end_clamped, double end_slope,
|
31
|
+
double *As, double *Bs, double *Cs)
|
32
|
+
// this is copied from dvector so that makers.c won't depend on dvectors.
|
33
|
+
{
|
34
|
+
double *Hs = ALLOC_N_double(n_pts_data);
|
35
|
+
double *alphas = ALLOC_N_double(n_pts_data);
|
36
|
+
double *Ls = ALLOC_N_double(n_pts_data);
|
37
|
+
double *mu_s = ALLOC_N_double(n_pts_data);
|
38
|
+
double *Zs = ALLOC_N_double(n_pts_data);
|
39
|
+
int n = n_pts_data-1, i, j;
|
40
|
+
for (i=0; i < n; i++)
|
41
|
+
Hs[i] = Xs[i+1] - Xs[i];
|
42
|
+
if (start_clamped) alphas[0] = 3.0*(Ys[1]-Ys[0])/Hs[0] - 3.0*start_slope;
|
43
|
+
if (end_clamped) alphas[n] = 3.0*end_slope - 3.0*(Ys[n]-Ys[n-1])/Hs[n-1];
|
44
|
+
for (i=1; i < n; i++)
|
45
|
+
alphas[i] = 3.0*(Ys[i+1]*Hs[i-1]-Ys[i]*(Xs[i+1]-Xs[i-1])+Ys[i-1]*Hs[i])/(Hs[i-1]*Hs[i]);
|
46
|
+
if (start_clamped) { Ls[0] = 2.0*Hs[0]; mu_s[0] = 0.5; Zs[0] = alphas[0]/Ls[0]; }
|
47
|
+
else { Ls[0] = 1.0; mu_s[0] = 0.0; Zs[0] = 0.0; }
|
48
|
+
for (i = 1; i < n; i++) {
|
49
|
+
Ls[i] = 2.0*(Xs[i+1]-Xs[i-1]) - Hs[i-1]*mu_s[i-1];
|
50
|
+
mu_s[i] = Hs[i]/Ls[i];
|
51
|
+
Zs[i] = (alphas[i] - Hs[i-1]*Zs[i-1])/Ls[i];
|
52
52
|
}
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
FM *p = Get_FM(fmkr);
|
57
|
-
bool start_clamped = (start_slope != Qnil), end_clamped = (end_slope != Qnil);
|
58
|
-
double start=0, end=0;
|
59
|
-
if (start_clamped) {
|
60
|
-
start_slope = rb_Float(start_slope);
|
61
|
-
start = NUM2DBL(start_slope);
|
53
|
+
if (end_clamped) {
|
54
|
+
Ls[n] = Hs[n-1]*(2.0-mu_s[n-1]);
|
55
|
+
Bs[n] = Zs[n] = (alphas[n]-Hs[n-1]*Zs[n-1])/Ls[n];
|
62
56
|
}
|
63
|
-
|
64
|
-
|
65
|
-
|
57
|
+
else { Ls[n] = 1.0; Zs[n] = 0.0; Bs[n] = 0.0; }
|
58
|
+
for (j = n-1; j >= 0; j--) {
|
59
|
+
Bs[j] = Zs[j] - mu_s[j]*Bs[j+1];
|
60
|
+
Cs[j] = (Ys[j+1]-Ys[j])/Hs[j] - Hs[j]*(Bs[j+1]+2.0*Bs[j])/3.0;
|
61
|
+
As[j] = (Bs[j+1]-Bs[j])/(3.0*Hs[j]);
|
66
62
|
}
|
67
|
-
|
68
|
-
|
69
|
-
|
63
|
+
free(Zs); free(mu_s); free(Ls); free(alphas); free(Hs);
|
64
|
+
}
|
65
|
+
|
66
|
+
static double spline_interpolate(double x, int n_pts_data,
|
67
|
+
double *Xs, double *Ys, double *As, double *Bs, double *Cs)
|
68
|
+
// this is copied from dvector so that makers.c won't depend on dvectors.
|
69
|
+
{
|
70
|
+
int j;
|
71
|
+
for (j = 0; j < n_pts_data && x >= Xs[j]; j++);
|
72
|
+
if (j == n_pts_data) return Ys[j-1];
|
73
|
+
if (j == 0) return Ys[0];
|
74
|
+
j--;
|
75
|
+
double dx = x - Xs[j];
|
76
|
+
return Ys[j] + dx*(Cs[j] + dx*(Bs[j] + dx*As[j]));
|
77
|
+
}
|
78
|
+
|
79
|
+
|
80
|
+
OBJ_PTR c_private_make_spline_interpolated_points(OBJ_PTR fmkr, FM *p,
|
81
|
+
OBJ_PTR Xvec, OBJ_PTR Xvec_data, OBJ_PTR Yvec_data,
|
82
|
+
OBJ_PTR start_slope, OBJ_PTR end_slope, int *ierr) {
|
83
|
+
|
84
|
+
bool start_clamped = (start_slope != OBJ_NIL), end_clamped = (end_slope != OBJ_NIL);
|
85
|
+
long xlen;
|
86
|
+
double start=0, end=0, *Ys;
|
87
|
+
double *Xs = Vector_Data_for_Read(Xvec, &xlen, ierr);
|
88
|
+
if (*ierr != 0) RETURN_NIL;
|
89
|
+
OBJ_PTR Yvec;
|
90
|
+
|
91
|
+
if (start_clamped) start = Number_to_double(start_slope, ierr);
|
92
|
+
if (end_clamped) end = Number_to_double(end_slope, ierr);
|
93
|
+
if (*ierr != 0) RETURN_NIL;
|
94
|
+
|
95
|
+
Ys = ALLOC_N_double(xlen); // Ys are same length as Xs
|
96
|
+
|
97
|
+
int i, n_pts_data;
|
98
|
+
double *As, *Bs, *Cs, *Ds;
|
99
|
+
long xdlen, ydlen;
|
100
|
+
double *X_data = Vector_Data_for_Read(Xvec_data, &xdlen, ierr);
|
101
|
+
if (*ierr != 0) RETURN_NIL;
|
102
|
+
double *Y_data = Vector_Data_for_Read(Yvec_data, &ydlen, ierr);
|
103
|
+
if (*ierr != 0) RETURN_NIL;
|
104
|
+
if (Xs == NULL || Ys == NULL || X_data == NULL || Y_data == NULL || xdlen != ydlen) {
|
105
|
+
RAISE_ERROR("Sorry: bad args",ierr); RETURN_NIL;
|
106
|
+
}
|
107
|
+
if (xlen == 0) RETURN_NIL;
|
108
|
+
n_pts_data = xdlen;
|
109
|
+
As = Y_data;
|
110
|
+
Bs = ALLOC_N_double(n_pts_data);
|
111
|
+
Cs = ALLOC_N_double(n_pts_data);
|
112
|
+
Ds = ALLOC_N_double(n_pts_data);
|
113
|
+
create_spline_interpolant(n_pts_data, X_data, Y_data,
|
114
|
+
start_clamped, start, end_clamped, end, Bs, Cs, Ds);
|
115
|
+
for (i = 0; i < xlen; i++)
|
116
|
+
Ys[i] = spline_interpolate(Xs[i], n_pts_data, X_data, As, Bs, Cs, Ds);
|
117
|
+
free(Ds); free(Cs); free(Bs);
|
118
|
+
Yvec = Vector_New(xlen, Ys);
|
119
|
+
free(Ys);
|
120
|
+
return Yvec;
|
70
121
|
}
|
71
122
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
123
|
+
|
124
|
+
/*
|
125
|
+
* Make points xs and ys to define a step function. x_data and y_data
|
126
|
+
* are arrays from which the step functions are generated. (xfirst,
|
127
|
+
* yfirst) and (xlast, ylast) are extra data points to fix the first
|
128
|
+
* and last steps. The x_data plus xfirst and xlast determine the
|
129
|
+
* widths of the steps. The y_data plus yfirst and ylast determine
|
130
|
+
* the height of the steps. For CENTERED justification, the steps
|
131
|
+
* occur at locations midway between the given x locations. For
|
132
|
+
* LEFT_JUSTIFIED, (x_data[i], y_data[i]) and (x_data[i], y_data[i+1])
|
133
|
+
* specifies where steps occurs. For RIGHT_JUSTIFIED, (x_data[i],
|
134
|
+
* y_data[i]) and (x_data[i], y_data[i-1]) specifies where steps
|
135
|
+
* occurs.
|
136
|
+
*
|
137
|
+
* Aug 24, 2007:
|
138
|
+
*
|
139
|
+
* TS added 'justification' to control the justification of steps.
|
140
|
+
* The use of [xy]first and [xy]last might need improvement.
|
141
|
+
*/
|
142
|
+
static void
|
143
|
+
c_make_steps(FM *p,
|
144
|
+
long *xsteps_len_ptr, double **xs_ptr,
|
145
|
+
long *ysteps_len_ptr, double **ys_ptr,
|
146
|
+
OBJ_PTR xvec_data, OBJ_PTR yvec_data,
|
147
|
+
double xfirst, double yfirst, double xlast, double ylast,
|
148
|
+
int justification, int *ierr)
|
149
|
+
{
|
150
|
+
double xnext, xprev, x;
|
151
|
+
long i, j, length, xdlen, ydlen;
|
152
|
+
double *xs = NULL, *ys = NULL;
|
153
|
+
double *x_data = Vector_Data_for_Read(xvec_data, &xdlen, ierr);
|
154
|
+
if (*ierr != 0) return;
|
155
|
+
double *y_data = Vector_Data_for_Read(yvec_data, &ydlen, ierr);
|
156
|
+
if (*ierr != 0) return;
|
157
|
+
if (x_data == NULL || y_data == NULL || xdlen != ydlen) {
|
158
|
+
RAISE_ERROR("Sorry: bad args for make_steps", ierr);
|
159
|
+
return;
|
160
|
+
}
|
161
|
+
|
162
|
+
// allocate memory for arrays to be returned
|
163
|
+
length = 2 * (xdlen + 1) + ((justification != CENTERED) ? 1 : 0);
|
164
|
+
|
165
|
+
*xsteps_len_ptr = length;
|
166
|
+
xs = ALLOC_N_double(length);
|
167
|
+
*xs_ptr = xs;
|
168
|
+
|
169
|
+
*ysteps_len_ptr = length;
|
170
|
+
ys = ALLOC_N_double(length);
|
171
|
+
*ys_ptr = ys;
|
172
|
+
|
173
|
+
// fill the arrays
|
174
|
+
switch (justification) {
|
175
|
+
case CENTERED:
|
176
|
+
for (i = 0, j = 0; i <= xdlen; ++i, j += 2) {
|
177
|
+
xprev = (i == 0) ? xfirst : x_data[i - 1];
|
178
|
+
xnext = (i == xdlen) ? xlast : x_data[i];
|
179
|
+
x = 0.5 * (xprev + xnext);
|
180
|
+
xs[j] = xs[j + 1] = x;
|
85
181
|
}
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
new_length = old_length + n_pts_to_add;
|
90
|
-
Xs = Dvector_Data_Resize(Xvec, new_length);
|
91
|
-
Ys = Dvector_Data_Resize(Yvec, new_length);
|
92
|
-
for (i = 0, j = 0; i <= n; i++, j += 2) {
|
93
|
-
xprev = (i==0)? xfirst : X_data[i-1];
|
94
|
-
xnext = (i==n)? xlast : X_data[i];
|
95
|
-
x = 0.5*(xprev + xnext);
|
96
|
-
Xs[j+old_length] = Xs[j+1+old_length] = x;
|
97
|
-
}
|
98
|
-
Ys[0] = yfirst;
|
99
|
-
for (i = 0, j = 1; i < n; i++, j += 2) {
|
100
|
-
Ys[j+old_length] = Ys[j+1+old_length] = Y_data[i];
|
101
|
-
}
|
102
|
-
Ys[n_pts_to_add-1+old_length] = ylast;
|
103
|
-
USE_P
|
182
|
+
ys[0] = yfirst;
|
183
|
+
for (i = 0, j = 1; i < xdlen; ++i, j += 2) {
|
184
|
+
ys[j] = ys[j + 1] = y_data[i];
|
104
185
|
}
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
186
|
+
ys[length - 1] = ylast;
|
187
|
+
break;
|
188
|
+
case LEFT_JUSTIFIED:
|
189
|
+
xs[0] = xfirst;
|
190
|
+
for (i = 0, j = 1; i <= xdlen; ++i, j += 2) {
|
191
|
+
xs[j] = xs[j + 1] = (i == xdlen) ? xlast : x_data[i];
|
192
|
+
}
|
193
|
+
ys[0] = ys[1] = yfirst;
|
194
|
+
for (i = 0, j = 2; i < xdlen; ++i, j += 2) {
|
195
|
+
ys[j] = ys[j + 1] = y_data[i];
|
196
|
+
}
|
197
|
+
ys[length - 1] = ylast;
|
198
|
+
break;
|
199
|
+
case RIGHT_JUSTIFIED:
|
200
|
+
for (i = 0, j = 0; i <= xdlen; ++i, j += 2) {
|
201
|
+
xs[j] = xs[j + 1] = (i == 0) ? xfirst : x_data[i - 1];
|
202
|
+
}
|
203
|
+
xs[length - 1] = xlast;
|
204
|
+
ys[0] = yfirst;
|
205
|
+
for (i = 0, j = 1; i <= xdlen; ++i, j += 2) {
|
206
|
+
ys[j] = ys[j + 1] = (i == xdlen) ? ylast : y_data[i];
|
207
|
+
}
|
208
|
+
break;
|
209
|
+
default:
|
210
|
+
RAISE_ERROR_i("Sorry: unsupported justification specified (%d)",
|
211
|
+
justification, ierr);
|
212
|
+
return;
|
116
213
|
}
|
117
214
|
|
215
|
+
/* TS: I don't understand the use of the macro USE_P here, which
|
216
|
+
translates to p = NULL; For now, I'll comment out. */
|
217
|
+
//USE_P
|
218
|
+
}
|
219
|
+
|
220
|
+
|
221
|
+
OBJ_PTR
|
222
|
+
c_private_make_steps(OBJ_PTR fmkr, FM *p, OBJ_PTR xvec_data, OBJ_PTR yvec_data,
|
223
|
+
double xfirst, double yfirst, double xlast, double ylast,
|
224
|
+
int justification, int *ierr)
|
225
|
+
{
|
226
|
+
OBJ_PTR xvec;
|
227
|
+
OBJ_PTR yvec;
|
228
|
+
OBJ_PTR pts_array;
|
229
|
+
long xsteps_len = 0, ysteps_len = 0;
|
230
|
+
double *xsteps_data = NULL, *ysteps_data = NULL;
|
231
|
+
|
232
|
+
c_make_steps(p, &xsteps_len, &xsteps_data, &ysteps_len, &ysteps_data,
|
233
|
+
xvec_data, yvec_data, xfirst, yfirst, xlast, ylast,
|
234
|
+
justification, ierr);
|
235
|
+
if (*ierr != 0) RETURN_NIL;
|
236
|
+
|
237
|
+
xvec = Vector_New(xsteps_len, xsteps_data);
|
238
|
+
yvec = Vector_New(ysteps_len, ysteps_data);
|
239
|
+
free(xsteps_data);
|
240
|
+
free(ysteps_data);
|
241
|
+
|
242
|
+
pts_array = Array_New(2);
|
243
|
+
Array_Store(pts_array, 0, xvec, ierr);
|
244
|
+
if (*ierr != 0) RETURN_NIL;
|
245
|
+
Array_Store(pts_array, 1, yvec, ierr);
|
246
|
+
if (*ierr != 0) RETURN_NIL;
|
247
|
+
return pts_array;
|
248
|
+
}
|
249
|
+
|
250
|
+
|
118
251
|
/*
|
119
252
|
CONREC: A Contouring Subroutine
|
120
253
|
written by Paul Bourke
|
@@ -172,12 +305,18 @@ MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
|
172
305
|
#define min(x,y) (x<y?x:y)
|
173
306
|
#define max(x,y) (x>y?x:y)
|
174
307
|
|
175
|
-
#define PUSH_POINT(x,y
|
176
|
-
|
177
|
-
|
178
|
-
|
308
|
+
#define PUSH_POINT(x,y) { \
|
309
|
+
if (*dest_len_ptr >= *dest_sz_ptr) { \
|
310
|
+
*dest_sz_ptr += *dest_sz_ptr + 100; \
|
311
|
+
REALLOC_double(dest_xs_ptr,*dest_sz_ptr); \
|
312
|
+
REALLOC_double(dest_ys_ptr,*dest_sz_ptr); \
|
313
|
+
} \
|
314
|
+
(*dest_xs_ptr)[*dest_len_ptr] = x; \
|
315
|
+
(*dest_ys_ptr)[*dest_len_ptr] = y; \
|
316
|
+
(*dest_len_ptr)++; \
|
317
|
+
}
|
179
318
|
|
180
|
-
int conrec(double **d,
|
319
|
+
static int conrec(double **d,
|
181
320
|
int ilb,
|
182
321
|
int iub,
|
183
322
|
int jlb,
|
@@ -186,11 +325,14 @@ int conrec(double **d,
|
|
186
325
|
double *y,
|
187
326
|
int nc,
|
188
327
|
double *z,
|
189
|
-
|
190
|
-
|
191
|
-
|
328
|
+
long *dest_len_ptr,
|
329
|
+
double **dest_xs_ptr,
|
330
|
+
double **dest_ys_ptr,
|
331
|
+
long *dest_sz_ptr,
|
332
|
+
OBJ_PTR gaps,
|
192
333
|
double x_limit,
|
193
|
-
double y_limit
|
334
|
+
double y_limit,
|
335
|
+
int *ierr)
|
194
336
|
// d ! matrix of data to contour
|
195
337
|
// ilb,iub,jlb,jub ! index bounds of data matrix
|
196
338
|
// x ! data matrix column coordinates
|
@@ -198,14 +340,14 @@ int conrec(double **d,
|
|
198
340
|
// nc ! number of contour levels
|
199
341
|
// z ! contour levels in increasing order
|
200
342
|
{
|
201
|
-
int num_pts = 0;
|
202
|
-
double x_prev=0.0, y_prev=0.0;
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
343
|
+
int num_pts = 0;
|
344
|
+
double x_prev=0.0, y_prev=0.0;
|
345
|
+
int m1,m2,m3,case_value;
|
346
|
+
double dmin,dmax,x1=0.0,x2=0.0,y1=0.0,y2=0.0;
|
347
|
+
register int i,j,k,m;
|
348
|
+
double h[5];
|
349
|
+
int sh[5];
|
350
|
+
double xh[5],yh[5];
|
209
351
|
//===========================================================================
|
210
352
|
// The indexing of im and jm should be noted as it has to start from zero
|
211
353
|
// unlike the fortran counter part
|
@@ -390,10 +532,10 @@ double x_prev=0.0, y_prev=0.0;
|
|
390
532
|
double dx = x1 - x_prev, dy = y1 - y_prev;
|
391
533
|
if (dx < 0) dx = -dx; if (dy < 0) dy = -dy;
|
392
534
|
if (num_pts == 0 || dx > x_limit || dy > y_limit) {
|
393
|
-
if (num_pts > 0)
|
394
|
-
PUSH_POINT(x1,y1
|
535
|
+
if (num_pts > 0) { Array_Push(gaps, Integer_New(num_pts), ierr); if (*ierr != 0) return 0; }
|
536
|
+
PUSH_POINT(x1,y1); num_pts++;
|
395
537
|
}
|
396
|
-
PUSH_POINT(x2,y2
|
538
|
+
PUSH_POINT(x2,y2); num_pts++;
|
397
539
|
x_prev = x2; y_prev = y2;
|
398
540
|
}
|
399
541
|
}
|
@@ -426,26 +568,32 @@ double x_prev=0.0, y_prev=0.0;
|
|
426
568
|
// globals to this file
|
427
569
|
static int nx_1, ny_1, iGT, jGT, iLE, jLE;
|
428
570
|
|
429
|
-
static void free_space_for_curve();
|
430
|
-
static void get_space_for_curve();
|
571
|
+
static void free_space_for_curve(void);
|
572
|
+
static void get_space_for_curve(int *ierr);
|
431
573
|
static void draw_the_contour(
|
432
|
-
|
433
|
-
|
434
|
-
|
574
|
+
long *dest_len_ptr,
|
575
|
+
double **dest_xs_ptr,
|
576
|
+
double **dest_ys_ptr,
|
577
|
+
long *dest_sz_ptr,
|
578
|
+
OBJ_PTR gaps,
|
579
|
+
int *ierr);
|
435
580
|
|
436
581
|
static bool trace_contour(double z0,
|
437
582
|
double *x,
|
438
583
|
double *y,
|
439
|
-
|
584
|
+
double **z,
|
440
585
|
double **legit,
|
441
|
-
|
442
|
-
|
443
|
-
|
586
|
+
long *dest_len_ptr,
|
587
|
+
double **dest_xs_ptr,
|
588
|
+
double **dest_ys_ptr,
|
589
|
+
long *dest_sz_ptr,
|
590
|
+
OBJ_PTR gaps,
|
591
|
+
int *iterr);
|
444
592
|
|
445
|
-
static int FLAG(int ni, int nj, int ind);
|
593
|
+
static int FLAG(int ni, int nj, int ind, int *ierr);
|
446
594
|
static int append_segment(double xr, double yr, double zr, double OKr,
|
447
595
|
double xs, double ys, double zs, double OKs,
|
448
|
-
double z0);
|
596
|
+
double z0, int *ierr);
|
449
597
|
|
450
598
|
// Space for curve, shared by several routines
|
451
599
|
static double *xcurve, *ycurve;
|
@@ -456,7 +604,7 @@ static bool curve_storage_exists = false;
|
|
456
604
|
|
457
605
|
|
458
606
|
static void
|
459
|
-
free_space_for_curve()
|
607
|
+
free_space_for_curve(void)
|
460
608
|
{
|
461
609
|
if (curve_storage_exists) {
|
462
610
|
free(xcurve);
|
@@ -469,16 +617,16 @@ free_space_for_curve()
|
|
469
617
|
}
|
470
618
|
|
471
619
|
static void
|
472
|
-
get_space_for_curve()
|
620
|
+
get_space_for_curve(int *ierr)
|
473
621
|
{
|
474
622
|
max_in_curve = INITIAL_CURVE_SIZE;
|
475
623
|
if(curve_storage_exists) {
|
476
|
-
|
477
|
-
return;
|
624
|
+
RAISE_ERROR("storage is messed up (internal error)", ierr);
|
625
|
+
return;
|
478
626
|
}
|
479
|
-
xcurve =
|
480
|
-
ycurve =
|
481
|
-
legitcurve =
|
627
|
+
xcurve = ALLOC_N_double(max_in_curve);
|
628
|
+
ycurve = ALLOC_N_double(max_in_curve);
|
629
|
+
legitcurve = ALLOC_N_bool(max_in_curve);
|
482
630
|
curve_storage_exists = true;
|
483
631
|
num_in_curve = 0;
|
484
632
|
num_in_path = 0;
|
@@ -498,7 +646,6 @@ get_space_for_curve()
|
|
498
646
|
// contour_space_later centimeters, starting with a space of
|
499
647
|
// contour_space_first from the beginning of the trace.
|
500
648
|
//
|
501
|
-
// CONTOUR_VALUE MISSING_VALUE
|
502
649
|
static void
|
503
650
|
gr_contour(
|
504
651
|
double *x,
|
@@ -508,21 +655,25 @@ gr_contour(
|
|
508
655
|
int nx,
|
509
656
|
int ny,
|
510
657
|
double z0,
|
511
|
-
|
512
|
-
|
513
|
-
|
658
|
+
long *dest_len_ptr,
|
659
|
+
double **dest_xs_ptr,
|
660
|
+
double **dest_ys_ptr,
|
661
|
+
long *dest_sz_ptr,
|
662
|
+
OBJ_PTR gaps,
|
663
|
+
int *ierr)
|
514
664
|
{
|
515
665
|
register int i, j;
|
516
666
|
// Test for errors
|
517
|
-
|
518
|
-
|
667
|
+
if (nx <= 0) { RAISE_ERROR("nx<=0 (internal error)", ierr); return; }
|
668
|
+
if (ny <= 0) { RAISE_ERROR("ny<=0 (internal error)", ierr); return; }
|
519
669
|
// Save some globals
|
520
670
|
nx_1 = nx - 1;
|
521
671
|
ny_1 = ny - 1;
|
522
672
|
// Clear all switches.
|
523
|
-
FLAG(nx, ny, -1);
|
673
|
+
FLAG(nx, ny, -1, ierr);
|
524
674
|
// Get space for the curve.
|
525
|
-
get_space_for_curve();
|
675
|
+
get_space_for_curve(ierr);
|
676
|
+
if (*ierr != 0) return;
|
526
677
|
|
527
678
|
// Search for a contour intersecting various places on the grid. Whenever
|
528
679
|
// a contour is found to be between two grid points, call trace_contour()
|
@@ -553,7 +704,8 @@ gr_contour(
|
|
553
704
|
jLE = j;
|
554
705
|
iGT = i;
|
555
706
|
jGT = j;
|
556
|
-
trace_contour(z0, x, y, z, legit,
|
707
|
+
trace_contour(z0, x, y, z, legit, dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
|
708
|
+
if (*ierr != 0) return;
|
557
709
|
}
|
558
710
|
// Space through legit points, that is, skipping through good
|
559
711
|
// data looking for another island of bad data which will
|
@@ -576,10 +728,11 @@ gr_contour(
|
|
576
728
|
jLE = j - 1;
|
577
729
|
iGT = i;
|
578
730
|
jGT = j;
|
579
|
-
trace_contour(z0, x, y, z, legit,
|
731
|
+
trace_contour(z0, x, y, z, legit, dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
|
732
|
+
if (*ierr != 0) return;
|
580
733
|
}
|
581
734
|
// space through legit points
|
582
|
-
while (i > 0 && (legit == NULL || legit[i][j] != 0.0 && legit[i][ j - 1] != 0.0))
|
735
|
+
while (i > 0 && (legit == NULL || (legit[i][j] != 0.0 && legit[i][ j - 1] != 0.0)))
|
583
736
|
i--;
|
584
737
|
}
|
585
738
|
}
|
@@ -596,10 +749,11 @@ gr_contour(
|
|
596
749
|
jLE = j;
|
597
750
|
iGT = i;
|
598
751
|
jGT = j;
|
599
|
-
trace_contour(z0, x, y, z, legit,
|
752
|
+
trace_contour(z0, x, y, z, legit, dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
|
753
|
+
if (*ierr != 0) return;
|
600
754
|
}
|
601
755
|
// space through legit points
|
602
|
-
while (j > 0 && (legit == NULL || legit[i][j] != 0.0 && legit[i + 1][ j] != 0.0))
|
756
|
+
while (j > 0 && (legit == NULL || (legit[i][j] != 0.0 && legit[i + 1][ j] != 0.0)))
|
603
757
|
j--;
|
604
758
|
}
|
605
759
|
}
|
@@ -616,10 +770,11 @@ gr_contour(
|
|
616
770
|
jLE = j + 1;
|
617
771
|
iGT = i;
|
618
772
|
jGT = j;
|
619
|
-
trace_contour(z0, x, y, z, legit,
|
773
|
+
trace_contour(z0, x, y, z, legit, dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
|
774
|
+
if (*ierr != 0) return;
|
620
775
|
}
|
621
776
|
// space through legit points
|
622
|
-
while (i < nx_1 && (legit == NULL || legit[i][j] != 0.0 && legit[i][ j + 1] != 0.0))
|
777
|
+
while (i < nx_1 && (legit == NULL || (legit[i][j] != 0.0 && legit[i][ j + 1] != 0.0)))
|
623
778
|
i++;
|
624
779
|
}
|
625
780
|
}
|
@@ -631,9 +786,12 @@ gr_contour(
|
|
631
786
|
int flag_is_set;
|
632
787
|
for (i = 1; i < nx; i++) {
|
633
788
|
// trace a contour if it hits here
|
634
|
-
flag_is_set = FLAG(i, j, 0);
|
635
|
-
|
636
|
-
|
789
|
+
flag_is_set = FLAG(i, j, 0, ierr);
|
790
|
+
if (*ierr != 0) return;
|
791
|
+
if (flag_is_set < 0) {
|
792
|
+
RAISE_ERROR("ran out of storage (internal error)", ierr);
|
793
|
+
return;
|
794
|
+
}
|
637
795
|
if (!flag_is_set
|
638
796
|
&& (legit == NULL || legit[i][j] != 0.0)
|
639
797
|
&& z[i][j] > z0
|
@@ -643,13 +801,14 @@ gr_contour(
|
|
643
801
|
jLE = j;
|
644
802
|
iGT = i;
|
645
803
|
jGT = j;
|
646
|
-
trace_contour(z0, x, y, z, legit,
|
804
|
+
trace_contour(z0, x, y, z, legit, dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
|
805
|
+
if (*ierr != 0) return;
|
647
806
|
}
|
648
807
|
}
|
649
808
|
}
|
650
809
|
// Free up space.
|
651
810
|
free_space_for_curve();
|
652
|
-
FLAG(nx, ny, 2);
|
811
|
+
FLAG(nx, ny, 2, ierr);
|
653
812
|
}
|
654
813
|
|
655
814
|
// trace_contour() -- trace_contour a contour line with high values of z to
|
@@ -662,9 +821,12 @@ trace_contour(double z0,
|
|
662
821
|
double *y,
|
663
822
|
double **z,
|
664
823
|
double **legit,
|
665
|
-
|
666
|
-
|
667
|
-
|
824
|
+
long *dest_len_ptr,
|
825
|
+
double **dest_xs_ptr,
|
826
|
+
double **dest_ys_ptr,
|
827
|
+
long *dest_sz_ptr,
|
828
|
+
OBJ_PTR gaps,
|
829
|
+
int *ierr
|
668
830
|
)
|
669
831
|
{
|
670
832
|
int i, ii, j, jj;
|
@@ -698,7 +860,8 @@ trace_contour(double z0,
|
|
698
860
|
|
699
861
|
append_segment(x[iLE], y[jLE], z[iLE][jLE], (legit == NULL)? 1.0: legit[iLE][jLE],
|
700
862
|
x[iGT], y[jGT], z[iGT][jGT], (legit == NULL)? 1.0: legit[iGT][jGT],
|
701
|
-
z0);
|
863
|
+
z0, ierr);
|
864
|
+
if (*ierr != 0) return false;
|
702
865
|
// Find the next point to check through a table lookup.
|
703
866
|
locate = 3 * (jGT - jLE) + (iGT - iLE) + 4;
|
704
867
|
i = iLE + i_test[locate];
|
@@ -707,27 +870,31 @@ trace_contour(double z0,
|
|
707
870
|
|
708
871
|
// Did it hit an edge?
|
709
872
|
if (i > nx_1 || i < 0 || j > ny_1 || j < 0) {
|
710
|
-
draw_the_contour(
|
873
|
+
draw_the_contour(dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
|
874
|
+
if (*ierr != 0) return false;
|
711
875
|
return true; // all done
|
712
876
|
}
|
713
877
|
|
714
878
|
// Test if retracing an existing contour. See explanation
|
715
879
|
// above, in grcntour(), just before search starts.
|
716
880
|
if (locate == 5) {
|
717
|
-
int already_set = FLAG(iGT, jGT, 1);
|
881
|
+
int already_set = FLAG(iGT, jGT, 1, ierr);
|
882
|
+
if (*ierr != 0) return false;
|
718
883
|
if (already_set < 0) {
|
719
|
-
|
884
|
+
RAISE_ERROR("ran out of storage (internal error)", ierr);
|
720
885
|
return false;
|
721
886
|
}
|
722
887
|
if (already_set) {
|
723
|
-
draw_the_contour(
|
888
|
+
draw_the_contour(dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
|
889
|
+
if (*ierr != 0) return false;
|
724
890
|
return true; // all done
|
725
891
|
}
|
726
892
|
}
|
727
893
|
|
728
894
|
// Following new for 2.1.13
|
729
895
|
if (legit != NULL && legit[i][j] == 0.0) {
|
730
|
-
draw_the_contour(
|
896
|
+
draw_the_contour(dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
|
897
|
+
if (*ierr != 0) return false;
|
731
898
|
return true; // all done
|
732
899
|
}
|
733
900
|
|
@@ -755,14 +922,16 @@ trace_contour(double z0,
|
|
755
922
|
if (zcentre <= z0) {
|
756
923
|
append_segment(x[iGT], y[jGT], z[iGT][jGT], (legit == NULL)? 1.0: legit[iGT][jGT],
|
757
924
|
vx, vy, zcentre, legit_diag,
|
758
|
-
z0);
|
925
|
+
z0, ierr);
|
926
|
+
if (*ierr != 0) return false;
|
759
927
|
if (z[ii][jj] <= z0) {
|
760
928
|
iLE = ii, jLE = jj;
|
761
929
|
continue;
|
762
930
|
}
|
763
931
|
append_segment(x[ii], y[jj], z[ii][jj], (legit == NULL)? 1.0: legit[ii][jj],
|
764
932
|
vx, vy, zcentre, legit_diag,
|
765
|
-
z0);
|
933
|
+
z0, ierr);
|
934
|
+
if (*ierr != 0) return false;
|
766
935
|
if (z[i][j] <= z0) {
|
767
936
|
iGT = ii, jGT = jj;
|
768
937
|
iLE = i, jLE = j;
|
@@ -770,24 +939,28 @@ trace_contour(double z0,
|
|
770
939
|
}
|
771
940
|
append_segment(x[i], y[j], z[i][j], (legit == NULL)? 1.0: legit[i][j],
|
772
941
|
vx, vy, zcentre, legit_diag,
|
773
|
-
z0);
|
942
|
+
z0, ierr);
|
943
|
+
if (*ierr != 0) return false;
|
774
944
|
iGT = i, jGT = j;
|
775
945
|
continue;
|
776
946
|
}
|
777
947
|
append_segment(vx, vy, zcentre, legit_diag,
|
778
948
|
x[iLE], y[jLE], z[iLE][jLE], (legit == NULL)? 1.0: legit[iLE][jLE],
|
779
|
-
z0);
|
949
|
+
z0, ierr);
|
950
|
+
if (*ierr != 0) return false;
|
780
951
|
if (z[i][j] > z0) {
|
781
952
|
iGT = i, jGT = j;
|
782
953
|
continue;
|
783
954
|
}
|
784
955
|
append_segment(vx, vy, zcentre, legit_diag,
|
785
956
|
x[i], y[j], z[i][j], (legit == NULL)? 1.0: legit[i][j],
|
786
|
-
z0);
|
957
|
+
z0, ierr);
|
958
|
+
if (*ierr != 0) return false;
|
787
959
|
if (z[ii][jj] <= z0) {
|
788
960
|
append_segment(vx, vy, zcentre, legit_diag,
|
789
961
|
x[ii], y[jj], z[ii][jj], (legit == NULL)? 1.0: legit[ii][jj],
|
790
|
-
z0);
|
962
|
+
z0, ierr);
|
963
|
+
if (*ierr != 0) return false;
|
791
964
|
iLE = ii;
|
792
965
|
jLE = jj;
|
793
966
|
continue;
|
@@ -804,12 +977,12 @@ static double xplot_last, yplot_last;
|
|
804
977
|
static int
|
805
978
|
append_segment(double xr, double yr, double zr, double OKr,
|
806
979
|
double xs, double ys, double zs, double OKs,
|
807
|
-
double z0)
|
980
|
+
double z0, int *ierr)
|
808
981
|
{
|
809
|
-
|
982
|
+
if (zr == zs) { RAISE_ERROR("Contouring problem: zr = zs, which is illegal", ierr); return 0; }
|
810
983
|
double frac = (zr - z0) / (zr - zs);
|
811
|
-
if (frac < 0.0)
|
812
|
-
if (frac > 1.0)
|
984
|
+
if (frac < 0.0) { RAISE_ERROR("Contouring problem: frac < 0", ierr); return 0; }
|
985
|
+
if (frac > 1.0) { RAISE_ERROR("Contouring problem: frac > 1", ierr); return 0; }
|
813
986
|
double xplot = xr - frac * (xr - xs);
|
814
987
|
double yplot = yr - frac * (yr - ys);
|
815
988
|
// Avoid replot, which I suppose must be possible, given this code
|
@@ -820,17 +993,17 @@ append_segment(double xr, double yr, double zr, double OKr,
|
|
820
993
|
// do this with an STL vector class
|
821
994
|
max_in_curve *= 2;
|
822
995
|
int i;
|
823
|
-
double *tmp =
|
996
|
+
double *tmp = ALLOC_N_double(num_in_curve);
|
824
997
|
for (i = 0; i < num_in_curve; i++) tmp[i] = xcurve[i];
|
825
|
-
free(xcurve); xcurve =
|
998
|
+
free(xcurve); xcurve = ALLOC_N_double(max_in_curve);
|
826
999
|
for (i = 0; i < num_in_curve; i++) xcurve[i] = tmp[i];
|
827
1000
|
for (i = 0; i < num_in_curve; i++) tmp[i] = ycurve[i];
|
828
|
-
free(ycurve); ycurve =
|
1001
|
+
free(ycurve); ycurve = ALLOC_N_double(max_in_curve);
|
829
1002
|
for (i = 0; i < num_in_curve; i++) ycurve[i] = tmp[i];
|
830
1003
|
free(tmp);
|
831
|
-
bool *tmpl =
|
1004
|
+
bool *tmpl = ALLOC_N_bool(num_in_curve);
|
832
1005
|
for (i = 0; i < num_in_curve; i++) tmpl[i] = legitcurve[i];
|
833
|
-
free(legitcurve); legitcurve =
|
1006
|
+
free(legitcurve); legitcurve = ALLOC_N_bool(max_in_curve);
|
834
1007
|
for (i = 0; i < num_in_curve; i++) legitcurve[i] = tmpl[i];
|
835
1008
|
free(tmpl);
|
836
1009
|
}
|
@@ -852,13 +1025,15 @@ append_segment(double xr, double yr, double zr, double OKr,
|
|
852
1025
|
// Draw contour stored in (xcurve[],ycurve[],legitcurve[]), possibly with
|
853
1026
|
// labels (depending on global Label_contours).
|
854
1027
|
//
|
855
|
-
// CONTOUR_VALUE MISSING_VALUE
|
856
1028
|
#define FACTOR 3.0 // contour must be FACTOR*len long to be labelled
|
857
1029
|
static void
|
858
1030
|
draw_the_contour(
|
859
|
-
|
860
|
-
|
861
|
-
|
1031
|
+
long *dest_len_ptr,
|
1032
|
+
double **dest_xs_ptr,
|
1033
|
+
double **dest_ys_ptr,
|
1034
|
+
long *dest_sz_ptr,
|
1035
|
+
OBJ_PTR gaps,
|
1036
|
+
int *ierr)
|
862
1037
|
{
|
863
1038
|
if (num_in_curve == 1) {
|
864
1039
|
num_in_curve = 0;
|
@@ -868,13 +1043,16 @@ draw_the_contour(
|
|
868
1043
|
for (i = 0, k = 0; i < num_in_curve; i++) {
|
869
1044
|
if (legitcurve[i] == true) {
|
870
1045
|
// PUSH_POINT does num_in_path++
|
871
|
-
PUSH_POINT(xcurve[i],ycurve[i]
|
1046
|
+
PUSH_POINT(xcurve[i],ycurve[i]); num_in_path++;
|
872
1047
|
} else {
|
873
|
-
if (num_in_path > 0 && num_in_path != k)
|
1048
|
+
if (num_in_path > 0 && num_in_path != k) {
|
1049
|
+
Array_Push(gaps, Integer_New(num_in_path), ierr);
|
1050
|
+
if (*ierr != 0) return;
|
1051
|
+
}
|
874
1052
|
k = num_in_path;
|
875
1053
|
}
|
876
1054
|
}
|
877
|
-
|
1055
|
+
Array_Push(gaps, Integer_New(num_in_path), ierr);
|
878
1056
|
num_in_curve = 0;
|
879
1057
|
}
|
880
1058
|
|
@@ -885,11 +1063,11 @@ draw_the_contour(
|
|
885
1063
|
// if (ind == 1), check flag and then set it
|
886
1064
|
// if (ind == 2), clear the flag storage space
|
887
1065
|
// if (ind == 0), check flag, return value
|
888
|
-
// RETURN
|
1066
|
+
// RETURN value: Normally, the flag value (0 or 1). If the storage is
|
889
1067
|
// exhausted, return a number <0.
|
890
1068
|
#define NBITS 32
|
891
1069
|
static int
|
892
|
-
FLAG(int ni, int nj, int ind)
|
1070
|
+
FLAG(int ni, int nj, int ind, int *ierr)
|
893
1071
|
{
|
894
1072
|
static bool flag_storage_exists = false;
|
895
1073
|
static unsigned long *flag, mask[NBITS];
|
@@ -899,10 +1077,10 @@ FLAG(int ni, int nj, int ind)
|
|
899
1077
|
switch (ind) {
|
900
1078
|
case -1:
|
901
1079
|
// Allocate storage for flag array
|
902
|
-
if (flag_storage_exists)
|
903
|
-
|
1080
|
+
if (flag_storage_exists) {
|
1081
|
+
RAISE_ERROR("storage is messed up (internal error)", ierr); return 0; }
|
904
1082
|
size = 1 + ni * nj / NBITS; // total storage array length
|
905
|
-
flag =
|
1083
|
+
flag = ALLOC_N_unsigned_long(size);
|
906
1084
|
// Create mask
|
907
1085
|
mask[0] = 1;
|
908
1086
|
for (i = 1; i < NBITS; i++)
|
@@ -913,14 +1091,14 @@ FLAG(int ni, int nj, int ind)
|
|
913
1091
|
flag_storage_exists = true;
|
914
1092
|
return 0;
|
915
1093
|
case 2:
|
916
|
-
if (!flag_storage_exists)
|
917
|
-
|
1094
|
+
if (!flag_storage_exists) {
|
1095
|
+
RAISE_ERROR("No flag storage exists", ierr); return 0; }
|
918
1096
|
free(flag);
|
919
1097
|
flag_storage_exists = false;
|
920
1098
|
return 0;
|
921
1099
|
default:
|
922
|
-
if (!flag_storage_exists)
|
923
|
-
|
1100
|
+
if (!flag_storage_exists) {
|
1101
|
+
RAISE_ERROR("No flag storage exists", ierr); return 0; }
|
924
1102
|
break;
|
925
1103
|
}
|
926
1104
|
// ind was not -1 or 2
|
@@ -946,44 +1124,97 @@ FLAG(int ni, int nj, int ind)
|
|
946
1124
|
|
947
1125
|
|
948
1126
|
|
949
|
-
void c_make_contour(FM *p,
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
1127
|
+
static void c_make_contour(FM *p,
|
1128
|
+
long *dest_len_ptr,
|
1129
|
+
double **dest_xs_ptr,
|
1130
|
+
double **dest_ys_ptr,
|
1131
|
+
long *dest_sz_ptr,
|
1132
|
+
OBJ_PTR gaps,
|
1133
|
+
OBJ_PTR xs, OBJ_PTR ys,
|
1134
|
+
OBJ_PTR zs_data, double z_level,
|
1135
|
+
OBJ_PTR legit_data, int use_conrec, int *ierr) {
|
1136
|
+
|
1137
|
+
long xlen, ylen, num_zcolumns, num_zrows, num_columns, num_rows;
|
1138
|
+
double *x_coords = Vector_Data_for_Read(xs, &xlen, ierr);
|
1139
|
+
if (*ierr != 0) return;
|
1140
|
+
double *y_coords = Vector_Data_for_Read(ys, &ylen, ierr);
|
1141
|
+
if (*ierr != 0) return;
|
1142
|
+
double **zs = Table_Data_for_Read(zs_data, &num_zcolumns, &num_zrows, ierr);
|
1143
|
+
if (*ierr != 0) return;
|
1144
|
+
double **legit = Table_Data_for_Read(legit_data, &num_columns, &num_rows, ierr);
|
1145
|
+
if (*ierr != 0) return;
|
1146
|
+
double x_limit, y_limit;
|
1147
|
+
|
1148
|
+
if (x_coords == NULL || gaps == OBJ_NIL || zs == NULL || y_coords == NULL) {
|
1149
|
+
RAISE_ERROR("Sorry: bad args for make_contour. Need to provide xs, ys, gaps, and zs.", ierr); return;
|
958
1150
|
}
|
959
1151
|
if (xlen != num_columns || ylen != num_rows) {
|
960
|
-
|
1152
|
+
RAISE_ERROR("Sorry: bad args for make_contour. Needs xs.size == num columns and ys.size == num rows.", ierr); return;
|
961
1153
|
}
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
// NOTE: conrec data is TRANSPOSE of our data, so we switch x's and y's in the call
|
969
|
-
if (use_conrec == 1)
|
970
|
-
conrec(zs, 0, num_rows-1, 0, num_columns-1, y_coords, x_coords, 1, &z_level, dest_ys, dest_xs, gaps, y_limit, x_limit);
|
971
|
-
else
|
972
|
-
gr_contour(y_coords, x_coords, zs, legit, num_rows, num_columns, z_level, dest_ys, dest_xs, gaps);
|
1154
|
+
if (num_zcolumns != num_columns || num_zrows != num_rows) {
|
1155
|
+
RAISE_ERROR("Sorry: bad args for make_contour. Needs same dimension zs and legit flags.", ierr); return;
|
1156
|
+
}
|
1157
|
+
|
1158
|
+
// NOTE: contour data is TRANSPOSE of tioga data, so we switch x's and y's in the call
|
973
1159
|
|
1160
|
+
if (use_conrec == 1) {
|
1161
|
+
x_limit = 0.001*(x_coords[xlen-1] - x_coords[0])/xlen;
|
1162
|
+
if (x_limit < 0) x_limit = -x_limit;
|
1163
|
+
y_limit = 0.001*(y_coords[ylen-1] - y_coords[0])/ylen;
|
1164
|
+
if (y_limit < 0) y_limit = -y_limit;
|
1165
|
+
conrec(zs, 0, num_rows-1, 0, num_columns-1, y_coords, x_coords, 1, &z_level,
|
1166
|
+
dest_len_ptr, dest_ys_ptr, dest_xs_ptr, dest_sz_ptr, gaps, y_limit, x_limit, ierr);
|
1167
|
+
} else {
|
1168
|
+
gr_contour(y_coords, x_coords, zs, legit, num_rows, num_columns, z_level,
|
1169
|
+
dest_len_ptr, dest_ys_ptr, dest_xs_ptr, dest_sz_ptr, gaps, ierr);
|
1170
|
+
}
|
974
1171
|
}
|
975
1172
|
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
1173
|
+
|
1174
|
+
OBJ_PTR c_private_make_contour(OBJ_PTR fmkr, FM *p,
|
1175
|
+
OBJ_PTR gaps, // these vectors get the results
|
1176
|
+
OBJ_PTR xs, OBJ_PTR ys, // data x coordinates and y coordinates
|
1177
|
+
OBJ_PTR zs, double z_level, // the table of values and the desired contour level
|
1178
|
+
OBJ_PTR legit, // the table of flags (nonzero means okay)
|
1179
|
+
int method, // int == 1 means CONREC
|
1180
|
+
int *ierr
|
982
1181
|
) {
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
1182
|
+
/* uses Xvec_data and Yvec_data to create a cubic spline interpolant.
|
1183
|
+
once the spline interpolant is created, it is sampled at the n_pts_to_add in Xs.
|
1184
|
+
Xvec entry i is set to the value of the spline at Yvec entry i.
|
1185
|
+
Both the X_data and the Xs should be stored in ascending order.
|
1186
|
+
There is a boundary condition choice to be made for each end concerning the slope.
|
1187
|
+
If clamped is true, the corresponding slope argument value sets the slope.
|
1188
|
+
If clamped is false (known as a "free" or "natural" spline),
|
1189
|
+
the 2nd derivative is set to 0 and the slope is determined by the fit.
|
1190
|
+
In this case, the corresponding slope argument is ignored.
|
1191
|
+
*/
|
1192
|
+
long dest_len, dest_sz;
|
1193
|
+
double *dest_xs_data;
|
1194
|
+
double *dest_ys_data;
|
1195
|
+
OBJ_PTR Xvec;
|
1196
|
+
OBJ_PTR Yvec;
|
1197
|
+
OBJ_PTR pts_array;
|
1198
|
+
|
1199
|
+
dest_len = 0; dest_sz = 3000;
|
1200
|
+
dest_xs_data = ALLOC_N_double(dest_sz);
|
1201
|
+
dest_ys_data = ALLOC_N_double(dest_sz);
|
1202
|
+
|
1203
|
+
c_make_contour(p, &dest_len, &dest_xs_data, &dest_ys_data, &dest_sz,
|
1204
|
+
gaps, xs, ys, zs, z_level, legit, method, ierr);
|
1205
|
+
if (*ierr != 0) RETURN_NIL;
|
1206
|
+
|
1207
|
+
Xvec = Vector_New(dest_len, dest_xs_data);
|
1208
|
+
Yvec = Vector_New(dest_len, dest_ys_data);
|
1209
|
+
free(dest_xs_data);
|
1210
|
+
free(dest_ys_data);
|
1211
|
+
|
1212
|
+
pts_array = Array_New(2);
|
1213
|
+
Array_Store(pts_array,0,Xvec,ierr);
|
1214
|
+
if (*ierr != 0) RETURN_NIL;
|
1215
|
+
Array_Store(pts_array,1,Yvec,ierr);
|
1216
|
+
if (*ierr != 0) RETURN_NIL;
|
1217
|
+
return pts_array;
|
987
1218
|
}
|
988
1219
|
|
989
1220
|
|