1 /*
2 Gri - A language for scientific graphics programming
3 Copyright (C) 2008 Daniel Kelley
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <ctype.h>
24 #include <stddef.h>
25 #include "extern.hh"
26 #include "files.hh"
27 #include "superus.hh"
28
29 // `interpolate x grid to .left. .right. .inc.|{/.cols.}'
30 // `interpolate y grid to .bottom. .top. .inc.|{/.rows.}'
31 bool
interpolateCmd()32 interpolateCmd()
33 {
34 bool is_x = false;
35 if (word_is(1, "x"))
36 is_x = true;
37 else if (!word_is(1, "y")) {
38 err("Second word must be `x' or `y'");
39 }
40 int num;
41 double start, stop, increment;
42 if (is_x) {
43 Require(getdnum(_word[4], &start), READ_WORD_ERROR(".left."));
44 Require(getdnum(_word[5], &stop), READ_WORD_ERROR(".right."));
45 } else {
46 Require(getdnum(_word[4], &start), READ_WORD_ERROR(".bottom."));
47 Require(getdnum(_word[5], &stop), READ_WORD_ERROR(".top."));
48 }
49 switch (_nword) {
50 case 7:
51 if (is_x) {
52 Require(getdnum(_word[6], &increment),
53 READ_WORD_ERROR(".cols."));
54 } else {
55 Require(getdnum(_word[6], &increment),
56 READ_WORD_ERROR(".rows."));
57 }
58 num = int(1 + (stop - start) / increment);
59 break;
60 case 8:
61 Require(word_is(6, "/"), err("6-th word must be `/'"));
62 Require(getinum(_word[7], &num), READ_WORD_ERROR(".inc."));
63 if (num < 2) {
64 err("Increment .inc. must exceed 1");
65 return false;
66 }
67 increment = (stop - start) / (num - 1);
68 break;
69 }
70 if (num < 0) {
71 err("Sign of increment disagrees with start and stop values");
72 return false;
73 }
74 //
75 // The grid must already exist
76 if (!_grid_exists) {
77 err("Cannot `convert grid to image' since no grid data exist yet");
78 return false;
79 }
80 if (!_xgrid_exists) {
81 err("Cannot `convert grid to image' since x-grid doesn't exist yet");
82 return false;
83 }
84 if (!_ygrid_exists) {
85 err("Cannot `convert grid to image' since y-grid doesn't exist yet");
86 return false;
87 }
88 increment *= 0.9999999; // to avoid overflow
89 double znew;
90 GriMatrix<double> _f_xy_new;
91 if (is_x) {
92 std::vector<double> ygrid((size_t)_num_ymatrix_data, 0.0);
93 _f_xy_new.set_size(num, _num_ymatrix_data);
94 unsigned int i, j;
95 j = _num_ymatrix_data - 1;
96 do {
97 ygrid[j] = _ymatrix[j];
98 double xnew = start;
99 for (i = 0; i < (unsigned int)num; i++) {
100 grid_interp(xnew, _ymatrix[j], &znew);
101 _f_xy_new(i, j) = znew;
102 xnew += increment;
103 }
104 } while (j-- != 0);
105 // Dump into official storage
106 allocate_grid_storage(num, _num_ymatrix_data);
107 allocate_xmatrix_storage(num);
108 for (i = 0; i < (unsigned int)num; i++)
109 _xmatrix[i] = start + i * increment;
110 for (j = 0; j < _num_ymatrix_data; j++)
111 _ymatrix[j] = ygrid[j];
112 for (j = 0; j < _num_ymatrix_data; j++) {
113 for (i = 0; i < (unsigned int)num; i++) {
114 _f_xy(i, j) = _f_xy_new(i, j);
115 _legit_xy(i, j) = true;
116 }
117 }
118 } else {
119 std::vector<double> xgrid((size_t)_num_xmatrix_data, 0.0);
120 _f_xy_new.set_size(_num_xmatrix_data, num);
121 unsigned int i, j;
122 for (i = 0; i < _num_xmatrix_data; i++) {
123 xgrid[i] = _xmatrix[i];
124 double ynew = start;
125 for (j = 0; j < (unsigned int)num; j++) {
126 grid_interp(_xmatrix[i], ynew, &znew);
127 _f_xy_new(i, j) = znew;
128 ynew += increment;
129 }
130 }
131 // Dump into official storage
132 allocate_grid_storage(_num_xmatrix_data, num);
133 allocate_ymatrix_storage(num);
134 for (i = 0; i < _num_xmatrix_data; i++)
135 _xmatrix[i] = xgrid[i];
136 for (j = 0; j < (unsigned int) num; j++)
137 _ymatrix[j] = start + j * increment;
138 for (i = 0; i < _num_xmatrix_data; i++) {
139 for (j = 0; j < (unsigned int)num; j++) {
140 _f_xy(i, j) = _f_xy_new(i, j);
141 _legit_xy(i, j) = true;
142 }
143 }
144 }
145 return true;
146 }
147