/* @(#)plmodf.c 17.1.1.1 (ES0-DMD) 01/25/02 17:44:49 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COPYRIGHT (c) 1993 European Southern Observatory .IDENTifer PLMODF .AUTHOR R.M. van Hees IPG-ESO Garching .KEYWORDS low level plot routine .LANGUAGE C .PURPOSE modify data values in a frame using the cursor input: char *cpntr pointer to the frame int *image contains in pixel units int *npix number of pixels in x and y double *start value of first pixel in world coordinates double *step distance between pixels in world coordinates int ncur number of curor positions int ndeg degree of the polynomial interpolation int binmode bin mode in/output: int *go_on flag which tels the outside world to stop or to go on int *ibar has the user pressed the space bar?? .COMMENTS holds static functions SORT2, ALINT, AITKEN .ENVIRONment MIDAS and AGL #include Prototypes for AGL application programs #include Prototypes for MIDAS interfaces #include Symbols used by the PLT interfaces .VERSION 1.0 18-Aug-1993 FORTRAN --> ANSI-C RvH ------------------------------------------------------------*/ /* * Define _POSIX_SOURCE to indicate * that this is a POSIX program */ #define _POSIX_SOURCE 1 /* * definition of the used functions in this module */ #include #include #include /* * define some macros and constants */ #include #define BAR 32 #define MAXDEG 100 /* * declaration of private functions used in this module */ /*++++++++++++++++++++++++++++++ .IDENTifer SORT2 .PURPOSE Sort string of values into ascending sequence of values input: int n dimension of arrays xval and yval in/output float xval[] array to be sorted float yval[] array to be sorted like the first array ------------------------------*/ #ifdef __STDC__ static void SORT2( int n, float *xval, float *yval ) #else static void SORT2( n, xval, yval ) int n; float *xval, *yval; #endif { register int indx; if ( n < 2 ) return; indx = n - 1; do { register int jj, ii = -1; for ( jj = 0; jj < indx; jj++ ) { if ( xval[jj] > xval[jj+1] ) { float xtemp = xval[jj], ytemp = yval[jj]; xval[jj] = xval[jj+1]; yval[jj] = yval[jj+1]; xval[jj+1] = xtemp; yval[jj+1] = ytemp; ii = jj; } } indx = ii; } while ( indx != -1 ); } /*++++++++++++++++++++++++++++++ .IDENTifer ALINT .PURPOSE linear interpolation over a range in values input: float *xval values along the X-axis float *yval values along the Y-axis float xarg X-value of the requested return value int str first data item which may be used int last last data item which may be used .RETURNS Y-value at X position: xarg ------------------------------*/ #ifdef __STDC__ static float ALINT( float *xval, float *yval, float xarg, int str, int last ) #else static float ALINT( xval, yval, xarg, str, last ) int str, last; float *xval, *yval, xarg; #endif { int pix[2]; double dx[2], dy[2]; /* * select the effective interval */ pix[1] = str; while ( xval[pix[1]] < xarg && pix[1] < last ) pix[1]++; if ( pix[1] == str ) pix[1] += 1; pix[0] = pix[1] - 1; /* * and do the interpolation */ dx[0] = (double) xval[pix[0]]; dx[1] = (double) xval[pix[1]]; dy[0] = (double) yval[pix[0]]; dy[1] = (double) yval[pix[1]]; return (float) dy[0] + (dy[1] - dy[0]) * (xarg - dx[0]) / (dx[1] - dx[0]); } /*++++++++++++++++++++++++++++++ .IDENTifer AITKEN .PURPOSE Aitken interpolation input: float *xval values along the X-axis float *yval values along the Y-axis float xarg X-value of the requested return value int str first data item which may be used int last last data item which may be used int ideg degree of the polynomial interpolation .RETURNS Y-value at X position: xarg ------------------------------*/ #ifdef __STDC__ static float AITKEN( float *xval, float *yval, float xarg, int str, int last, int ideg ) #else static float AITKEN( xval, yval, xarg, str, last, ideg ) int str, last, ideg; float *xval, *yval, xarg; #endif { int id, ii, jj, pix[2]; double dx[MAXDEG], dy[MAXDEG]; ii = str + 1; while( (xarg >= xval[ii-1] && xarg < xval[ii]) && (ii++ < last) ); pix[0] = MYMAX( str, ii - ideg + 1 ); pix[1] = pix[0] + ideg; if ( pix[1] > last ) { pix[1] = last; pix[0] = pix[1] - ideg; } for ( id = 0, ii = pix[0]; ii <= pix[1]; id++, ii++ ) { dx[id] = xval[ii]; dy[id] = yval[ii]; } for ( ii = 0; ii < id; ii++ ) { for ( jj = ii; jj <= id; jj++ ) { dy[jj+1] = dy[ii] + (xarg - dx[ii]) * (dy[jj+1] - dy[ii]) / (dx[jj+1] - dx[ii]); } } return (float) dy[id+1]; } /*++++++++++++++++++++++++++++++++++++++++++++++++++ * * Here starts the code of the main routine */ void PLMODF(cpntr, image, npix, start, step, ncur, ndeg, binmode, go_on, ibar) char *cpntr; float *image; int *npix; double *start, *step; int ncur, ndeg, binmode, *go_on, *ibar; { int ii, indx, key, mnpix, mxpix, nc, nnpix, pixval, pix[2]; float *p_row; float *xval, *yval, *xpos; float xv = 0.0, yv = 0.0; xval = (float *) osmmget( ncur * sizeof( float )); yval = (float *) osmmget( ncur * sizeof( float )); indx = (int) (*(image+2) - 1) * *npix; p_row = (float *) cpntr + indx; /* * set the coordinate system to USER */ AG_SSET( "user" ); mnpix = (int) MYMIN( *image, *(image+1) )-1; mxpix = (int) MYMAX( *image, *(image+1) )-1; do { nc = 0; do { AG_VLOC( &xv, &yv, &key, &pixval ); if ( key == BAR ) { if ( *ibar == 0 ) *ibar = 1; else *go_on = FALSE; } else { *ibar = 0; xval[nc] = xv; yval[nc] = yv; AG_GPLM( &xv, &yv, 1, 4 ); } nc++; } while ( nc < ncur && key != BAR ); /* * sort the given positions and determine the range effective for change */ if ( key != BAR ) { SORT2( ncur, xval, yval ); pix[0] = (int) ((xval[0] - start[0])/step[0] + 0.5); if ( mnpix > pix[0]) pix[0] = mnpix; pix[1] = (int)( (xval[ncur-1] - start[0])/step[0] + 0.5); if ( mxpix < pix[1] ) pix[1] = mxpix; nnpix = abs(pix[1] - pix[0]) + 1; /* * we calculate the x position one before and one after the new values */ xpos = (float *) osmmget( nnpix * sizeof( float )); if (step[0] > 0) for ( ii = 0; ii < nnpix; ii++ ) xpos[ii] = (float) (start[0] + (pix[0]+ii) * step[0]); else for ( ii = 0; ii < nnpix; ii++ ) xpos[ii] = (float) (start[0] + (pix[1]+ii) * step[0]); /* * we interpolate between the given values */ for ( ii = 0; ii < nnpix; ii++ ) { if ( ndeg < 2 ) if (step[0] > 0) *(p_row+pix[0]+ii) = ALINT( xval, yval, xpos[ii], 0, ncur-1 ); else *(p_row+pix[1]+ii) = ALINT( xval, yval, xpos[ii], 0, ncur-1 ); else if (step[0] > 0) *(p_row+pix[0]+ii) = AITKEN( xval, yval, xpos[ii], 0, ncur-1, ndeg ); else *(p_row+pix[1]+ii) = AITKEN( xval, yval, xpos[ii], 0, ncur-1, ndeg ); } /* * and draw the line nicely connected with the old data */ if (step[0] > 0) PCDATA( 0, 1, binmode, xpos, p_row+pix[0], 0.0, nnpix ); else PCDATA( 0, 1, binmode, xpos, p_row+pix[1], 0.0, nnpix ); (void) osmmfree( (char *) xpos ); } } while ( *go_on && *ibar == 0 ); (void) osmmfree( (char *) xval ); (void) osmmfree( (char *) yval ); return; }