1
// $Id: x21d.d 11684 2011-03-31 04:15:32Z airwin $
4
// Copyright (C) 2009 Werner Smekal
6
// This file is part of PLplot.
8
// PLplot is free software; you can redistribute it and/or modify
9
// it under the terms of the GNU Library General Public License as published
10
// by the Free Software Foundation; either version 2 of the License, or
11
// (at your option) any later version.
13
// PLplot 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.
18
// You should have received a copy of the GNU Library General Public License
19
// along with PLplot; if not, write to the Free Software
20
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28
// Options data structure definition.
34
PLFLT threshold = 1.001;
42
int main( char[][] args )
44
string[] title = [ "Cubic Spline Approximation",
45
"Delaunay Linear Interpolation",
46
"Natural Neighbors Interpolation",
47
"KNN Inv. Distance Weighted",
48
"3NN Linear Interpolation",
49
"4NN Around Inv. Dist. Weighted" ];
54
// plMergeOpts(options, "x21c options", NULL);
55
plparseopts( args, PL_PARSE_FULL );
57
PLFLT[] opt = [ 0.0, 0.0, wmin, knn_order, threshold, 0.0 ];
62
// Initialise random number generator
66
x.length = y.length = z.length = pts;
67
create_data( x, y, z ); // the sampled data
70
for ( int i = 1; i < pts; i++ )
81
create_grid( xg, yg ); // grid the data at
83
PLFLT[][] zg = new PLFLT[][xp];
84
for ( int i = 0; i < xp; i++ )
85
zg[i] = new PLFLT[yp];
87
PLFLT[] clev = new PLFLT[nl];
90
plenv( xm, xM, ym, yM, 2, 0 );
92
pllab( "X", "Y", "The original data sampling" );
99
for ( int k = 0; k < 2; k++ )
102
for ( int alg = 1; alg < 7; alg++ )
104
plgriddata( x, y, z, xg, yg, zg, alg, opt[alg - 1] );
106
// - CSA can generate NaNs (only interpolates?!).
107
// - DTLI and NNI can generate NaNs for points outside the convex hull
108
// of the data points.
109
// - NNLI can generate NaNs if a sufficiently thick triangle is not found
111
// PLplot should be NaN/Inf aware, but changing it now is quite a job...
112
// so, instead of not plotting the NaN regions, a weighted average over
113
// the neighbors is done.
116
if ( alg == GRID_CSA || alg == GRID_DTLI || alg == GRID_NNLI || alg == GRID_NNI )
120
for ( int i = 0; i < xp; i++ )
122
for ( int j = 0; j < yp; j++ )
124
if ( isnan( zg[i][j] ) ) // average (IDW) over the 8 neighbors
129
for ( int ii = i - 1; ii <= i + 1 && ii < xp; ii++ )
131
for ( int jj = j - 1; jj <= j + 1 && jj < yp; jj++ )
133
if ( ii >= 0 && jj >= 0 && !isnan( zg[ii][jj] ) )
135
d = ( abs( ii - i ) + abs( jj - j ) ) == 1 ? 1.0 : 1.4142;
136
zg[i][j] += zg[ii][jj] / ( d * d );
151
plMinMax2dGrid( zg, lzM, lzm );
153
lzm = fmin( lzm, zmin );
154
lzM = fmax( lzM, zmax );
156
// Increase limits slightly to prevent spurious contours
157
// due to rounding errors
167
for ( int i = 0; i < nl; i++ )
168
clev[i] = lzm + ( lzM - lzm ) / ( nl - 1 ) * i;
170
plenv0( xm, xM, ym, yM, 2, 0 );
172
pllab( "X", "Y", title[alg - 1] );
173
plshades( zg, null, xm, xM, ym, yM, clev, 1, 0, 1, 1 );
178
for ( int i = 0; i < nl; i++ )
179
clev[i] = lzm + ( lzM - lzm ) / ( nl - 1 ) * i;
182
plvpor( 0.0, 1.0, 0.0, 0.9 );
183
plwind( -1.1, 0.75, -0.65, 1.20 );
185
// For the comparison to be fair, all plots should have the
186
// same z values, but to get the max/min of the data generated
187
// by all algorithms would imply two passes. Keep it simple.
189
// plw3d(1., 1., 1., xm, xM, ym, yM, zmin, zmax, 30, -60);
192
plw3d( 1., 1., 1., xm, xM, ym, yM, lzm, lzM, 30, -40 );
193
plbox3( "bntu", "X", 0., 0,
195
"bcdfntu", "Z", 0.5, 0 );
197
pllab( "", "", title[alg - 1] );
198
plot3dc( xg, yg, zg, DRAW_LINEXY | MAG_COLOR | BASE_CONT, clev );
209
void create_grid( PLFLT[] x, PLFLT[] y )
214
for ( int i = 0; i < px; i++ )
215
x[i] = xm + ( xM - xm ) * i / ( px - 1.0 );
217
for ( int i = 0; i < py; i++ )
218
y[i] = ym + ( yM - ym ) * i / ( py - 1.0 );
222
void create_data( PLFLT[] x, PLFLT[] y, PLFLT[] z )
225
assert( pts == y.length, "create_data(): Arrays must be of same length" );
226
assert( pts == z.length, "create_data(): Arrays must be of same length" );
229
for ( int i = 0; i < pts; i++ )
231
xt = ( xM - xm ) * plrandd();
232
yt = ( yM - ym ) * plrandd();
238
else // std=1, meaning that many points are outside the plot range
240
x[i] = sqrt( -2.0 * log( xt ) ) * cos( 2. * PI * yt ) + xm;
241
y[i] = sqrt( -2.0 * log( xt ) ) * sin( 2. * PI * yt ) + ym;
245
r = sqrt( x[i] * x[i] + y[i] * y[i] );
246
z[i] = exp( -r * r ) * cos( 2.0 * PI * r );
249
z[i] = log( pow( 1. - x[i], 2.9 ) + 100.0 * pow( y[i] - pow( x[i], 2.0 ), 2.0 ) );
256
PLFLT[] i = [ 0.0, 1.0 ]; // boundaries
258
PLFLT[] h = [ 240.0, 0.0 ]; // blue -> green -> yellow -> red
259
PLFLT[] l = [ 0.6, 0.6 ];
260
PLFLT[] s = [ 0.8, 0.8 ];
263
plscmap1l( 0, i, h, l, s );