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