scale.c

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

Generated on Mon Sep 18 01:24:47 2006 for BRL-CAD by  doxygen 1.4.6