1
//--------------------------------------------------------------------------
2
// $Id: x20.java 11301 2010-11-02 17:21:08Z airwin $
3
//--------------------------------------------------------------------------
5
//--------------------------------------------------------------------------
6
// Copyright (C) 2004,2006 Andrew Ross
7
// Copyright (C) 2004 Alan W. Irwin
9
// This file is part of PLplot.
11
// PLplot is free software; you can redistribute it and/or modify
12
// it under the terms of the GNU Library General Public License as published by
13
// the Free Software Foundation; version 2 of the License.
15
// PLplot is distributed in the hope that it will be useful,
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
// GNU Library General Public License for more details.
20
// You should have received a copy of the GNU Library General Public License
21
// along with PLplot; if not, write to the Free Software
22
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
//--------------------------------------------------------------------------
25
//--------------------------------------------------------------------------
26
// Implementation of PLplot example 20 in Java.
27
//--------------------------------------------------------------------------
30
// Current user defined command line options are not supported in
34
package plplot.examples;
43
PLStream pls = new PLStream();
45
static int XDIM = 260;
46
static int YDIM = 220;
47
static boolean dbg = false;
48
static boolean nosombrero = false;
49
static boolean nointeractive = false;
50
static String f_name = null;
52
//static PLOptionTable options[];
54
// PLOptionTable options[] = {
56
// "dbg", /* extra debugging plot */
62
// "Extra debugging plot" },
64
// "nosombrero", /* Turns on test of xor function */
70
// "No sombrero plot" },
72
// "nointeractive", /* Turns on test of xor function */
78
// "No interactive selection" },
80
// "save", /* For saving in postscript */
86
// "Save sombrero plot in color postscript `filename'" },
89
// NULL, /* handler */
90
// NULL, /* client data */
91
// NULL, /* address of variable to set */
93
// NULL, /* short syntax */
94
// NULL } /* long syntax */
100
double x[] = new double[XDIM];
101
double y[] = new double[YDIM];
102
double z[][] = new double[XDIM][YDIM];
104
double xi[] = new double[1];
105
double yi[] = new double[1];
106
double xe[] = new double[1];
107
double ye[] = new double[1];
108
int i, j, width, height, num_col;
109
int n[] = new int[1];
113
double maxmin[] = new double[2];
114
double x0, y0, dy, stretch;
115
double xg[][], yg[][];
119
// Bugs in plimage():
120
// -at high magnifications, the left and right edge are ragged, try
121
// ./x20c -dev xwin -wplt 0.3,0.3,0.6,0.6 -ori 0.5
124
// -if the window is resized after a selection is made on "lena", when
125
// making a new selection the old one will re-appear.
128
// plplot initialization
130
// Parse and process command line arguments.
131
//pls.MergeOpts(options, "x20c options", NULL);
132
pls.parseopts( args, PLStream.PL_PARSE_FULL | PLStream.PL_PARSE_NOPROGRAM );
134
// Initialize PLplot.
137
// view image border pixels
140
pls.env( 1., (double) XDIM, 1., (double) YDIM, 1, 1 ); // no plot box
142
// build a one pixel square border, for diagnostics
143
for ( i = 0; i < XDIM; i++ )
144
z[i][YDIM - 1] = 1.; // right
145
for ( i = 0; i < XDIM; i++ )
146
z[i][0] = 1.; // left
148
for ( i = 0; i < YDIM; i++ )
150
for ( i = 0; i < YDIM; i++ )
151
z[XDIM - 1][i] = 1.; // botton
153
pls.lab( "...around a blue square.", " ", "A red border should appear..." );
155
pls.image( z, 1., (double) XDIM, 1., (double) YDIM, 0., 0.,
156
1., (double) XDIM, 1., (double) YDIM );
159
// sombrero-like demo
162
r = new double[XDIM][YDIM];
163
pls.col0( 2 ); // draw a yellow plot box, useful for diagnostics! :(
164
pls.env( 0., 2. * Math.PI, 0, 3. * Math.PI, 1, -1 );
166
for ( i = 0; i < XDIM; i++ )
167
x[i] = i * 2. * Math.PI / ( XDIM - 1 );
168
for ( i = 0; i < YDIM; i++ )
169
y[i] = i * 3. * Math.PI / ( YDIM - 1 );
171
for ( i = 0; i < XDIM; i++ )
172
for ( j = 0; j < YDIM; j++ )
174
r[i][j] = Math.sqrt( x[i] * x[i] + y[j] * y[j] ) + 1e-3;
175
z[i][j] = Math.sin( r[i][j] ) / ( r[i][j] );
178
pls.lab( "No, an amplitude clipped \"sombrero\"", "", "Saturn?" );
179
pls.ptex( 2., 2., 3., 4., 0., "Transparent image" );
180
pls.image( z, 0., 2. * Math.PI, 0., 3. * Math.PI, 0.05, 1.,
181
0., 2. * Math.PI, 0., 3. * Math.PI );
184
if ( f_name != null )
190
if ( ( img_f = read_img( "lena.pgm", n ) ) == null )
192
if ( ( img_f = read_img( "../lena.pgm", n ) ) == null )
194
System.out.println( "File error - aborting" );
200
width = img_f.length;
201
height = img_f[0].length;
204
gray_cmap( num_col );
207
pls.env( 1., width, 1., height, 1, -1 );
209
if ( !nointeractive )
210
pls.lab( "Set and drag Button 1 to (re)set selection, Button 2 to finish.", " ", "Lena..." );
212
pls.lab( "", " ", "Lena..." );
214
pls.image( img_f, 1., (double) width, 1., (double) height, 0., 0.,
215
1., width, 1., height );
217
// selection/expansion demo
218
if ( !nointeractive )
220
xi[0] = 200.; xe[0] = 330.;
221
yi[0] = 280.; ye[0] = 220.;
223
if ( get_clip( xi, xe, yi, ye ) ) // get selection rectangle
230
// I'm unable to continue, clearing the plot and advancing to the next
231
// one, without hiting the enter key, or pressing the button... help!
233
// Forcing the xwin driver to leave locate mode and destroying the
234
// xhairs (in GetCursorCmd()) solves some problems, but I still have
235
// to press the enter key or press Button-2 to go to next plot, even
236
// if a pladv() is not present! Using plbop() solves the problem, but
237
// it shouldn't be needed!
243
// spause(false), adv(0), spause(true), also works,
244
// but the above question remains.
245
// With this approach, the previous pause state is lost,
246
// as there is no API call to get its current state.
252
// display selection only
253
pls.image( img_f, 1., (double) width, 1., (double) height, 0., 0., xi[0], xe[0], ye[0], yi[0] );
258
pls.env( xi[0], xe[0], ye[0], yi[0], 1, -1 );
259
pls.image( img_f, 1., (double) width, 1., (double) height, 0., 0., xi[0], xe[0], ye[0], yi[0] );
262
// Base the dynamic range on the image contents.
263
f2mnmx( img_f, width, height, maxmin );
267
// For java we use 2-d arrays to replace the pltr function
268
// even for the NULL case.
269
xg = new double[width + 1][height + 1];
270
yg = new double[width + 1][height + 1];
272
for ( i = 0; i <= width; i++ )
274
for ( j = 0; j <= height; j++ )
276
xg[i][j] = (double) i;
277
yg[i][j] = (double) j;
280
// Draw a saturated version of the original image. Only use
281
// the middle 50% of the image's full dynamic range.
283
pls.env( 0, width, 0, height, 1, -1 );
284
pls.lab( "", "", "Reduced dynamic range image example" );
285
pls.imagefr( img_f, 0., (double) width, 0., (double) height, 0., 0.,
286
img_min + img_max * 0.25,
287
img_max - img_max * 0.25,
290
// Draw a distorted version of the original image, showing its full dynamic range.
291
pls.env( 0, width, 0, height, 1, -1 );
292
pls.lab( "", "", "Distorted image example" );
299
// In C / C++ the following would work, with plimagefr directly calling
300
// mypltr. For compatibilty with other language bindings the same effect
301
// can be achieved by generating the transformed grid first and then
303
// plimagefr(img_f, width, height, 0., width, 0., height, 0., 0., img_min, img_max, mypltr, (PLPointer) &stretch);
305
for ( i = 0; i <= width; i++ )
307
for ( j = 0; j <= height; j++ )
309
xg[i][j] = x0 + ( x0 - i ) * ( 1.0 - stretch *
310
Math.cos( ( j - y0 ) / dy * Math.PI * 0.5 ) );
315
pls.imagefr( img_f, 0., (double) width, 0., (double) height, 0., 0., img_min, img_max, xg, yg );
319
// read image from file in binary ppm format
320
double [][] read_img( String fname, int [] num_col )
329
// naive grayscale binary ppm reading. If you know how to, improve it
331
in = new BufferedReader( new FileReader( fname ) );
332
in2 = new DataInputStream( new DataInputStream( new BufferedInputStream( new FileInputStream( fname ) ) ) );
334
catch ( FileNotFoundException e ) {
335
System.out.println( "File " + fname + " not found" );
340
line = in.readLine();
342
if ( line.compareTo( "P5\n" ) == 0 ) // I only understand this!
344
System.out.println( line );
345
System.out.println( "unknown file format " + fname );
348
in2.skip( line.getBytes().length + 1 );
352
line = in.readLine();
353
in2.skip( line.getBytes().length + 1 );
354
} while ( line.charAt( 0 ) == '#' );
356
st = new StringTokenizer( line );
357
w = Integer.parseInt( st.nextToken() );
358
h = Integer.parseInt( st.nextToken() );
360
line = in.readLine();
361
in2.skip( line.getBytes().length + 1 );
362
st = new StringTokenizer( line );
363
num_col[0] = Integer.parseInt( st.nextToken() );
365
img = new double[w][h];
367
for ( j = 0; j < h; j++ )
369
for ( i = 0; i < w; i++ )
371
img[i][h - j - 1] = (double) in2.readUnsignedByte();
375
catch ( IOException e ) {
376
System.out.println( "Error reading " + fname );
384
void save_plot( String fname )
386
PLStream pls2 = new PLStream(); // create a new one
388
pls2.sdev( "psc" ); // new device type. Use a known existing driver
389
pls2.sfnam( fname ); // file name
391
pls2.cpstrm( pls, false ); // copy old stream parameters to new stream
392
pls2.replot(); // do the save
395
// get selection square interactively
396
boolean get_clip( double[] xi, double[] xe, double[] yi, double[] ye )
398
PLGraphicsIn gin = new PLGraphicsIn();
399
double xxi = xi[0], yyi = yi[0], xxe = xe[0], yye = ye[0], t;
400
boolean start = false;
401
boolean[] st = new boolean[1];
403
pls.xormod( true, st ); // enter xor mode to draw a selection rectangle
405
if ( st[0] ) // driver has xormod capability, continue
407
double sx[] = new double[5];
408
double sy[] = new double[5];
411
pls.xormod( false, st );
412
pls.getCursor( gin );
413
pls.xormod( true, st );
415
if ( gin.getButton() == 1 )
417
xxi = gin.getWX(); yyi = gin.getWY();
419
pls.line( sx, sy ); // clear previous rectangle
423
sx[0] = xxi; sy[0] = yyi;
424
sx[4] = xxi; sy[4] = yyi;
427
if ( ( gin.getState() & (long) 0x100 ) != 0 )
429
xxe = gin.getWX(); yye = gin.getWY();
431
pls.line( sx, sy ); // clear previous rectangle
435
sx[2] = xxe; sy[2] = yye;
436
sx[1] = xxe; sy[1] = yyi;
437
sx[3] = xxi; sy[3] = yye;
438
pls.line( sx, sy ); // draw new rectangle
441
if ( gin.getButton() == 3 || gin.getKeysym() == 0x0D || gin.getKeysym() == 'Q' )
444
pls.line( sx, sy ); // clear previous rectangle
448
pls.xormod( false, st ); // leave xor mod
451
t = xxi; xxi = xxe; xxe = t;
456
t = yyi; yyi = yye; yye = t;
459
xe[0] = xxe; xi[0] = xxi;
460
ye[0] = yye; yi[0] = yyi;
462
return ( gin.getKeysym() == 'Q' );
469
void gray_cmap( int num_col )
471
double r[] = new double[2];
472
double g[] = new double[2];
473
double b[] = new double[2];
474
double pos[] = new double[2];
476
r[0] = g[0] = b[0] = 0.0;
477
r[1] = g[1] = b[1] = 1.0;
482
pls.scmap1n( num_col );
483
pls.scmap1l( true, pos, r, g, b );
486
// Calculate the minimum and maximum of a 2-d array
487
void f2mnmx( double [][] f, int nx, int ny, double[] fmaxmin )
491
fmaxmin[0] = f[0][0];
492
fmaxmin[1] = fmaxmin[0];
494
for ( i = 0; i < nx; i++ )
496
for ( j = 0; j < ny; j++ )
498
fmaxmin[0] = Math.max( fmaxmin[0], f[i][j] );
499
fmaxmin[1] = Math.min( fmaxmin[1], f[i][j] );
504
public static void main( String[] args )
511
//--------------------------------------------------------------------------
513
//--------------------------------------------------------------------------