// Copyright (C) 2004 Joao Cardoso // // This file is part of PLplot. // // PLplot is free software; you can redistribute it and/or modify // it under the terms of the GNU Library General Public License as published // by the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // PLplot is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with PLplot; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #include "pltk.h" #include #include static int AppInit( Tcl_Interp *interp ); //-------------------------------------------------------------------------- // main -- // // Just a stub routine to call pltkMain. The latter is nice to have // when building extended wishes, since then you don't have to rely on // sucking the Tk main out of libtk (which doesn't work correctly on all // systems/compilers/linkers/etc). Hopefully in the future Tk will // supply a sufficiently capable tkMain() type function that can be used // instead. //-------------------------------------------------------------------------- int main( int argc, const char **argv ) { exit( pltkMain( argc, argv, NULL, AppInit ) ); } // //-------------------------------------------------------------------------- // // AppInit -- // // This procedure performs application-specific initialization. // Most applications, especially those that incorporate additional // packages, will have their own version of this procedure. // // Results: // Returns a standard Tcl completion code, and leaves an error // message in interp->result if an error occurs. // // Side effects: // Depends on the startup script. // // Taken from tkAppInit.c -- // // Copyright (c) 1993 The Regents of the University of California. // All rights reserved. // // Permission is hereby granted, without written agreement and without // license or royalty fees, to use, copy, modify, and distribute this // software and its documentation for any purpose, provided that the // above copyright notice and the following two paragraphs appear in // all copies of this software. // // IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR // DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT // OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF // CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS // ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. //-------------------------------------------------------------------------- // int myplotCmd( ClientData, Tcl_Interp *, int, char ** ); static int AppInit( Tcl_Interp *interp ) { Tk_Window mainWindow = Tk_MainWindow( interp ); // // Call the init procedures for included packages. Each call should // look like this: // // if (Mod_Init(interp) == TCL_ERROR) { // return TCL_ERROR; // } // // where "Mod" is the name of the module. // if ( Pltk_Init( interp ) == TCL_ERROR ) { return TCL_ERROR; } // // Call Tcl_CreateCommand for application-specific commands, if // they weren't already created by the init procedures called above. // Tcl_CreateCommand( interp, "myplot", (Tcl_CmdProc *) myplotCmd, (ClientData) mainWindow, (Tcl_CmdDeleteProc *) NULL ); return TCL_OK; } //-------------------------------------------------------------------------- // Taken from: // x01c.c // // Simple line plot and multiple windows demo. // static PLFLT x[101], y[101]; static PLFLT xscale, yscale, xoff, yoff, xs1[6], ys1[6]; static PLINT space0 = 0, mark0 = 0, space1 = 1500, mark1 = 1500; void myplot1( void ); void myplot2( void ); void myplot3( void ); void myplot4( void ); void plot1( void ); void plot2( void ); void plot3( void ); void myplot1() { // Set up the data // Original case xscale = 6.; yscale = 1.; xoff = 0.; yoff = 0.; // Do a plot plot1(); } void myplot2() { PLINT digmax; // Set up the data xscale = 1.; yscale = 0.0014; yoff = 0.0185; // Do a plot digmax = 5; plsyax( digmax, 0 ); plot1(); } void myplot3() { plot2(); } void myplot4() { plot3(); } //-------------------------------------------------------------------------- void plot1( void ) { int i; PLFLT xmin, xmax, ymin, ymax; for ( i = 0; i < 60; i++ ) { x[i] = xoff + xscale * ( i + 1 ) / 60.0; y[i] = yoff + yscale * pow( x[i], 2. ); } xmin = x[0]; xmax = x[59]; ymin = y[0]; ymax = y[59]; for ( i = 0; i < 6; i++ ) { xs1[i] = x[i * 10 + 3]; ys1[i] = y[i * 10 + 3]; } // Set up the viewport and window using PLENV. The range in X is // 0.0 to 6.0, and the range in Y is 0.0 to 30.0. The axes are // scaled separately (just = 0), and we just draw a labelled // box (axis = 0). plcol0( 1 ); plenv( xmin, xmax, ymin, ymax, 0, 0 ); plcol0( 6 ); pllab( "(x)", "(y)", "#frPLplot Example 1 - y=x#u2" ); // Plot the data points plcol0( 9 ); plpoin( 6, xs1, ys1, 9 ); // Draw the line through the data plcol0( 4 ); plline( 60, x, y ); } //-------------------------------------------------------------------------- void plot2( void ) { int i; // Set up the viewport and window using PLENV. The range in X is -2.0 to // 10.0, and the range in Y is -0.4 to 2.0. The axes are scaled separately // (just = 0), and we draw a box with axes (axis = 1). plcol0( 1 ); plenv( (PLFLT) -2.0, (PLFLT) 10.0, (PLFLT) -0.4, (PLFLT) 1.2, 0, 1 ); plcol0( 2 ); pllab( "(x)", "sin(x)/x", "#frPLplot Example 1 - Sinc Function" ); // Fill up the arrays for ( i = 0; i < 100; i++ ) { x[i] = ( i - 19.0 ) / 6.0; y[i] = 1.0; if ( x[i] != 0.0 ) y[i] = sin( x[i] ) / x[i]; } // Draw the line plcol0( 3 ); plline( 100, x, y ); } //-------------------------------------------------------------------------- void plot3( void ) { int i; // For the final graph we wish to override the default tick intervals, and // so do not use PLENV pladv( 0 ); // Use standard viewport, and define X range from 0 to 360 degrees, Y range // from -1.2 to 1.2. plvsta(); plwind( (PLFLT) 0.0, (PLFLT) 360.0, (PLFLT) -1.2, (PLFLT) 1.2 ); // Draw a box with ticks spaced 60 degrees apart in X, and 0.2 in Y. plcol0( 1 ); plbox( "bcnst", (PLFLT) 60.0, 2, "bcnstv", (PLFLT) 0.2, 2 ); // Superimpose a dashed line grid, with 1.5 mm marks and spaces. plstyl // expects a pointer!! plstyl( 1, &mark1, &space1 ); plcol0( 2 ); plbox( "g", (PLFLT) 30.0, 0, "g", (PLFLT) 0.2, 0 ); plstyl( 0, &mark0, &space0 ); plcol0( 3 ); pllab( "Angle (degrees)", "sine", "#frPLplot Example 1 - Sine function" ); for ( i = 0; i < 101; i++ ) { x[i] = 3.6 * i; y[i] = sin( x[i] * 3.141592654 / 180.0 ); } plcol0( 4 ); plline( 101, x, y ); } //-------------------------------------------------------------------------- // Taken from: // x16c.c // // plshade demo, using color fill. // // Maurice LeBrun // IFS, University of Texas at Austin // 20 Mar 1994 // #define NCONTR 30 // Number of contours #define XPTS 35 // Data points in x #define YPTS 46 // Datat points in y #define XSPA 2. / ( XPTS - 1 ) #define YSPA 2. / ( YPTS - 1 ) static PLFLT clevel[NCONTR]; // Utility macros #ifndef PI #define PI 3.1415926535897932384 #endif #ifndef MAX #define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) #endif #ifndef MIN #define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) #endif // Transformation function PLFLT tr[6] = { XSPA, 0.0, -1.0, 0.0, YSPA, -1.0 }; static void mypltr( PLFLT xloc, PLFLT yloc, PLFLT *tx, PLFLT *ty, void * PL_UNUSED( pltr_data ) ) { *tx = tr[0] * xloc + tr[1] * yloc + tr[2]; *ty = tr[3] * xloc + tr[4] * yloc + tr[5]; } // Function prototypes static void f2mnmx( PLFLT **f, PLINT nx, PLINT ny, PLFLT *fmin, PLFLT *fmax ); void shade( void ); //-------------------------------------------------------------------------- // shade // // Does several shade plots using different coordinate mappings. //-------------------------------------------------------------------------- void shade( void ) { int i, j; PLFLT xloc, yloc, argx, argy, distort; PLFLT **z, **w, zmin, zmax; PLFLT xg1[XPTS], yg1[YPTS]; PLcGrid cgrid1; PLcGrid2 cgrid2; PLFLT shade_min, shade_max, sh_color; PLINT sh_cmap = 1, sh_width; PLINT min_color = 1, min_width = 0, max_color = 0, max_width = 0; // Set up function arrays plAlloc2dGrid( &z, XPTS, YPTS ); plAlloc2dGrid( &w, XPTS, YPTS ); // Set up data array for ( i = 0; i < XPTS; i++ ) { xloc = (double) ( i - ( XPTS / 2 ) ) / (double) ( XPTS / 2 ); for ( j = 0; j < YPTS; j++ ) { yloc = (double) ( j - ( YPTS / 2 ) ) / (double) ( YPTS / 2 ) - 1.0; z[i][j] = -sin( 7. * xloc ) * cos( 7. * yloc ) + xloc * xloc - yloc * yloc; w[i][j] = -cos( 7. * xloc ) * sin( 7. * yloc ) + 2 * xloc * yloc; } } f2mnmx( z, XPTS, YPTS, &zmin, &zmax ); for ( i = 0; i < NCONTR; i++ ) clevel[i] = zmin + ( zmax - zmin ) * ( i + 0.5 ) / (PLFLT) NCONTR; // Set up coordinate grids cgrid1.xg = xg1; cgrid1.yg = yg1; cgrid1.nx = XPTS; cgrid1.ny = YPTS; plAlloc2dGrid( &cgrid2.xg, XPTS, YPTS ); plAlloc2dGrid( &cgrid2.yg, XPTS, YPTS ); cgrid2.nx = XPTS; cgrid2.ny = YPTS; for ( i = 0; i < XPTS; i++ ) { for ( j = 0; j < YPTS; j++ ) { mypltr( (PLFLT) i, (PLFLT) j, &xloc, &yloc, NULL ); argx = xloc * PI / 2; argy = yloc * PI / 2; distort = 0.4; cgrid1.xg[i] = xloc + distort * cos( argx ); cgrid1.yg[j] = yloc - distort * cos( argy ); cgrid2.xg[i][j] = xloc + distort * cos( argx ) * cos( argy ); cgrid2.yg[i][j] = yloc - 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 ); for ( i = 0; i < NCONTR; i++ ) { shade_min = zmin + ( zmax - zmin ) * i / (PLFLT) NCONTR; shade_max = zmin + ( zmax - zmin ) * ( i + 1 ) / (PLFLT) NCONTR; sh_color = i / (PLFLT) ( NCONTR - 1 ); sh_width = 2; plpsty( 0 ); plshade( (const PLFLT * const *) z, XPTS, YPTS, NULL, -1., 1., -1., 1., shade_min, shade_max, sh_cmap, sh_color, sh_width, min_color, min_width, max_color, max_width, plfill, 1, NULL, NULL ); } plcol0( 1 ); plbox( "bcnst", 0.0, 0, "bcnstv", 0.0, 0 ); plcol0( 2 ); // // plcont(w, XPTS, YPTS, 1, XPTS, 1, YPTS, clevel, NCONTR, mypltr, NULL); // pllab( "distance", "altitude", "Bogon density" ); // Clean up plFree2dGrid( z, XPTS, YPTS ); plFree2dGrid( w, XPTS, YPTS ); plFree2dGrid( cgrid2.xg, XPTS, YPTS ); plFree2dGrid( cgrid2.yg, XPTS, YPTS ); } //-------------------------------------------------------------------------- // f2mnmx // // Returns min & max of input 2d array. //-------------------------------------------------------------------------- static void f2mnmx( PLFLT **f, PLINT nx, PLINT ny, PLFLT *fmn, PLFLT *fmx ) { int i, j; *fmx = f[0][0]; *fmn = *fmx; for ( i = 0; i < nx; i++ ) { for ( j = 0; j < ny; j++ ) { *fmx = MAX( *fmx, f[i][j] ); *fmn = MIN( *fmn, f[i][j] ); } } } //-------------------------------------------------------------------------- int myplotCmd( ClientData PL_UNUSED( cd ), Tcl_Interp *PL_UNUSED( interp ), int PL_UNUSED( argc ), char **argv ) { if ( !strcmp( argv[1], "1" ) ) myplot1(); if ( !strcmp( argv[1], "2" ) ) myplot2(); if ( !strcmp( argv[1], "3" ) ) myplot3(); if ( !strcmp( argv[1], "4" ) ) shade(); plflush(); return TCL_OK; }