// $Id: x16c.c 12346 2013-05-22 22:41:41Z andrewross $
//
// plshade demo, using color fill.
//
// Maurice LeBrun
// IFS, University of Texas at Austin
// 20 Mar 1994
//
#include "plcdemos.h"
// Fundamental settings. See notes[] for more info.
static int ns = 20; // Default number of shade levels
static int nx = 35; // Default number of data points in x
static int ny = 46; // Default number of data points in y
static int exclude = 0; // By default do not plot a page illustrating
// exclusion. API is probably going to change
// anyway, and cannot be reproduced by any
// front end other than the C one.
// For now, don't show the colorbars while we are working out the API.
static int colorbar = 1;
// polar plot data
#define PERIMETERPTS 100
// Transformation function
PLFLT tr[6];
static void
mypltr( PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, void * PL_UNUSED( pltr_data ) )
{
*tx = tr[0] * x + tr[1] * y + tr[2];
*ty = tr[3] * x + tr[4] * y + tr[5];
}
// Function prototypes
static void
f2mnmx( PLFLT **f, PLINT nx, PLINT ny, PLFLT *fmin, PLFLT *fmax );
PLINT zdefined( PLFLT x, PLFLT y );
// Options data structure definition.
static PLOptionTable options[] = {
{
"colorbar", // Turns on the colorbar for each page
NULL,
NULL,
&colorbar,
PL_OPT_BOOL,
"-colorbar",
"Plot a \"color bar\" on each page."
},
{
"exclude", // Turns on page showing exclusion
NULL,
NULL,
&exclude,
PL_OPT_BOOL,
"-exclude",
"Plot the \"exclusion\" page."
},
{
"ns", // Number of shade levels
NULL,
NULL,
&ns,
PL_OPT_INT,
"-ns levels",
"Sets number of shade levels"
},
{
"nx", // Number of data points in x
NULL,
NULL,
&nx,
PL_OPT_INT,
"-nx xpts",
"Sets number of data points in x"
},
{
"ny", // Number of data points in y
NULL,
NULL,
&ny,
PL_OPT_INT,
"-ny ypts",
"Sets number of data points in y"
},
{
NULL, // option
NULL, // handler
NULL, // client data
NULL, // address of variable to set
0, // mode flag
NULL, // short syntax
NULL
} // long syntax
};
static const char *notes[] = {
"To get smoother color variation, increase ns, nx, and ny. To get faster",
"response (especially on a serial link), decrease them. A decent but quick",
"test results from ns around 5 and nx, ny around 25.",
NULL
};
PLINT
zdefined( PLFLT x, PLFLT y )
{
PLFLT z = sqrt( x * x + y * y );
return z < 0.4 || z > 0.6;
}
//--------------------------------------------------------------------------
// main
//
// Does several shade plots using different coordinate mappings.
//--------------------------------------------------------------------------
int
main( int argc, const char *argv[] )
{
int i, j;
PLFLT x, y, argx, argy, distort, r, t;
PLFLT px[PERIMETERPTS], py[PERIMETERPTS];
PLFLT **z, **w, zmin, zmax;
PLFLT *clevel, *shedge, *xg1, *yg1;
PLcGrid cgrid1;
PLcGrid2 cgrid2;
PLFLT fill_width = 2., cont_width = 0.;
PLFLT colorbar_width, colorbar_height;
PLINT cont_color = 0;
#define NUM_AXES 1
PLINT n_axis_opts = NUM_AXES;
const char *axis_opts[] = {
"bcvtm",
};
PLINT num_values[NUM_AXES];
PLFLT *values[NUM_AXES];
PLFLT axis_ticks[NUM_AXES] = {
0.0,
};
PLINT axis_subticks[NUM_AXES] = {
0,
};
#define NUM_LABELS 1
PLINT n_labels = NUM_LABELS;
PLINT label_opts[] = {
PL_COLORBAR_LABEL_BOTTOM,
};
const char *labels[] = {
"Magnitude",
};
// Parse and process command line arguments
plMergeOpts( options, "x16c options", notes );
plparseopts( &argc, argv, PL_PARSE_FULL );
// Load colour palettes
plspal0( "cmap0_black_on_white.pal" );
plspal1( "cmap1_gray.pal", 1 );
// Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
plscmap0n( 3 );
// Initialize plplot
plinit();
// Set up transformation function
tr[0] = 2. / ( nx - 1 );
tr[1] = 0.0;
tr[2] = -1.0;
tr[3] = 0.0;
tr[4] = 2. / ( ny - 1 );
tr[5] = -1.0;
// Allocate data structures
clevel = (PLFLT *) calloc( (size_t) ns, sizeof ( PLFLT ) );
shedge = (PLFLT *) calloc( (size_t) ( ns + 1 ), sizeof ( PLFLT ) );
xg1 = (PLFLT *) calloc( (size_t) nx, sizeof ( PLFLT ) );
yg1 = (PLFLT *) calloc( (size_t) ny, sizeof ( PLFLT ) );
plAlloc2dGrid( &z, nx, ny );
plAlloc2dGrid( &w, nx, ny );
// Set up data array
for ( i = 0; i < nx; i++ )
{
x = (double) ( i - ( nx / 2 ) ) / (double) ( nx / 2 );
for ( j = 0; j < ny; j++ )
{
y = (double) ( j - ( ny / 2 ) ) / (double) ( ny / 2 ) - 1.0;
z[i][j] = -sin( 7. * x ) * cos( 7. * y ) + x * x - y * y;
w[i][j] = -cos( 7. * x ) * sin( 7. * y ) + 2 * x * y;
}
}
f2mnmx( z, nx, ny, &zmin, &zmax );
for ( i = 0; i < ns; i++ )
clevel[i] = zmin + ( zmax - zmin ) * ( i + 0.5 ) / (PLFLT) ns;
for ( i = 0; i < ns + 1; i++ )
shedge[i] = zmin + ( zmax - zmin ) * (PLFLT) i / (PLFLT) ns;
// Set up coordinate grids
cgrid1.xg = xg1;
cgrid1.yg = yg1;
cgrid1.nx = nx;
cgrid1.ny = ny;
plAlloc2dGrid( &cgrid2.xg, nx, ny );
plAlloc2dGrid( &cgrid2.yg, nx, ny );
cgrid2.nx = nx;
cgrid2.ny = ny;
for ( i = 0; i < nx; i++ )
{
for ( j = 0; j < ny; j++ )
{
mypltr( (PLFLT) i, (PLFLT) j, &x, &y, NULL );
argx = x * M_PI / 2;
argy = y * M_PI / 2;
distort = 0.4;
cgrid1.xg[i] = x + distort * cos( argx );
cgrid1.yg[j] = y - distort * cos( argy );
cgrid2.xg[i][j] = x + distort * cos( argx ) * cos( argy );
cgrid2.yg[i][j] = y - distort * cos( argx ) * cos( argy );
}
}
// Plot using identity transform
pladv( 0 );
plvpor( 0.1, 0.9, 0.1, 0.9 );
plwind( -1.0, 1.0, -1.0, 1.0 );
plpsty( 0 );
plshades( (const PLFLT * const *) z, nx, ny, NULL, -1., 1., -1., 1.,
shedge, ns + 1, fill_width,
cont_color, cont_width,
plfill, 1, NULL, NULL );
if ( colorbar )
{
// Smaller text
plschr( 0.0, 0.75 );
// Small ticks on the vertical axis
plsmaj( 0.0, 0.5 );
plsmin( 0.0, 0.5 );
num_values[0] = ns + 1;
values[0] = shedge;
plcolorbar( &colorbar_width, &colorbar_height,
PL_COLORBAR_SHADE | PL_COLORBAR_SHADE_LABEL, 0,
0.005, 0.0, 0.0375, 0.875, 0, 1, 1, 0.0, 0.0,
cont_color, cont_width,
n_labels, label_opts, labels,
n_axis_opts, axis_opts,
axis_ticks, axis_subticks,
num_values, (const PLFLT * const *) values );
// Reset text and tick sizes
plschr( 0.0, 1.0 );
plsmaj( 0.0, 1.0 );
plsmin( 0.0, 1.0 );
}
plcol0( 1 );
plbox( "bcnst", 0.0, 0, "bcnstv", 0.0, 0 );
plcol0( 2 );
//
// plcont((const PLFLT **) w, nx, ny, 1, nx, 1, ny, clevel, ns, mypltr, NULL);
//
pllab( "distance", "altitude", "Bogon density" );
// Plot using 1d coordinate transform
// Load colour palettes
plspal0( "cmap0_black_on_white.pal" );
plspal1( "cmap1_blue_yellow.pal", 1 );
// Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
plscmap0n( 3 );
pladv( 0 );
plvpor( 0.1, 0.9, 0.1, 0.9 );
plwind( -1.0, 1.0, -1.0, 1.0 );
plpsty( 0 );
plshades( (const PLFLT * const *) z, nx, ny, NULL, -1., 1., -1., 1.,
shedge, ns + 1, fill_width,
cont_color, cont_width,
plfill, 1, pltr1, (void *) &cgrid1 );
if ( colorbar )
{
// Smaller text
plschr( 0.0, 0.75 );
// Small ticks on the vertical axis
plsmaj( 0.0, 0.5 );
plsmin( 0.0, 0.5 );
num_values[0] = ns + 1;
values[0] = shedge;
plcolorbar( &colorbar_width, &colorbar_height,
PL_COLORBAR_SHADE | PL_COLORBAR_SHADE_LABEL, 0,
0.005, 0.0, 0.0375, 0.875, 0, 1, 1, 0.0, 0.0,
cont_color, cont_width,
n_labels, label_opts, labels,
n_axis_opts, axis_opts,
axis_ticks, axis_subticks,
num_values, (const PLFLT * const *) values );
// Reset text and tick sizes
plschr( 0.0, 1.0 );
plsmaj( 0.0, 1.0 );
plsmin( 0.0, 1.0 );
}
plcol0( 1 );
plbox( "bcnst", 0.0, 0, "bcnstv", 0.0, 0 );
plcol0( 2 );
//
// plcont((const PLFLT **) w, nx, ny, 1, nx, 1, ny, clevel, ns, pltr1, (void *) &cgrid1);
//
pllab( "distance", "altitude", "Bogon density" );
// Plot using 2d coordinate transform
// Load colour palettes
plspal0( "cmap0_black_on_white.pal" );
plspal1( "cmap1_blue_red.pal", 1 );
// Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
plscmap0n( 3 );
pladv( 0 );
plvpor( 0.1, 0.9, 0.1, 0.9 );
plwind( -1.0, 1.0, -1.0, 1.0 );
plpsty( 0 );
plshades( (const PLFLT * const *) z, nx, ny, NULL, -1., 1., -1., 1.,
shedge, ns + 1, fill_width,
cont_color, cont_width,
plfill, 0, pltr2, (void *) &cgrid2 );
if ( colorbar )
{
// Smaller text
plschr( 0.0, 0.75 );
// Small ticks on the vertical axis
plsmaj( 0.0, 0.5 );
plsmin( 0.0, 0.5 );
num_values[0] = ns + 1;
values[0] = shedge;
plcolorbar( &colorbar_width, &colorbar_height,
PL_COLORBAR_SHADE | PL_COLORBAR_SHADE_LABEL, 0,
0.005, 0.0, 0.0375, 0.875, 0, 1, 1, 0.0, 0.0,
cont_color, cont_width,
n_labels, label_opts, labels,
n_axis_opts, axis_opts,
axis_ticks, axis_subticks,
num_values, (const PLFLT * const *) values );
// Reset text and tick sizes
plschr( 0.0, 1.0 );
plsmaj( 0.0, 1.0 );
plsmin( 0.0, 1.0 );
}
plcol0( 1 );
plbox( "bcnst", 0.0, 0, "bcnstv", 0.0, 0 );
plcol0( 2 );
plcont( (const PLFLT * const *) w, nx, ny, 1, nx, 1, ny, clevel, ns, pltr2, (void *) &cgrid2 );
pllab( "distance", "altitude", "Bogon density, with streamlines" );
// Plot using 2d coordinate transform
// Load colour palettes
plspal0( "" );
plspal1( "", 1 );
// Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
plscmap0n( 3 );
pladv( 0 );
plvpor( 0.1, 0.9, 0.1, 0.9 );
plwind( -1.0, 1.0, -1.0, 1.0 );
plpsty( 0 );
plshades( (const PLFLT * const *) z, nx, ny, NULL, -1., 1., -1., 1.,
shedge, ns + 1, fill_width,
2, 3.,
plfill, 0, pltr2, (void *) &cgrid2 );
if ( colorbar )
{
// Smaller text
plschr( 0.0, 0.75 );
// Small ticks on the vertical axis
plsmaj( 0.0, 0.5 );
plsmin( 0.0, 0.5 );
num_values[0] = ns + 1;
values[0] = shedge;
plcolorbar( &colorbar_width, &colorbar_height,
PL_COLORBAR_SHADE | PL_COLORBAR_SHADE_LABEL, 0,
0.005, 0.0, 0.0375, 0.875, 0, 1, 1, 0.0, 0.0,
2, 3.,
n_labels, label_opts, labels,
n_axis_opts, axis_opts,
axis_ticks, axis_subticks,
num_values, (const PLFLT * const *) values );
// Reset text and tick sizes
plschr( 0.0, 1.0 );
plsmaj( 0.0, 1.0 );
plsmin( 0.0, 1.0 );
}
plcol0( 1 );
plbox( "bcnst", 0.0, 0, "bcnstv", 0.0, 0 );
plcol0( 2 );
// plcont((const PLFLT **) w, nx, ny, 1, nx, 1, ny, clevel, ns, pltr2, (void *) &cgrid2);
pllab( "distance", "altitude", "Bogon density" );
// Note this exclusion API will probably change.
// Plot using 2d coordinate transform and exclusion
if ( exclude )
{
// Load colour palettes
plspal0( "cmap0_black_on_white.pal" );
plspal1( "cmap1_gray.pal", 1 );
// Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
plscmap0n( 3 );
pladv( 0 );
plvpor( 0.1, 0.9, 0.1, 0.9 );
plwind( -1.0, 1.0, -1.0, 1.0 );
plpsty( 0 );
plshades( (const PLFLT * const *) z, nx, ny, zdefined, -1., 1., -1., 1.,
shedge, ns + 1, fill_width,
cont_color, cont_width,
plfill, 0, pltr2, (void *) &cgrid2 );
plcol0( 1 );
plbox( "bcnst", 0.0, 0, "bcnstv", 0.0, 0 );
pllab( "distance", "altitude", "Bogon density with exclusion" );
}
// Example with polar coordinates.
// Load colour palettes
plspal0( "cmap0_black_on_white.pal" );
plspal1( "cmap1_gray.pal", 1 );
// Reduce colors in cmap 0 so that cmap 1 is useful on a 16-color display
plscmap0n( 3 );
pladv( 0 );
plvpor( .1, .9, .1, .9 );
plwind( -1., 1., -1., 1. );
plpsty( 0 );
// Build new coordinate matrices.
for ( i = 0; i < nx; i++ )
{
r = ( (PLFLT) i ) / ( nx - 1 );
for ( j = 0; j < ny; j++ )
{
t = ( 2. * M_PI / ( ny - 1. ) ) * j;
cgrid2.xg[i][j] = r * cos( t );
cgrid2.yg[i][j] = r * sin( t );
z[i][j] = exp( -r * r ) * cos( 5. * M_PI * r ) * cos( 5. * t );
}
}
// Need a new shedge to go along with the new data set.
f2mnmx( z, nx, ny, &zmin, &zmax );
for ( i = 0; i < ns + 1; i++ )
shedge[i] = zmin + ( zmax - zmin ) * (PLFLT) i / (PLFLT) ns;
// Now we can shade the interior region.
plshades( (const PLFLT * const *) z, nx, ny, NULL, -1., 1., -1., 1.,
shedge, ns + 1, fill_width,
cont_color, cont_width,
plfill, 0, pltr2, (void *) &cgrid2 );
if ( colorbar )
{
// Smaller text
plschr( 0.0, 0.75 );
// Small ticks on the vertical axis
plsmaj( 0.0, 0.5 );
plsmin( 0.0, 0.5 );
num_values[0] = ns + 1;
values[0] = shedge;
plcolorbar( &colorbar_width, &colorbar_height,
PL_COLORBAR_SHADE | PL_COLORBAR_SHADE_LABEL, 0,
0.005, 0.0, 0.0375, 0.875, 0, 1, 1, 0.0, 0.0,
cont_color, cont_width,
n_labels, label_opts, labels,
n_axis_opts, axis_opts,
axis_ticks, axis_subticks,
num_values, (const PLFLT * const *) values );
// Reset text and tick sizes
plschr( 0.0, 1.0 );
plsmaj( 0.0, 1.0 );
plsmin( 0.0, 1.0 );
}
// Now we can draw the perimeter. (If do before, shade stuff may overlap.)
for ( i = 0; i < PERIMETERPTS; i++ )
{
t = ( 2. * M_PI / ( PERIMETERPTS - 1 ) ) * (double) i;
px[i] = cos( t );
py[i] = sin( t );
}
plcol0( 1 );
plline( PERIMETERPTS, px, py );
// And label the plot.
plcol0( 2 );
pllab( "", "", "Tokamak Bogon Instability" );
// Clean up
free( (void *) clevel );
free( (void *) shedge );
free( (void *) xg1 );
free( (void *) yg1 );
plFree2dGrid( z, nx, ny );
plFree2dGrid( w, nx, ny );
plFree2dGrid( cgrid2.xg, nx, ny );
plFree2dGrid( cgrid2.yg, nx, ny );
plend();
exit( 0 );
}
//--------------------------------------------------------------------------
// f2mnmx
//
// Returns min & max of input 2d array.
//--------------------------------------------------------------------------
static void
f2mnmx( PLFLT **f, PLINT nnx, PLINT nny, PLFLT *fnmin, PLFLT *fnmax )
{
int i, j;
*fnmax = f[0][0];
*fnmin = *fnmax;
for ( i = 0; i < nnx; i++ )
{
for ( j = 0; j < nny; j++ )
{
*fnmax = MAX( *fnmax, f[i][j] );
*fnmin = MIN( *fnmin, f[i][j] );
}
}
}