scale.c

Go to the documentation of this file.
00001 /*                         S C A L E . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 2004-2012 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * version 2.1 as published by the Free Software Foundation.
00010  *
00011  * This library is distributed in the hope that it will be useful, but
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this file; see the file named COPYING for more
00018  * information.
00019  */
00020 /** @addtogroup plot */
00021 /** @{ */
00022 /** @file libbn/scale.c
00023  *
00024  * @brief scale geometry points.
00025  *
00026  *      @note
00027  *      This file is a candidate for deletion.
00028  *      Nothing else in BRL-CAD uses this.
00029  */
00030 
00031 #include "common.h"
00032 
00033 #include <stdio.h>
00034 #include <math.h>
00035 #include "vmath.h"
00036 #include "plot3.h"
00037 
00038 /**
00039  * @brief
00040  *      This routine is intended to take an array of
00041  * data points as input (either integer, floating, or
00042  * double), and scale it to fit in a space of LENGTH units.
00043  *
00044  * An output array is returned
00045  * which contains the scaled information stored in 16-bit integers.  The input
00046  * and output arrays may overlap, as the input will never
00047  * occupy more space than the output.  Also output are
00048  * the minimum value encountered (MIN), and a delta
00049  * factor showing the increase in value each XXXX.
00050  * This DX factor is rounded to 1, 2, 4, 5, 8, or 10 to
00051  * produce nicer looking axes.
00052  *
00053  *
00054  *      @param[in] idata        This pointer contains the address
00055  *                              of the input array to be scaled.
00056  *                              Actual type of array is determined
00057  *                              by MODE parameter.
00058  *
00059  *      @param[in] elements     Number of elements in IDATA to be used.
00060  *
00061  *      @param[in] mode         Specifies type of data that IDATA points
00062  *                              to;  should be one of:
00063  *                                      'd' - double precision
00064  *                                      'f' - float (single precision)
00065  *                                      'i' - integer
00066  *
00067  *      @param[in] length               Contains the length (in 1/1000ths of an
00068  *                              inch) of the region in which the data is
00069  *                              to be scaled into.  Note that the actual
00070  *                              amount of space needed may be this value
00071  *                              rounded up to the next inch.
00072  *
00073  *      @param[out] odata       This pointer contains the address of the
00074  *                              output array, which will always be of
00075  *                              integer type.
00076  *
00077  *      @param[out] min         This pointer contains the address of the
00078  *                              location for minimum point found to be
00079  *                              placed in.
00080  *
00081  *      @param dx               This pointer addresses the delta value
00082  *                              of the data which corresponds to the width
00083  *                              of EACH tick.
00084  *                              This implies that:
00085  *                               -#     This is exactly the number to divide
00086  *                                      raw data by to scale it to this scale
00087  *                                      (ex:  2 graphs with one scale factor)
00088  *                               -#     When this value is fed to the AXIS
00089  *                                      routine, it must be multiplied
00090  *                                      by 1000.0 first (to specify increment
00091  *                                      between one INCH ticks).
00092  *
00093  * The fact that this routine returns variables of type DOUBLE has
00094  * important implications for FORTRAN users.  These variables must
00095  * be declared of type DOUBLE PRECISION to reserve enough space.
00096  */
00097 void
00098 tp_scale(int *idata,
00099          int elements,
00100          register int mode,
00101          int length,
00102          int *odata,
00103          double *min,
00104          double *dx)
00105 {
00106     double xmax, xmin, x, workdx;
00107     register int i;                     /* Index variable */
00108     static double log_10;               /* Saved value for log base-2(10) */
00109     float *ifloatp;                     /* Used to convert pointer-to-int to float */
00110     double *idoublep;           /* Used to convert pointer-to-int to double */
00111     double fractional;          /* Fractional part of DX */
00112     int integral;                       /* Integral part of DX */
00113 
00114     /* Prepare to use a pointer to an array of variable type */
00115     ifloatp = (float *)idata;
00116     idoublep = (double *)idata;
00117     /* Find the maximum and minimum data values */
00118     xmax = xmin = 0.0;
00119     for ( i=0; i<elements; i++ )  {
00120         x = (mode=='f')
00121             ? ifloatp[i]
00122             : ( (mode=='d')
00123                 ? idoublep[i]
00124                 : idata[i]
00125                 );
00126         if ( x > xmax )
00127             xmax = x;
00128         if ( x < xmin )
00129             xmin = x;
00130     }
00131 
00132     /* Split initial DX into integral and fractional exponents of 10 */
00133     if ( log_10 <= 0.0 )
00134         log_10 = log(10.0);
00135 
00136     fractional = log( (xmax-xmin)/length ) / log_10;    /* LOG10(DX) */
00137     integral = fractional;                      /* truncate! */
00138     fractional -= integral;                     /* leave only fract */
00139 
00140     if ( fractional < 0.0 )  {
00141         fractional += 1.0;              /* ?? */
00142         integral -= 1;
00143     }
00144 
00145     fractional = pow( 10.0, fractional );
00146     i = fractional - 0.01;
00147     switch ( i )  {
00148 
00149         case 1:
00150             fractional = 2.0;
00151             break;
00152 
00153         case 2:
00154         case 3:
00155             fractional = 4.0;
00156             break;
00157 
00158         case 4:
00159             fractional = 5.0;
00160             break;
00161 
00162         case 5:
00163         case 6:
00164         case 7:
00165             fractional = 8.0;
00166             break;
00167 
00168         case 8:
00169         case 9:
00170             fractional = 10.0;
00171 
00172     }
00173 
00174     /* Compute DX factor, combining power of ten & adjusted co-efficient */
00175     workdx = pow( 10.0, (double)integral ) * fractional;
00176 
00177     /* Apply the MIN and DX values to the users input data */
00178     for ( i=0; i<elements; i++ )  {
00179         if ( mode == 'f' )
00180             odata[i] = (ifloatp[i] - xmin) / workdx;
00181         else
00182             if ( mode == 'd' )
00183                 odata[i] = (idoublep[i] - xmin) / workdx;
00184             else
00185                 odata[i] = (idata[i] - xmin) / workdx;
00186     }
00187 
00188     /* Send MIN and DX back to the user */
00189     *min = xmin;
00190     *dx = workdx;
00191 }
00192 
00193 
00194 /**
00195  *      FORTRAN Interface
00196  */
00197 void
00198 PL_FORTRAN(fscale, FSCALE)(int idata[], int *elements, char *mode, int *length, int odata[], double *min, double *dx)
00199 {
00200     tp_scale( idata, *elements, *mode, *length, odata, min, dx );
00201 }
00202 
00203 /** @} */
00204 /*
00205  * Local Variables:
00206  * mode: C
00207  * tab-width: 8
00208  * indent-tabs-mode: t
00209  * c-file-style: "stroustrup"
00210  * End:
00211  * ex: shiftwidth=4 tabstop=8
00212  */
Generated on Tue Dec 11 13:14:28 2012 for LIBBN by  doxygen 1.6.3