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