1 //-------------------------------------------------------------------------- 2 // Copyright (C) 2001, 2002 Geoffrey Furnish 3 // Copyright (C) 2002-2014 Alan W. Irwin 4 // Copyright (C) 2004 Andrew Ross 5 // 6 // This file is part of PLplot. 7 // 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 by 10 // the Free Software Foundation; version 2 of the License. 11 // 12 // PLplot is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 // GNU Library General Public License for more details. 16 // 17 // You should have received a copy of the GNU Library General Public License 18 // along with PLplot; if not, write to the Free Software 19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 //-------------------------------------------------------------------------- 21 22 //-------------------------------------------------------------------------- 23 // Implementation of PLplot example 9 in Java. 24 //-------------------------------------------------------------------------- 25 26 package plplot.examples; 27 28 import plplot.core.*; 29 import static plplot.core.plplotjavacConstants.*; 30 31 import java.lang.Math; 32 33 class x09 { 34 static final int XPTS = 35; 35 static final int YPTS = 46; 36 static final double XSPA = 2. / ( XPTS - 1 ); 37 static final double YSPA = 2. / ( YPTS - 1 ); 38 39 // polar plot data 40 static final int PERIMETERPTS = 100; 41 static final int RPTS = 40; 42 static final int THETAPTS = 40; 43 44 // potential plot data 45 static final int PPERIMETERPTS = 100; 46 static final int PRPTS = 40; 47 static final int PTHETAPTS = 64; 48 static final int PNLEVEL = 20; 49 50 final double clevel[] = { -1., -.8, -.6, -.4, -.2, 0, .2, .4, .6, .8, 1. }; 51 // Transformation function 52 final double tr[] = { XSPA, 0.0, -1.0, 0.0, YSPA, -1.0 }; 53 54 PLStream pls = new PLStream(); 55 56 // State data used by f2mnmx 57 double fmin, fmax; 58 59 // Does a large series of unlabelled and labelled contour plots. 60 main( String[] args )61 public static void main( String[] args ) 62 { 63 new x09( args ); 64 } 65 x09( String[] args )66 public x09( String[] args ) 67 { 68 int i, j; 69 70 double[][] xg0 = new double[XPTS][YPTS]; 71 double[][] yg0 = new double[XPTS][YPTS]; 72 double[][] xg1 = new double[XPTS][YPTS]; 73 double[][] yg1 = new double[XPTS][YPTS]; 74 double[][] xg2 = new double[XPTS][YPTS]; 75 double[][] yg2 = new double[XPTS][YPTS]; 76 double[][] z = new double[XPTS][YPTS]; 77 double[][] w = new double[XPTS][YPTS]; 78 79 double xx, yy, argx, argy, distort; 80 final int[] mark = { 1500 }; 81 final int[] space = { 1500 }; 82 final int[] mark0 = {}; 83 final int[] space0 = {}; 84 85 // Parse and process command line arguments. 86 87 pls.parseopts( args, PL_PARSE_FULL | PL_PARSE_NOPROGRAM ); 88 // Initialize plplot 89 90 pls.init(); 91 92 // Set up function arrays 93 94 for ( i = 0; i < XPTS; i++ ) 95 { 96 xx = (double) ( i - ( XPTS / 2 ) ) / (double) ( XPTS / 2 ); 97 for ( j = 0; j < YPTS; j++ ) 98 { 99 yy = (double) ( j - ( YPTS / 2 ) ) / (double) ( YPTS / 2 ) - 1.0; 100 z[i][j] = xx * xx - yy * yy; 101 w[i][j] = 2 * xx * yy; 102 } 103 } 104 105 // Set up grids 106 107 108 for ( i = 0; i < XPTS; i++ ) 109 { 110 for ( j = 0; j < YPTS; j++ ) 111 { 112 // Replacement for mypltr of x09c.c 113 xx = tr[0] * i + tr[1] * j + tr[2]; 114 yy = tr[3] * i + tr[4] * j + tr[5]; 115 116 argx = xx * Math.PI / 2; 117 argy = yy * Math.PI / 2; 118 distort = 0.4; 119 120 // Note these are one-dimensional because of arrangement of 121 // zeros in the final tr definition above. 122 // But I haven't found out yet, how with swig to overload 123 // one- and two-dimensional array arguments so for now make 124 // xg0 --> yg1 two-dimensional. 125 xg0[i][j] = xx; 126 yg0[i][j] = yy; 127 xg1[i][j] = xx + distort * Math.cos( argx ); 128 yg1[i][j] = yy - distort * Math.cos( argy ); 129 130 xg2[i][j] = xx + distort * Math.cos( argx ) * Math.cos( argy ); 131 yg2[i][j] = yy - distort * Math.cos( argx ) * Math.cos( argy ); 132 } 133 } 134 135 136 // Plot using scaled identity transform used to create xg0 and yg0 137 // pls.setcontlabelparam(0.006, 0.3, 0.1, 0); 138 // pls.env(-1.0, 1.0, -1.0, 1.0, 0, 0); 139 // pls.col0(2); 140 // pls.cont( z, 1, XPTS, 1, YPTS, clevel, xg0, yg0 ); 141 // pls.styl(mark, space); 142 // pls.col0(3); 143 // pls.cont(w, 1, XPTS, 1, YPTS, clevel, xg0, yg0 ); 144 // pls.styl(mark0, space0); 145 // pls.col0(1); 146 // pls.lab("X Coordinate", "Y Coordinate", "Streamlines of flow"); 147 // 148 pls.setcontlabelformat( 4, 3 ); 149 pls.setcontlabelparam( 0.006, 0.3, 0.1, 1 ); 150 pls.env( -1.0, 1.0, -1.0, 1.0, 0, 0 ); 151 pls.col0( 2 ); 152 pls.cont( z, 1, XPTS, 1, YPTS, clevel, xg0, yg0 ); 153 pls.styl( mark, space ); 154 pls.col0( 3 ); 155 pls.cont( w, 1, XPTS, 1, YPTS, clevel, xg0, yg0 ); 156 pls.styl( mark0, space0 ); 157 pls.col0( 1 ); 158 pls.lab( "X Coordinate", "Y Coordinate", "Streamlines of flow" ); 159 pls.setcontlabelparam( 0.006, 0.3, 0.1, 0 ); 160 161 // Plot using 1d coordinate transform 162 pls.env( -1.0, 1.0, -1.0, 1.0, 0, 0 ); 163 pls.col0( 2 ); 164 pls.cont( z, 1, XPTS, 1, YPTS, clevel, xg1, yg1 ); 165 pls.styl( mark, space ); 166 pls.col0( 3 ); 167 pls.cont( w, 1, XPTS, 1, YPTS, clevel, xg1, yg1 ); 168 pls.styl( mark0, space0 ); 169 pls.col0( 1 ); 170 pls.lab( "X Coordinate", "Y Coordinate", "Streamlines of flow" ); 171 172 // pls.setcontlabelparam(0.006, 0.3, 0.1, 1); 173 // pls.env(-1.0, 1.0, -1.0, 1.0, 0, 0); 174 // pls.col0(2); 175 // pls.cont(z, 1, XPTS, 1, YPTS, clevel, xg1, yg1 ); 176 // pls.styl(mark, space); 177 // pls.col0(3); 178 // pls.cont(w, 1, XPTS, 1, YPTS, clevel, xg1, yg1 ); 179 // pls.styl(mark0, space0); 180 // pls.col0(1); 181 // pls.lab("X Coordinate", "Y Coordinate", "Streamlines of flow"); 182 // pls.setcontlabelparam(0.006, 0.3, 0.1, 0); 183 // 184 // Plot using 2d coordinate transform 185 pls.env( -1.0, 1.0, -1.0, 1.0, 0, 0 ); 186 pls.col0( 2 ); 187 pls.cont( z, 1, XPTS, 1, YPTS, clevel, xg2, yg2 ); 188 pls.styl( mark, space ); 189 pls.col0( 3 ); 190 pls.cont( w, 1, XPTS, 1, YPTS, clevel, xg2, yg2 ); 191 pls.styl( mark0, space0 ); 192 pls.col0( 1 ); 193 pls.lab( "X Coordinate", "Y Coordinate", "Streamlines of flow" ); 194 195 // pls.setcontlabelparam(0.006, 0.3, 0.1, 1); 196 // pls.env(-1.0, 1.0, -1.0, 1.0, 0, 0); 197 // pls.col0(2); 198 // pls.cont(z, 1, XPTS, 1, YPTS, clevel, xg2, yg2 ); 199 // pls.styl(mark, space); 200 // pls.col0(3); 201 // pls.cont(w, 1, XPTS, 1, YPTS, clevel, xg2, yg2 ); 202 // pls.styl(mark0, space0); 203 // pls.col0(1); 204 // pls.lab("X Coordinate", "Y Coordinate", "Streamlines of flow"); 205 // pls.setcontlabelparam(0.006, 0.3, 0.1, 0); 206 // 207 polar(); 208 // pls.setcontlabelparam(0.006, 0.3, 0.1, 1); 209 // polar(); 210 // pls.setcontlabelparam(0.006, 0.3, 0.1, 0); 211 // 212 potential(); 213 // pls.setcontlabelparam(0.006, 0.3, 0.1, 1); 214 // potential(); 215 // pls.setcontlabelparam(0.006, 0.3, 0.1, 0); 216 // 217 pls.end(); 218 } 219 polar()220 void polar() 221 // polar contour plot example. 222 { 223 int i, j; 224 double[] px = new double[PERIMETERPTS]; 225 double[] py = new double[PERIMETERPTS]; 226 double[][] xg = new double[RPTS][THETAPTS]; 227 double[][] yg = new double[RPTS][THETAPTS]; 228 double[][] z = new double[RPTS][THETAPTS]; 229 double t, r, theta; 230 double [] lev = new double[10]; 231 232 pls.env( -1., 1., -1., 1., 0, -2 ); 233 pls.col0( 1 ); 234 235 // Perimeter 236 for ( i = 0; i < PERIMETERPTS; i++ ) 237 { 238 t = ( 2. * Math.PI / ( PERIMETERPTS - 1 ) ) * i; 239 px[i] = Math.cos( t ); 240 py[i] = Math.sin( t ); 241 } 242 pls.line( px, py ); 243 244 // Create data to be contoured. 245 246 for ( i = 0; i < RPTS; i++ ) 247 { 248 r = i / (double) ( RPTS - 1 ); 249 for ( j = 0; j < THETAPTS; j++ ) 250 { 251 theta = ( 2. * Math.PI / ( THETAPTS - 1 ) ) * j; 252 xg[i][j] = r * Math.cos( theta ); 253 yg[i][j] = r * Math.sin( theta ); 254 z[i][j] = r; 255 } 256 } 257 258 for ( i = 0; i < 10; i++ ) 259 { 260 lev[i] = 0.05 + 0.10 * i; 261 } 262 263 pls.col0( 2 ); 264 pls.cont( z, 1, RPTS, 1, THETAPTS, lev, xg, yg ); 265 pls.col0( 1 ); 266 pls.lab( "", "", "Polar Contour Plot" ); 267 } 268 269 // Compute min and max value of a 2-d array. 270 f2mnmx( double[][] f, int nx, int ny )271 void f2mnmx( double[][] f, int nx, int ny ) 272 { 273 fmax = f[0][0]; 274 fmin = fmax; 275 276 for ( int i = 0; i < nx; i++ ) 277 for ( int j = 0; j < ny; j++ ) 278 { 279 if ( f[i][j] < fmin ) fmin = f[i][j]; 280 if ( f[i][j] > fmax ) fmax = f[i][j]; 281 } 282 } 283 potential()284 final void potential() 285 // Shielded potential contour plot example. 286 { 287 int i, j; 288 289 double rmax, xmin, xmax, x0, ymin, ymax, y0, zmin, zmax; 290 double peps, xpmin, xpmax, ypmin, ypmax; 291 double eps, q1, d1, q1i, d1i, q2, d2, q2i, d2i; 292 double div1, div1i, div2, div2i; 293 double [][] xg = new double[PRPTS][PTHETAPTS]; 294 double [][] yg = new double[PRPTS][PTHETAPTS]; 295 double [][] z = new double[PRPTS][PTHETAPTS]; 296 int nlevelneg, nlevelpos; 297 double dz, clev; 298 double [] clevelneg_store = new double[PNLEVEL]; 299 double [] clevelpos_store = new double[PNLEVEL]; 300 int ncollin, ncolbox, ncollab; 301 double [] px = new double[PPERIMETERPTS]; 302 double [] py = new double[PPERIMETERPTS]; 303 double t, r, theta; 304 305 // Create data to be contoured. 306 307 //java wants r unambiguously initialized for rmax below. 308 r = 0.; 309 for ( i = 0; i < PRPTS; i++ ) 310 { 311 r = 0.5 + i; 312 for ( j = 0; j < PTHETAPTS; j++ ) 313 { 314 theta = ( 2. * Math.PI / ( PTHETAPTS - 1 ) ) * ( 0.5 + j ); 315 xg[i][j] = r * Math.cos( theta ); 316 yg[i][j] = r * Math.sin( theta ); 317 } 318 } 319 320 rmax = r; 321 322 f2mnmx( xg, PRPTS, PTHETAPTS ); 323 xmin = fmin; 324 xmax = fmax; 325 326 f2mnmx( yg, PRPTS, PTHETAPTS ); 327 ymin = fmin; 328 ymax = fmax; 329 330 x0 = ( xmin + xmax ) / 2.; 331 y0 = ( ymin + ymax ) / 2.; 332 333 // Expanded limits 334 peps = 0.05; 335 xpmin = xmin - Math.abs( xmin ) * peps; 336 xpmax = xmax + Math.abs( xmax ) * peps; 337 ypmin = ymin - Math.abs( ymin ) * peps; 338 ypmax = ymax + Math.abs( ymax ) * peps; 339 340 // Potential inside a conducting cylinder (or sphere) by method of images. 341 // Charge 1 is placed at (d1, d1), with image charge at (d2, d2). 342 // Charge 2 is placed at (d1, -d1), with image charge at (d2, -d2). 343 // Also put in smoothing term at small distances. 344 345 eps = 2.; 346 347 q1 = 1.; 348 d1 = rmax / 4.; 349 350 q1i = -q1 * rmax / d1; 351 d1i = Math.pow( rmax, 2 ) / d1; 352 353 q2 = -1.; 354 d2 = rmax / 4.; 355 356 q2i = -q2 * rmax / d2; 357 d2i = Math.pow( rmax, 2 ) / d2; 358 359 for ( i = 0; i < PRPTS; i++ ) 360 { 361 for ( j = 0; j < PTHETAPTS; j++ ) 362 { 363 div1 = Math.sqrt( Math.pow( xg[i][j] - d1, 2 ) + Math.pow( yg[i][j] - d1, 2 ) + Math.pow( eps, 2 ) ); 364 div1i = Math.sqrt( Math.pow( xg[i][j] - d1i, 2 ) + Math.pow( yg[i][j] - d1i, 2 ) + Math.pow( eps, 2 ) ); 365 div2 = Math.sqrt( Math.pow( xg[i][j] - d2, 2 ) + Math.pow( yg[i][j] + d2, 2 ) + Math.pow( eps, 2 ) ); 366 div2i = Math.sqrt( Math.pow( xg[i][j] - d2i, 2 ) + Math.pow( yg[i][j] + d2i, 2 ) + Math.pow( eps, 2 ) ); 367 z[i][j] = q1 / div1 + q1i / div1i + q2 / div2 + q2i / div2i; 368 } 369 } 370 371 f2mnmx( z, PRPTS, PTHETAPTS ); 372 zmin = fmin; 373 zmax = fmax; 374 375 // printf("%.15g %.15g %.15g %.15g %.15g %.15g %.15g %.15g \n", 376 // q1, d1, q1i, d1i, q2, d2, q2i, d2i); 377 // System.out.println(xmin); 378 // System.out.println(xmax); 379 // System.out.println(ymin); 380 // System.out.println(ymax); 381 // System.out.println(zmin); 382 // System.out.println(zmax); 383 384 // Positive and negative contour levels. 385 dz = ( zmax - zmin ) / PNLEVEL; 386 nlevelneg = 0; 387 nlevelpos = 0; 388 for ( i = 0; i < PNLEVEL; i++ ) 389 { 390 clev = zmin + ( i + 0.5 ) * dz; 391 if ( clev <= 0. ) 392 clevelneg_store[nlevelneg++] = clev; 393 else 394 clevelpos_store[nlevelpos++] = clev; 395 } 396 // Colours! 397 ncollin = 11; 398 ncolbox = 1; 399 ncollab = 2; 400 401 // Finally start plotting this page! 402 pls.adv( 0 ); 403 pls.col0( ncolbox ); 404 405 pls.vpas( 0.1, 0.9, 0.1, 0.9, 1.0 ); 406 pls.wind( xpmin, xpmax, ypmin, ypmax ); 407 pls.box( "", 0., 0, "", 0., 0 ); 408 409 pls.col0( ncollin ); 410 if ( nlevelneg > 0 ) 411 { 412 // Negative contours 413 pls.lsty( 2 ); 414 // The point here is to copy results into an array of the correct size 415 // which is essential for the java wrapper of plplot to work correctly. 416 double [] clevelneg = new double[nlevelneg]; 417 System.arraycopy( clevelneg_store, 0, clevelneg, 0, nlevelneg ); 418 pls.cont( z, 1, PRPTS, 1, PTHETAPTS, clevelneg, xg, yg ); 419 } 420 421 if ( nlevelpos > 0 ) 422 { 423 // Positive contours 424 pls.lsty( 1 ); 425 double [] clevelpos = new double[nlevelpos]; 426 // The point here is to copy results into an array of the correct size 427 // which is essential for the java wrapper of plplot to work correctly. 428 System.arraycopy( clevelpos_store, 0, clevelpos, 0, nlevelpos ); 429 pls.cont( z, 1, PRPTS, 1, PTHETAPTS, clevelpos, xg, yg ); 430 } 431 432 // Draw outer boundary 433 for ( i = 0; i < PPERIMETERPTS; i++ ) 434 { 435 t = ( 2. * Math.PI / ( PPERIMETERPTS - 1 ) ) * i; 436 px[i] = x0 + rmax * Math.cos( t ); 437 py[i] = y0 + rmax * Math.sin( t ); 438 } 439 440 pls.col0( ncolbox ); 441 pls.line( px, py ); 442 443 pls.col0( ncollab ); 444 pls.lab( "", "", "Shielded potential of charges in a conducting sphere" ); 445 } 446 } 447 448 //-------------------------------------------------------------------------- 449 // End of x09.java 450 //-------------------------------------------------------------------------- 451