tioga 1.7 → 1.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -166,12 +166,21 @@ static void Convert_Frame_Text_Position_To_Output_Location(FM *p, int frame_side
166
166
  }
167
167
  *xp = p->page_left + page_x; *yp = p->page_bottom + page_y;
168
168
  }
169
-
170
- void c_show_rotated_text(OBJ_PTR fmkr, FM *p, char *text, int frame_side, double shift, double fraction,
171
- double scale, double angle, int justification, int alignment, OBJ_PTR measure_name, int *ierr) {
172
- double x, y, base_angle, ft_ht = p->default_text_scale * scale * p->default_font_size;
173
- Convert_Frame_Text_Position_To_Output_Location(p, frame_side, shift*ft_ht*ENLARGE, fraction, &x, &y, &base_angle, text, ierr);
174
- tex_show_rotated_text(fmkr, p, text, x, y, scale, angle + base_angle, justification, alignment, measure_name);
169
+
170
+
171
+ void c_show_rotated_text(OBJ_PTR fmkr, FM *p, char *text, int frame_side,
172
+ double shift, double fraction, double scale,
173
+ double angle, int justification, int alignment,
174
+ OBJ_PTR measure_name, int *ierr)
175
+ {
176
+ double x = 0, y = 0, base_angle = 0;
177
+ double ft_ht = p->default_text_scale * scale * p->default_font_size;
178
+ Convert_Frame_Text_Position_To_Output_Location(p, frame_side,
179
+ shift * ft_ht * ENLARGE,
180
+ fraction, &x, &y,
181
+ &base_angle, text, ierr);
182
+ tex_show_rotated_text(fmkr, p, text, x, y, scale, angle + base_angle,
183
+ justification, alignment, measure_name);
175
184
  }
176
185
 
177
186
 
@@ -384,8 +393,8 @@ void private_make_portfolio(char *name, OBJ_PTR fignums, OBJ_PTR fignames, int *
384
393
  Takes sizes in bp.
385
394
 
386
395
  */
387
- void c_save_measure(OBJ_PTR fmkr, OBJ_PTR measure_name,
388
- double width, double height, double depth)
396
+ void c_private_save_measure(OBJ_PTR fmkr, OBJ_PTR measure_name,
397
+ double width, double height, double depth)
389
398
  {
390
399
  double angle, scale;
391
400
  int just, align;
@@ -506,7 +515,7 @@ void c_save_measure(OBJ_PTR fmkr, OBJ_PTR measure_name,
506
515
  of arrays (xy) of doubles
507
516
  */
508
517
  OBJ_PTR points = Array_New(0);
509
- OBJ_PTR current_point;
518
+ OBJ_PTR current_point = NULL;
510
519
  int i;
511
520
  for(i = 0; i < 8; i++) {
512
521
  char buf[4];
@@ -1,6 +1,8 @@
1
+ /* -*- c-basic-offset: 3; -*- */
1
2
  /* wrappers.c */
2
3
  /*
3
4
  Copyright (C) 2007 Bill Paxton
5
+ (C) 2008 Vincent Fourmond
4
6
 
5
7
  This file is part of Tioga.
6
8
 
@@ -29,7 +31,15 @@
29
31
 
30
32
  // axes.c
31
33
  OBJ_PTR FM_show_axis(OBJ_PTR fmkr, OBJ_PTR loc) { int ierr=0;
32
- c_show_axis(fmkr, Get_FM(fmkr, &ierr), Number_to_int(loc, &ierr), &ierr); RETURN_NIL; }
34
+ /* Now choosing between c_show_axis_generic and c_show_axis */
35
+ if(Is_Kind_of_Integer(loc)) /* A simple location */
36
+ c_show_axis(fmkr, Get_FM(fmkr, &ierr),
37
+ Number_to_int(loc, &ierr), &ierr);
38
+ else /* A hash */
39
+ c_show_axis_generic(fmkr, Get_FM(fmkr, &ierr), loc, &ierr);
40
+ RETURN_NIL;
41
+ }
42
+
33
43
  OBJ_PTR FM_show_edge(OBJ_PTR fmkr, OBJ_PTR loc) { int ierr=0;
34
44
  c_show_edge(fmkr, Get_FM(fmkr, &ierr), Number_to_int(loc, &ierr), &ierr); RETURN_NIL; }
35
45
  OBJ_PTR FM_no_title(OBJ_PTR fmkr) { int ierr=0; c_no_title(fmkr, Get_FM(fmkr, &ierr), &ierr); RETURN_NIL; }
@@ -42,6 +52,12 @@ OBJ_PTR FM_no_right_edge(OBJ_PTR fmkr) { int ierr=0; c_no_right_edge(fmkr, Get_F
42
52
  OBJ_PTR FM_no_top_edge(OBJ_PTR fmkr) { int ierr=0; c_no_top_edge(fmkr, Get_FM(fmkr, &ierr), &ierr); RETURN_NIL; }
43
53
  OBJ_PTR FM_no_bottom_edge(OBJ_PTR fmkr) { int ierr=0; c_no_bottom_edge(fmkr, Get_FM(fmkr, &ierr), &ierr); RETURN_NIL;}
44
54
 
55
+ OBJ_PTR FM_axis_information(OBJ_PTR fmkr, OBJ_PTR spec)
56
+ {
57
+ int ierr=0;
58
+ return c_axis_get_information(fmkr, Get_FM(fmkr, &ierr), spec, &ierr);
59
+ }
60
+
45
61
  // init.c
46
62
  OBJ_PTR FM_private_init_fm_data(OBJ_PTR fmkr) { int ierr=0;
47
63
  c_private_init_fm_data(fmkr, Get_FM(fmkr, &ierr), &ierr); RETURN_NIL; }
@@ -477,13 +493,13 @@ OBJ_PTR FM_check_label_clip(OBJ_PTR fmkr, OBJ_PTR xloc, OBJ_PTR yloc) { int ierr
477
493
  return c_check_label_clip(fmkr, Get_FM(fmkr, &ierr), Number_to_double(xloc, &ierr), Number_to_double(yloc, &ierr), &ierr); }
478
494
 
479
495
 
480
- OBJ_PTR FM_save_measure(OBJ_PTR fmkr, OBJ_PTR measure_name,
481
- OBJ_PTR width, OBJ_PTR height, OBJ_PTR depth)
496
+ OBJ_PTR FM_private_save_measure(OBJ_PTR fmkr, OBJ_PTR measure_name,
497
+ OBJ_PTR width, OBJ_PTR height, OBJ_PTR depth)
482
498
  {
483
499
  int ierr;
484
- c_save_measure(fmkr, measure_name,
485
- Number_to_double(width,&ierr),
486
- Number_to_double(height,&ierr),
487
- Number_to_double(depth,&ierr));
500
+ c_private_save_measure(fmkr, measure_name,
501
+ Number_to_double(width,&ierr),
502
+ Number_to_double(height,&ierr),
503
+ Number_to_double(depth,&ierr));
488
504
  return OBJ_NIL;
489
505
  }
@@ -45,6 +45,8 @@ extern OBJ_PTR FM_no_left_edge(OBJ_PTR fmkr);
45
45
  extern OBJ_PTR FM_no_right_edge(OBJ_PTR fmkr);
46
46
  extern OBJ_PTR FM_no_top_edge(OBJ_PTR fmkr);
47
47
  extern OBJ_PTR FM_no_bottom_edge(OBJ_PTR fmkr);
48
+ extern OBJ_PTR FM_axis_information(OBJ_PTR fmkr, OBJ_PTR loc);
49
+
48
50
 
49
51
  /*======================================================================*/
50
52
  // init.c
@@ -250,9 +252,9 @@ extern OBJ_PTR FM_check_label_clip(OBJ_PTR fmkr, OBJ_PTR xloc, OBJ_PTR yloc);
250
252
 
251
253
 
252
254
  /* For saving results of text measurements. */
253
- extern OBJ_PTR FM_save_measure(OBJ_PTR fmkr, OBJ_PTR measure_name,
254
- OBJ_PTR width, OBJ_PTR height,
255
- OBJ_PTR depth);
255
+ extern OBJ_PTR FM_private_save_measure(OBJ_PTR fmkr, OBJ_PTR measure_name,
256
+ OBJ_PTR width, OBJ_PTR height,
257
+ OBJ_PTR depth);
256
258
 
257
259
 
258
260
  #endif /* __wrappers_H__ */
data/split/extconf.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  require './mkmf2.rb'
4
4
 
5
- $CFLAGS += " -O2 -Wall "
5
+ $CFLAGS += " -O2 -g -Wall -Werror-implicit-function-declaration"
6
6
 
7
7
  # Now, if you want to install the include file, you need to
8
8
  # set the EXTCONF_RB_INCLUDE
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tioga
3
3
  version: !ruby/object:Gem::Version
4
- version: "1.7"
4
+ version: "1.8"
5
5
  platform: ruby
6
6
  authors: []
7
7
 
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: split/scripts
10
10
  cert_chain: []
11
11
 
12
- date: 2008-01-28 00:00:00 +01:00
12
+ date: 2008-04-05 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -28,29 +28,28 @@ extra_rdoc_files: []
28
28
  files:
29
29
  - split/Tioga/wrappers.c
30
30
  - split/Tioga/init.c
31
- - split/Tioga/shared/pdf_font_dicts.c
32
- - split/Tioga/shared/pdfcoords.c
33
- - split/Tioga/shared/pdftext.c
34
- - split/Tioga/shared/axes.c
35
- - split/Tioga/shared/makers.c
36
- - split/Tioga/shared/pdfpath.c
37
- - split/Tioga/shared/pdfcolor.c
38
- - split/Tioga/shared/texout.c
39
- - split/Tioga/shared/pdffile.c
40
- - split/Tioga/shared/pdfimage.c
41
31
  - split/Tioga/figures.c
42
32
  - split/Tioga/generic.c
33
+ - split/Tioga/pdf_font_dicts.c
34
+ - split/Tioga/pdfcoords.c
35
+ - split/Tioga/pdftext.c
36
+ - split/Tioga/axes.c
37
+ - split/Tioga/makers.c
38
+ - split/Tioga/pdfpath.c
39
+ - split/Tioga/pdfcolor.c
40
+ - split/Tioga/texout.c
41
+ - split/Tioga/pdffile.c
42
+ - split/Tioga/pdfimage.c
43
43
  - split/Function/function.c
44
44
  - split/Function/joint_qsort.c
45
45
  - split/Dvector/dvector.c
46
46
  - split/Dtable/dtable.c
47
47
  - split/Flate/flate.c
48
- - split/symbols.c
49
48
  - split/Tioga/generic.h
50
49
  - split/Tioga/pdfs.h
51
50
  - split/Tioga/wrappers.h
52
- - split/Tioga/figures.h
53
51
  - split/Tioga/symbols.h
52
+ - split/Tioga/figures.h
54
53
  - split/Tioga/defs.h
55
54
  - split/Tioga/safe_double.h
56
55
  - split/Tioga/namespace.h
@@ -62,29 +61,25 @@ files:
62
61
  - split/Function/safe_double.h
63
62
  - split/Function/namespace.h
64
63
  - split/Function/dvector.h
65
- - split/namespace.h
66
- - split/Dvector/include/dvector.h
67
64
  - split/Dvector/dvector_intern.h
68
65
  - split/Dvector/symbols.h
69
66
  - split/Dvector/defs.h
70
67
  - split/Dvector/safe_double.h
71
68
  - split/Dvector/namespace.h
72
- - split/Dtable/include/dtable.h
73
- - split/Dtable/dtable_intern.h
74
69
  - split/Dtable/symbols.h
70
+ - split/Dtable/dtable_intern.h
75
71
  - split/Dtable/defs.h
76
72
  - split/Dtable/safe_double.h
77
73
  - split/Dtable/namespace.h
78
74
  - split/Dtable/dvector.h
79
- - split/defs.h
80
- - split/Flate/include/flate.h
81
- - split/Flate/flate_intern.h
82
75
  - split/Flate/symbols.h
76
+ - split/Flate/flate_intern.h
83
77
  - split/Flate/defs.h
84
78
  - split/Flate/safe_double.h
85
79
  - split/Flate/namespace.h
86
- - split/symbols.h
87
- - split/safe_double.h
80
+ - split/Dvector/include/dvector.h
81
+ - split/Dtable/include/dtable.h
82
+ - split/Flate/include/flate.h
88
83
  - split/Tioga/lib/Rectangles.rb
89
84
  - split/Tioga/lib/Colorbars.rb
90
85
  - split/Tioga/lib/Shading.rb
@@ -113,10 +108,10 @@ files:
113
108
  - split/Tioga/lib/tioga_ui_cmds.rb
114
109
  - split/Tioga/lib/Images.rb
115
110
  - split/Tioga/lib/Doc.rb
111
+ - split/Tioga/lib/TexPreamble.rb
116
112
  - split/Tioga/lib/Titles_and_Labels.rb
117
113
  - split/Tioga/lib/Transparency.rb
118
114
  - split/Tioga/lib/ColorConstants.rb
119
- - split/Tioga/lib/TexPreamble.rb
120
115
  - split/Tioga/mk_tioga_sty.rb
121
116
  - split/Tioga/extconf.rb
122
117
  - split/Function/lib/Function_extras.rb
@@ -129,6 +124,11 @@ files:
129
124
  - split/Flate/extconf.rb
130
125
  - split/extconf.rb
131
126
  - split/mkmf2.rb
127
+ - split/namespace.h
128
+ - split/defs.h
129
+ - split/symbols.h
130
+ - split/safe_double.h
131
+ - split/symbols.c
132
132
  - tests/profile_Dvector
133
133
  - tests/benchmark_dvector_reads.rb
134
134
  - tests/dvector_read_test.data
@@ -163,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
163
163
  version:
164
164
  requirements: []
165
165
 
166
- rubyforge_project:
166
+ rubyforge_project: tioga
167
167
  rubygems_version: 1.0.1
168
168
  signing_key:
169
169
  specification_version: 2
@@ -1,1220 +0,0 @@
1
- /* makers.c */
2
- /*
3
- Copyright (C) 2005 Bill Paxton
4
- Copyright (C) 2007 Taro Sato
5
-
6
- This file is part of Tioga.
7
-
8
- Tioga is free software; you can redistribute it and/or modify
9
- it under the terms of the GNU General Library Public License as published
10
- by the Free Software Foundation; either version 2 of the License, or
11
- (at your option) any later version.
12
-
13
- Tioga is distributed in the hope that it will be useful,
14
- but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- GNU Library General Public License for more details.
17
-
18
- You should have received a copy of the GNU Library General Public License
19
- along with Tioga; if not, write to the Free Software
20
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
- */
22
-
23
- #include "figures.h"
24
- #include "generic.h"
25
-
26
-
27
- /* Lines */
28
-
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
- }
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];
56
- }
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]);
62
- }
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;
121
- }
122
-
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;
181
- }
182
- ys[0] = yfirst;
183
- for (i = 0, j = 1; i < xdlen; ++i, j += 2) {
184
- ys[j] = ys[j + 1] = y_data[i];
185
- }
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;
213
- }
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
-
251
- /*
252
- CONREC: A Contouring Subroutine
253
- written by Paul Bourke
254
- see: http://astronomy.swin.edu.au/~pbourke/projection/conrec/
255
-
256
- Copyright (c) 1996-1997 Nicholas Yue
257
-
258
- This software is copyrighted by Nicholas Yue. This code is base on the work of
259
- Paul D. Bourke CONREC.F routine
260
-
261
- The authors hereby grant permission to use, copy, and distribute this
262
- software and its documentation for any purpose, provided that existing
263
- copyright notices are retained in all copies and that this notice is included
264
- verbatim in any distributions. Additionally, the authors grant permission to
265
- modify this software and its documentation for any purpose, provided that
266
- such modifications are not distributed without the explicit consent of the
267
- authors and that existing copyright notices are retained in all copies. Some
268
- of the algorithms implemented by this software are patented, observe all
269
- applicable patent law.
270
-
271
- IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
272
- DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
273
- OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
274
- EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275
-
276
- THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
277
- BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
278
- PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN
279
- "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
280
- MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
281
- */
282
-
283
- //=============================================================================
284
- //
285
- // CONREC is a contouring subroutine for rectangularily spaced data.
286
- //
287
- // It emits calls to a line drawing subroutine supplied by the user
288
- // which draws a contour map corresponding to real*4data on a randomly
289
- // spaced rectangular grid. The coordinates emitted are in the same
290
- // units given in the x() and y() arrays.
291
- //
292
- // Any number of contour levels may be specified but they must be
293
- // in order of increasing value.
294
- //
295
- // As this code is ported from FORTRAN-77, please be very careful of the
296
- // various indices like ilb,iub,jlb and jub, remeber that C/C++ indices
297
- // starts from zero (0)
298
- //
299
- //=============================================================================
300
- #include <stdio.h>
301
- #include <math.h>
302
-
303
- #define xsect(p1,p2) (h[p2]*xh[p1]-h[p1]*xh[p2])/(h[p2]-h[p1])
304
- #define ysect(p1,p2) (h[p2]*yh[p1]-h[p1]*yh[p2])/(h[p2]-h[p1])
305
- #define min(x,y) (x<y?x:y)
306
- #define max(x,y) (x>y?x:y)
307
-
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
- }
318
-
319
- static int conrec(double **d,
320
- int ilb,
321
- int iub,
322
- int jlb,
323
- int jub,
324
- double *x,
325
- double *y,
326
- int nc,
327
- double *z,
328
- long *dest_len_ptr,
329
- double **dest_xs_ptr,
330
- double **dest_ys_ptr,
331
- long *dest_sz_ptr,
332
- OBJ_PTR gaps,
333
- double x_limit,
334
- double y_limit,
335
- int *ierr)
336
- // d ! matrix of data to contour
337
- // ilb,iub,jlb,jub ! index bounds of data matrix
338
- // x ! data matrix column coordinates
339
- // y ! data matrix row coordinates
340
- // nc ! number of contour levels
341
- // z ! contour levels in increasing order
342
- {
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];
351
- //===========================================================================
352
- // The indexing of im and jm should be noted as it has to start from zero
353
- // unlike the fortran counter part
354
- //===========================================================================
355
- int im[4] = {0,1,1,0},jm[4]={0,0,1,1};
356
- //===========================================================================
357
- // Note that castab is arranged differently from the FORTRAN code because
358
- // Fortran and C/C++ arrays are transposes of each other, in this case
359
- // it is more tricky as castab is in 3 dimension
360
- //===========================================================================
361
- int castab[3][3][3] =
362
- {
363
- {
364
- {0,0,8},{0,2,5},{7,6,9}
365
- },
366
- {
367
- {0,3,4},{1,3,1},{4,3,0}
368
- },
369
- {
370
- {9,6,7},{5,2,0},{8,0,0}
371
- }
372
- };
373
- for (j=(jub-1);j>=jlb;j--) {
374
- for (i=ilb;i<=iub-1;i++) {
375
- double temp1,temp2;
376
- temp1 = min(d[i][j],d[i][j+1]);
377
- temp2 = min(d[i+1][j],d[i+1][j+1]);
378
- dmin = min(temp1,temp2);
379
- temp1 = max(d[i][j],d[i][j+1]);
380
- temp2 = max(d[i+1][j],d[i+1][j+1]);
381
- dmax = max(temp1,temp2);
382
- if (dmax>=z[0]&&dmin<=z[nc-1]) {
383
- for (k=0;k<nc;k++) {
384
- if (z[k]>=dmin&&z[k]<=dmax) {
385
- for (m=4;m>=0;m--) {
386
- if (m>0) {
387
- //=============================================================
388
- // The indexing of im and jm should be noted as it has to
389
- // start from zero
390
- //=============================================================
391
- h[m] = d[i+im[m-1]][j+jm[m-1]]-z[k];
392
- xh[m] = x[i+im[m-1]];
393
- yh[m] = y[j+jm[m-1]];
394
- } else {
395
- h[0] = 0.25*(h[1]+h[2]+h[3]+h[4]);
396
- xh[0]=0.5*(x[i]+x[i+1]);
397
- yh[0]=0.5*(y[j]+y[j+1]);
398
- }
399
- if (h[m]>0.0) {
400
- sh[m] = 1;
401
- } else if (h[m]<0.0) {
402
- sh[m] = -1;
403
- } else
404
- sh[m] = 0;
405
- }
406
- //=================================================================
407
- //
408
- // Note: at this stage the relative heights of the corners and the
409
- // centre are in the h array, and the corresponding coordinates are
410
- // in the xh and yh arrays. The centre of the box is indexed by 0
411
- // and the 4 corners by 1 to 4 as shown below.
412
- // Each triangle is then indexed by the parameter m, and the 3
413
- // vertices of each triangle are indexed by parameters m1,m2,and
414
- // m3.
415
- // It is assumed that the centre of the box is always vertex 2
416
- // though this isimportant only when all 3 vertices lie exactly on
417
- // the same contour level, in which case only the side of the box
418
- // is drawn.
419
- //
420
- //
421
- // vertex 4 +-------------------+ vertex 3
422
- // | \ / |
423
- // | \ m-3 / |
424
- // | \ / |
425
- // | \ / |
426
- // | m=2 X m=2 | the centre is vertex 0
427
- // | / \ |
428
- // | / \ |
429
- // | / m=1 \ |
430
- // | / \ |
431
- // vertex 1 +-------------------+ vertex 2
432
- //
433
- //
434
- //
435
- // Scan each triangle in the box
436
- //
437
- //=================================================================
438
- for (m=1;m<=4;m++) {
439
- m1 = m;
440
- m2 = 0;
441
- if (m!=4)
442
- m3 = m+1;
443
- else
444
- m3 = 1;
445
- case_value = castab[sh[m1]+1][sh[m2]+1][sh[m3]+1];
446
- if (case_value!=0) {
447
- switch (case_value) {
448
- //===========================================================
449
- // Case 1 - Line between vertices 1 and 2
450
- //===========================================================
451
- case 1:
452
- x1=xh[m1];
453
- y1=yh[m1];
454
- x2=xh[m2];
455
- y2=yh[m2];
456
- break;
457
- //===========================================================
458
- // Case 2 - Line between vertices 2 and 3
459
- //===========================================================
460
- case 2:
461
- x1=xh[m2];
462
- y1=yh[m2];
463
- x2=xh[m3];
464
- y2=yh[m3];
465
- break;
466
- //===========================================================
467
- // Case 3 - Line between vertices 3 and 1
468
- //===========================================================
469
- case 3:
470
- x1=xh[m3];
471
- y1=yh[m3];
472
- x2=xh[m1];
473
- y2=yh[m1];
474
- break;
475
- //===========================================================
476
- // Case 4 - Line between vertex 1 and side 2-3
477
- //===========================================================
478
- case 4:
479
- x1=xh[m1];
480
- y1=yh[m1];
481
- x2=xsect(m2,m3);
482
- y2=ysect(m2,m3);
483
- break;
484
- //===========================================================
485
- // Case 5 - Line between vertex 2 and side 3-1
486
- //===========================================================
487
- case 5:
488
- x1=xh[m2];
489
- y1=yh[m2];
490
- x2=xsect(m3,m1);
491
- y2=ysect(m3,m1);
492
- break;
493
- //===========================================================
494
- // Case 6 - Line between vertex 3 and side 1-2
495
- //===========================================================
496
- case 6:
497
- x1=xh[m3];
498
- y1=yh[m3];
499
- x2=xsect(m1,m2);
500
- y2=ysect(m1,m2);
501
- break;
502
- //===========================================================
503
- // Case 7 - Line between sides 1-2 and 2-3
504
- //===========================================================
505
- case 7:
506
- x1=xsect(m1,m2);
507
- y1=ysect(m1,m2);
508
- x2=xsect(m2,m3);
509
- y2=ysect(m2,m3);
510
- break;
511
- //===========================================================
512
- // Case 8 - Line between sides 2-3 and 3-1
513
- //===========================================================
514
- case 8:
515
- x1=xsect(m2,m3);
516
- y1=ysect(m2,m3);
517
- x2=xsect(m3,m1);
518
- y2=ysect(m3,m1);
519
- break;
520
- //===========================================================
521
- // Case 9 - Line between sides 3-1 and 1-2
522
- //===========================================================
523
- case 9:
524
- x1=xsect(m3,m1);
525
- y1=ysect(m3,m1);
526
- x2=xsect(m1,m2);
527
- y2=ysect(m1,m2);
528
- break;
529
- default:
530
- break;
531
- }
532
- double dx = x1 - x_prev, dy = y1 - y_prev;
533
- if (dx < 0) dx = -dx; if (dy < 0) dy = -dy;
534
- if (num_pts == 0 || dx > x_limit || dy > y_limit) {
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++;
537
- }
538
- PUSH_POINT(x2,y2); num_pts++;
539
- x_prev = x2; y_prev = y2;
540
- }
541
- }
542
- }
543
- }
544
- }
545
- }
546
- }
547
- return 0;
548
- }
549
-
550
- /* end of conrec */
551
-
552
-
553
-
554
-
555
-
556
-
557
-
558
-
559
- // the following code is from Gri
560
-
561
-
562
-
563
-
564
- #include <math.h>
565
- #include <stdio.h>
566
- #include <string.h>
567
-
568
- // globals to this file
569
- static int nx_1, ny_1, iGT, jGT, iLE, jLE;
570
-
571
- static void free_space_for_curve(void);
572
- static void get_space_for_curve(int *ierr);
573
- static void draw_the_contour(
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);
580
-
581
- static bool trace_contour(double z0,
582
- double *x,
583
- double *y,
584
- double **z,
585
- double **legit,
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);
592
-
593
- static int FLAG(int ni, int nj, int ind, int *ierr);
594
- static int append_segment(double xr, double yr, double zr, double OKr,
595
- double xs, double ys, double zs, double OKs,
596
- double z0, int *ierr);
597
-
598
- // Space for curve, shared by several routines
599
- static double *xcurve, *ycurve;
600
- static bool *legitcurve;
601
- #define INITIAL_CURVE_SIZE 100
602
- static int num_in_curve, max_in_curve, num_in_path;
603
- static bool curve_storage_exists = false;
604
-
605
-
606
- static void
607
- free_space_for_curve(void)
608
- {
609
- if (curve_storage_exists) {
610
- free(xcurve);
611
- free(ycurve);
612
- free(legitcurve);
613
- curve_storage_exists = false;
614
- }
615
- num_in_curve = 0;
616
- num_in_path = 0;
617
- }
618
-
619
- static void
620
- get_space_for_curve(int *ierr)
621
- {
622
- max_in_curve = INITIAL_CURVE_SIZE;
623
- if(curve_storage_exists) {
624
- RAISE_ERROR("storage is messed up (internal error)", ierr);
625
- return;
626
- }
627
- xcurve = ALLOC_N_double(max_in_curve);
628
- ycurve = ALLOC_N_double(max_in_curve);
629
- legitcurve = ALLOC_N_bool(max_in_curve);
630
- curve_storage_exists = true;
631
- num_in_curve = 0;
632
- num_in_path = 0;
633
- }
634
-
635
-
636
-
637
- // gr_contour() -- draw contour line for gridded data
638
- //
639
- // DESCRIPTION: Draws a contour for the value z0, through data z[i][j] defined
640
- // on the rectangular grid x[i] and y[j] (where 0<=i<nx and 0<=j<ny). That
641
- // the grid is rectangular but needn't be square or regular. Contours are
642
- // drawn only in triangular regions surrounded by 3 good points (ie, 3 points
643
- // with legit[i][j] != 0.0).
644
- //
645
- // The contour is labelled, with the string// lab, at intervals of
646
- // contour_space_later centimeters, starting with a space of
647
- // contour_space_first from the beginning of the trace.
648
- //
649
- static void
650
- gr_contour(
651
- double *x,
652
- double *y,
653
- double **z,
654
- double **legit,
655
- int nx,
656
- int ny,
657
- double z0,
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)
664
- {
665
- register int i, j;
666
- // Test for errors
667
- if (nx <= 0) { RAISE_ERROR("nx<=0 (internal error)", ierr); return; }
668
- if (ny <= 0) { RAISE_ERROR("ny<=0 (internal error)", ierr); return; }
669
- // Save some globals
670
- nx_1 = nx - 1;
671
- ny_1 = ny - 1;
672
- // Clear all switches.
673
- FLAG(nx, ny, -1, ierr);
674
- // Get space for the curve.
675
- get_space_for_curve(ierr);
676
- if (*ierr != 0) return;
677
-
678
- // Search for a contour intersecting various places on the grid. Whenever
679
- // a contour is found to be between two grid points, call trace_contour()
680
- // after defining the global variables iLE,jLE,iGT,jGT so that
681
- // z[iLE]jLE] <= z0 < z[iGT][jGT], where legit[iLE][jLE] != 0
682
- // and legit[iGT][jGT] != 0.
683
- //
684
- // NOTE: always start a contour running upwards (to greater j), between
685
- // two sideways neighboring points (same j). Later, in trace_contour(),
686
- // test 'locate' for value 5. If it's 5, it means that the same geometry
687
- // obtains, so set a flag and check whether already set. If already
688
- // set, it means we've traced this contour before, so trace_contour()
689
- // knows to stop then.
690
-
691
- // Search bottom
692
- for (i = 1; i < nx; i++) {
693
- j = 0;
694
- while (j < ny_1) {
695
- // move north to first legit point
696
- while (j < ny_1
697
- && (legit == NULL || !(legit[i][j] != 0.0 && legit[i - 1][j] != 0.0))
698
- ) {
699
- j++;
700
- }
701
- // trace a contour if it hits here
702
- if (j < ny_1 && z[i][j] > z0 && z[i - 1][j] <= z0) {
703
- iLE = i - 1;
704
- jLE = j;
705
- iGT = i;
706
- jGT = j;
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;
709
- }
710
- // Space through legit points, that is, skipping through good
711
- // data looking for another island of bad data which will
712
- // thus be a new 'bottom edge'.
713
- while (j < ny_1 && (legit == NULL || (legit[i][j] != 0.0 && legit[i - 1][j] != 0.0)))
714
- j++;
715
- }
716
- }
717
-
718
- // search right edge
719
- for (j = 1; j < ny; j++) {
720
- i = nx_1;
721
- while (i > 0) {
722
- // move west to first legit point
723
- while (i > 0 && (legit == NULL || !(legit[i][j] != 0.0 && legit[i][ j - 1] != 0.0)))
724
- i--;
725
- // trace a contour if it hits here
726
- if (i > 0 && z[i][j] > z0 && z[i][j - 1] <= z0) {
727
- iLE = i;
728
- jLE = j - 1;
729
- iGT = i;
730
- jGT = j;
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;
733
- }
734
- // space through legit points
735
- while (i > 0 && (legit == NULL || (legit[i][j] != 0.0 && legit[i][ j - 1] != 0.0)))
736
- i--;
737
- }
738
- }
739
-
740
- // search top edge
741
- for (i = nx_1 - 1; i > -1; i--) {
742
- j = ny_1;
743
- while (j > 0) {
744
- while (j > 0 && (legit == NULL || !(legit[i][j] != 0.0 && legit[i + 1][ j] != 0.0)))
745
- j--;
746
- // trace a contour if it hits here
747
- if (j > 0 && z[i][j] > z0 && z[i + 1][ j] <= z0) {
748
- iLE = i + 1;
749
- jLE = j;
750
- iGT = i;
751
- jGT = j;
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;
754
- }
755
- // space through legit points
756
- while (j > 0 && (legit == NULL || (legit[i][j] != 0.0 && legit[i + 1][ j] != 0.0)))
757
- j--;
758
- }
759
- }
760
-
761
- // search left edge
762
- for (j = ny_1 - 1; j > -1; j--) {
763
- i = 0;
764
- while (i < nx_1) {
765
- while (i < nx_1 && (legit == NULL || !(legit[i][j] != 0.0 && legit[i][ j + 1] != 0.0)))
766
- i++;
767
- // trace a contour if it hits here
768
- if (i < nx_1 && z[i][j] > z0 && z[i][j + 1] <= z0) {
769
- iLE = i;
770
- jLE = j + 1;
771
- iGT = i;
772
- jGT = j;
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;
775
- }
776
- // space through legit points
777
- while (i < nx_1 && (legit == NULL || (legit[i][j] != 0.0 && legit[i][ j + 1] != 0.0)))
778
- i++;
779
- }
780
- }
781
-
782
- // Search interior. Pass up from bottom (starting at left), through all
783
- // interior points. Look for contours which enter, with high to right,
784
- // between iLE on left and iGT on right.
785
- for (j = 1; j < ny_1; j++) {
786
- int flag_is_set;
787
- for (i = 1; i < nx; i++) {
788
- // trace a contour if it hits here
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
- }
795
- if (!flag_is_set
796
- && (legit == NULL || legit[i][j] != 0.0)
797
- && z[i][j] > z0
798
- && (legit == NULL || legit[i - 1][j] != 0.0)
799
- && z[i - 1][j] <= z0) {
800
- iLE = i - 1;
801
- jLE = j;
802
- iGT = i;
803
- jGT = j;
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;
806
- }
807
- }
808
- }
809
- // Free up space.
810
- free_space_for_curve();
811
- FLAG(nx, ny, 2, ierr);
812
- }
813
-
814
- // trace_contour() -- trace_contour a contour line with high values of z to
815
- // it's right. Stores points in (*xcurve, *ycurve) and the legit flag is
816
- // stored in *legitcurve; initially these must be empty; you must also free
817
- // them after this call, so that the next call will work OK.
818
- static bool
819
- trace_contour(double z0,
820
- double *x,
821
- double *y,
822
- double **z,
823
- double **legit,
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
830
- )
831
- {
832
- int i, ii, j, jj;
833
- double zp, vx, vy, zcentre;
834
- int locate;
835
- // locate tells where delta-grid point is. It codes as follows to
836
- // i_test[] and j_test[] 6 7 8 3 4 5 0 1 2
837
- static int i_test[9] = {
838
- 0, 1, 1, // 6 7 8
839
- 0, 9, 0, // 3 4 5
840
- -1, -1, 0 // 0 1 2
841
- };
842
- static int j_test[9] =
843
- {
844
- -1, 0, 0, // 6 7 8
845
- -1, 9, 1, // 3 4 5
846
- 0, 0, 1 // 0 1 2
847
- };
848
- static int dtest[9] =
849
- {
850
- 0, 1, 0, // 6 7 8
851
- 1, 0, 1, // 3 4 5
852
- 0, 1, 0 // 0 1 2
853
- };
854
-
855
-
856
- // Trace the curve, storing results with append_segment() into *xcurve,
857
- // *ycurve, *legitcurve. When done, call draw_the_contour(), which draws
858
- // the contour stored in these arrays.
859
- while (true) {
860
-
861
- append_segment(x[iLE], y[jLE], z[iLE][jLE], (legit == NULL)? 1.0: legit[iLE][jLE],
862
- x[iGT], y[jGT], z[iGT][jGT], (legit == NULL)? 1.0: legit[iGT][jGT],
863
- z0, ierr);
864
- if (*ierr != 0) return false;
865
- // Find the next point to check through a table lookup.
866
- locate = 3 * (jGT - jLE) + (iGT - iLE) + 4;
867
- i = iLE + i_test[locate];
868
- j = jLE + j_test[locate];
869
-
870
-
871
- // Did it hit an edge?
872
- if (i > nx_1 || i < 0 || j > ny_1 || j < 0) {
873
- draw_the_contour(dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
874
- if (*ierr != 0) return false;
875
- return true; // all done
876
- }
877
-
878
- // Test if retracing an existing contour. See explanation
879
- // above, in grcntour(), just before search starts.
880
- if (locate == 5) {
881
- int already_set = FLAG(iGT, jGT, 1, ierr);
882
- if (*ierr != 0) return false;
883
- if (already_set < 0) {
884
- RAISE_ERROR("ran out of storage (internal error)", ierr);
885
- return false;
886
- }
887
- if (already_set) {
888
- draw_the_contour(dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
889
- if (*ierr != 0) return false;
890
- return true; // all done
891
- }
892
- }
893
-
894
- // Following new for 2.1.13
895
- if (legit != NULL && legit[i][j] == 0.0) {
896
- draw_the_contour(dest_len_ptr, dest_xs_ptr, dest_ys_ptr, dest_sz_ptr, gaps, ierr);
897
- if (*ierr != 0) return false;
898
- return true; // all done
899
- }
900
-
901
- if (!dtest[locate]) {
902
- zp = z[i][j];
903
- if (zp > z0)
904
- iGT = i, jGT = j;
905
- else
906
- iLE = i, jLE = j;
907
- continue;
908
- }
909
- vx = (x[iGT] + x[i]) * 0.5;
910
- vy = (y[jGT] + y[j]) * 0.5;
911
- locate = 3 * (jGT - j) + iGT - i + 4;
912
- // Fourth point in rectangular boundary
913
- ii = i + i_test[locate];
914
- jj = j + j_test[locate];
915
- bool legit_diag =
916
- (legit == NULL || (legit[iLE][jLE] != 0.0
917
- && legit[iGT][jGT] != 0.0
918
- && legit[i][j] != 0.0
919
- && legit[ii][jj] != 0.0)) ? true : false;
920
- zcentre = 0.25 * (z[iLE][jLE] + z[iGT][jGT] + z[i][j] + z[ii][jj]);
921
-
922
- if (zcentre <= z0) {
923
- append_segment(x[iGT], y[jGT], z[iGT][jGT], (legit == NULL)? 1.0: legit[iGT][jGT],
924
- vx, vy, zcentre, legit_diag,
925
- z0, ierr);
926
- if (*ierr != 0) return false;
927
- if (z[ii][jj] <= z0) {
928
- iLE = ii, jLE = jj;
929
- continue;
930
- }
931
- append_segment(x[ii], y[jj], z[ii][jj], (legit == NULL)? 1.0: legit[ii][jj],
932
- vx, vy, zcentre, legit_diag,
933
- z0, ierr);
934
- if (*ierr != 0) return false;
935
- if (z[i][j] <= z0) {
936
- iGT = ii, jGT = jj;
937
- iLE = i, jLE = j;
938
- continue;
939
- }
940
- append_segment(x[i], y[j], z[i][j], (legit == NULL)? 1.0: legit[i][j],
941
- vx, vy, zcentre, legit_diag,
942
- z0, ierr);
943
- if (*ierr != 0) return false;
944
- iGT = i, jGT = j;
945
- continue;
946
- }
947
- append_segment(vx, vy, zcentre, legit_diag,
948
- x[iLE], y[jLE], z[iLE][jLE], (legit == NULL)? 1.0: legit[iLE][jLE],
949
- z0, ierr);
950
- if (*ierr != 0) return false;
951
- if (z[i][j] > z0) {
952
- iGT = i, jGT = j;
953
- continue;
954
- }
955
- append_segment(vx, vy, zcentre, legit_diag,
956
- x[i], y[j], z[i][j], (legit == NULL)? 1.0: legit[i][j],
957
- z0, ierr);
958
- if (*ierr != 0) return false;
959
- if (z[ii][jj] <= z0) {
960
- append_segment(vx, vy, zcentre, legit_diag,
961
- x[ii], y[jj], z[ii][jj], (legit == NULL)? 1.0: legit[ii][jj],
962
- z0, ierr);
963
- if (*ierr != 0) return false;
964
- iLE = ii;
965
- jLE = jj;
966
- continue;
967
- }
968
- iLE = i;
969
- jLE = j;
970
- iGT = ii;
971
- jGT = jj;
972
- }
973
- }
974
-
975
- // append_segment() -- append a line segment on the contour
976
- static double xplot_last, yplot_last;
977
- static int
978
- append_segment(double xr, double yr, double zr, double OKr,
979
- double xs, double ys, double zs, double OKs,
980
- double z0, int *ierr)
981
- {
982
- if (zr == zs) { RAISE_ERROR("Contouring problem: zr = zs, which is illegal", ierr); return 0; }
983
- double frac = (zr - z0) / (zr - zs);
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; }
986
- double xplot = xr - frac * (xr - xs);
987
- double yplot = yr - frac * (yr - ys);
988
- // Avoid replot, which I suppose must be possible, given this code
989
- if (num_in_curve > 0 && xplot == xplot_last && yplot == yplot_last)
990
- return 1;
991
- if (num_in_curve > max_in_curve - 1) {
992
- // Get new storage if running on empty. Better to
993
- // do this with an STL vector class
994
- max_in_curve *= 2;
995
- int i;
996
- double *tmp = ALLOC_N_double(num_in_curve);
997
- for (i = 0; i < num_in_curve; i++) tmp[i] = xcurve[i];
998
- free(xcurve); xcurve = ALLOC_N_double(max_in_curve);
999
- for (i = 0; i < num_in_curve; i++) xcurve[i] = tmp[i];
1000
- for (i = 0; i < num_in_curve; i++) tmp[i] = ycurve[i];
1001
- free(ycurve); ycurve = ALLOC_N_double(max_in_curve);
1002
- for (i = 0; i < num_in_curve; i++) ycurve[i] = tmp[i];
1003
- free(tmp);
1004
- bool *tmpl = ALLOC_N_bool(num_in_curve);
1005
- for (i = 0; i < num_in_curve; i++) tmpl[i] = legitcurve[i];
1006
- free(legitcurve); legitcurve = ALLOC_N_bool(max_in_curve);
1007
- for (i = 0; i < num_in_curve; i++) legitcurve[i] = tmpl[i];
1008
- free(tmpl);
1009
- }
1010
- // A segment is appended only if both the present point and the last
1011
- // point came by interpolating between OK points.
1012
- xcurve[num_in_curve] = xplot;
1013
- ycurve[num_in_curve] = yplot;
1014
- if (OKr != 0.0 && OKs != 0.0)
1015
- legitcurve[num_in_curve] = true;
1016
- else
1017
- legitcurve[num_in_curve] = false;
1018
- num_in_curve++;
1019
- xplot_last = xplot;
1020
- yplot_last = yplot;
1021
- return 1;
1022
- }
1023
-
1024
-
1025
- // Draw contour stored in (xcurve[],ycurve[],legitcurve[]), possibly with
1026
- // labels (depending on global Label_contours).
1027
- //
1028
- #define FACTOR 3.0 // contour must be FACTOR*len long to be labelled
1029
- static void
1030
- draw_the_contour(
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)
1037
- {
1038
- if (num_in_curve == 1) {
1039
- num_in_curve = 0;
1040
- return;
1041
- }
1042
- int i, k;
1043
- for (i = 0, k = 0; i < num_in_curve; i++) {
1044
- if (legitcurve[i] == true) {
1045
- // PUSH_POINT does num_in_path++
1046
- PUSH_POINT(xcurve[i],ycurve[i]); num_in_path++;
1047
- } else {
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
- }
1052
- k = num_in_path;
1053
- }
1054
- }
1055
- Array_Push(gaps, Integer_New(num_in_path), ierr);
1056
- num_in_curve = 0;
1057
- }
1058
-
1059
- // FLAG() -- check flag for gr_contour() and trace_contour()
1060
- // ni = row (or, if ind==-1, number of rows)
1061
- // nj = col (or, if ind==-1, number of cols)
1062
- // if (ind == -1), get flag storage space; initialize flags to 0
1063
- // if (ind == 1), check flag and then set it
1064
- // if (ind == 2), clear the flag storage space
1065
- // if (ind == 0), check flag, return value
1066
- // RETURN value: Normally, the flag value (0 or 1). If the storage is
1067
- // exhausted, return a number <0.
1068
- #define NBITS 32
1069
- static int
1070
- FLAG(int ni, int nj, int ind, int *ierr)
1071
- {
1072
- static bool flag_storage_exists = false;
1073
- static unsigned long *flag, mask[NBITS];
1074
- static int size;
1075
- static int ni_max; // x-dimension is saved
1076
- int i, ipos, iword, ibit, return_value;
1077
- switch (ind) {
1078
- case -1:
1079
- // Allocate storage for flag array
1080
- if (flag_storage_exists) {
1081
- RAISE_ERROR("storage is messed up (internal error)", ierr); return 0; }
1082
- size = 1 + ni * nj / NBITS; // total storage array length
1083
- flag = ALLOC_N_unsigned_long(size);
1084
- // Create mask
1085
- mask[0] = 1;
1086
- for (i = 1; i < NBITS; i++)
1087
- mask[i] = 2 * mask[i - 1];
1088
- for (i = 0; i < size; i++) // Zero out flag
1089
- flag[i] = 0;
1090
- ni_max = ni; // Save for later
1091
- flag_storage_exists = true;
1092
- return 0;
1093
- case 2:
1094
- if (!flag_storage_exists) {
1095
- RAISE_ERROR("No flag storage exists", ierr); return 0; }
1096
- free(flag);
1097
- flag_storage_exists = false;
1098
- return 0;
1099
- default:
1100
- if (!flag_storage_exists) {
1101
- RAISE_ERROR("No flag storage exists", ierr); return 0; }
1102
- break;
1103
- }
1104
- // ind was not -1 or 2
1105
- // Find location of bit.
1106
- ipos = nj * ni_max + ni;
1107
- iword = ipos / NBITS;
1108
- ibit = ipos - iword * NBITS;
1109
- // Check for something being broken here, causing to run out of space.
1110
- // This should never happen, but may as well check.
1111
- if (iword >= size)
1112
- return (-99); // no space
1113
- // Get flag.
1114
- return_value = (0 != (*(flag + iword) & mask[ibit]));
1115
- // If ind=1 and flag wasn't set, set the flag
1116
- if (ind == 1 && !return_value)
1117
- flag[iword] |= mask[ibit];
1118
- // Return the flag value
1119
- return return_value;
1120
- }
1121
- #undef NBITS
1122
-
1123
- // end of contour code from Gri
1124
-
1125
-
1126
-
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;
1150
- }
1151
- if (xlen != num_columns || ylen != num_rows) {
1152
- RAISE_ERROR("Sorry: bad args for make_contour. Needs xs.size == num columns and ys.size == num rows.", ierr); return;
1153
- }
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
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
- }
1171
- }
1172
-
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
1181
- ) {
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;
1218
- }
1219
-
1220
-