BRL-CAD
scale.c
Go to the documentation of this file.
1 /* S C A L E . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @addtogroup plot */
21 /** @{ */
22 /** @file libbn/scale.c
23  *
24  * @brief scale geometry points.
25  *
26  * @note
27  * This file is a candidate for deletion.
28  * Nothing else in BRL-CAD uses this.
29  */
30 
31 #include "common.h"
32 
33 #include <stdio.h>
34 #include <math.h>
35 #include "vmath.h"
36 #include "plot3.h"
37 
38 /**
39  * @brief
40  * This routine is intended to take an array of
41  * data points as input (either integer, floating, or
42  * double), and scale it to fit in a space of LENGTH units.
43  *
44  * An output array is returned
45  * which contains the scaled information stored in 16-bit integers. The input
46  * and output arrays may overlap, as the input will never
47  * occupy more space than the output. Also output are
48  * the minimum value encountered (MIN), and a delta
49  * factor showing the increase in value each XXXX.
50  * This DX factor is rounded to 1, 2, 4, 5, 8, or 10 to
51  * produce nicer looking axes.
52  *
53  *
54  * @param[in] idata This pointer contains the address
55  * of the input array to be scaled.
56  * Actual type of array is determined
57  * by MODE parameter.
58  *
59  * @param[in] elements Number of elements in IDATA to be used.
60  *
61  * @param[in] mode Specifies type of data that IDATA points
62  * to; should be one of:
63  * 'd' - double precision
64  * 'f' - float (single precision)
65  * 'i' - integer
66  *
67  * @param[in] length Contains the length (in 1/1000ths of an
68  * inch) of the region in which the data is
69  * to be scaled into. Note that the actual
70  * amount of space needed may be this value
71  * rounded up to the next inch.
72  *
73  * @param[out] odata This pointer contains the address of the
74  * output array, which will always be of
75  * integer type.
76  *
77  * @param[out] min This pointer contains the address of the
78  * location for minimum point found to be
79  * placed in.
80  *
81  * @param dx This pointer addresses the delta value
82  * of the data which corresponds to the width
83  * of EACH tick.
84  * This implies that:
85  * -# This is exactly the number to divide
86  * raw data by to scale it to this scale
87  * (ex: 2 graphs with one scale factor)
88  * -# When this value is fed to the AXIS
89  * routine, it must be multiplied
90  * by 1000.0 first (to specify increment
91  * between one INCH ticks).
92  *
93  * The fact that this routine returns variables of type DOUBLE has
94  * important implications for FORTRAN users. These variables must
95  * be declared of type DOUBLE PRECISION to reserve enough space.
96  */
97 void
98 tp_scale(int *idata,
99  int elements,
100  register int mode,
101  int length,
102  int *odata,
103  double *min,
104  double *dx)
105 {
106  double xmax, xmin, x, workdx;
107  register int i; /* Index variable */
108  static double log_10; /* Saved value for log base-2(10) */
109  float *ifloatp; /* Used to convert pointer-to-int to float */
110  double *idoublep; /* Used to convert pointer-to-int to double */
111  double fractional; /* Fractional part of DX */
112  int integral; /* Integral part of DX */
113 
114  /* Prepare to use a pointer to an array of variable type */
115  ifloatp = (float *)idata;
116  idoublep = (double *)idata;
117  /* Find the maximum and minimum data values */
118  xmax = xmin = 0.0;
119  for ( i=0; i<elements; i++ ) {
120  x = (mode=='f')
121  ? ifloatp[i]
122  : ( (mode=='d')
123  ? idoublep[i]
124  : idata[i]
125  );
126  V_MAX(xmax, x);
127  V_MIN(xmin, x);
128  }
129 
130  /* Split initial DX into integral and fractional exponents of 10 */
131  if ( log_10 <= 0.0 )
132  log_10 = log(10.0);
133 
134  fractional = log( (xmax-xmin)/length ) / log_10; /* LOG10(DX) */
135  integral = fractional; /* truncate! */
136  fractional -= integral; /* leave only fract */
137 
138  if ( fractional < 0.0 ) {
139  fractional += 1.0; /* ?? */
140  integral -= 1;
141  }
142 
143  fractional = pow( 10.0, fractional );
144  i = fractional - 0.01;
145  switch ( i ) {
146 
147  case 1:
148  fractional = 2.0;
149  break;
150 
151  case 2:
152  case 3:
153  fractional = 4.0;
154  break;
155 
156  case 4:
157  fractional = 5.0;
158  break;
159 
160  case 5:
161  case 6:
162  case 7:
163  fractional = 8.0;
164  break;
165 
166  case 8:
167  case 9:
168  fractional = 10.0;
169 
170  }
171 
172  /* Compute DX factor, combining power of ten & adjusted co-efficient */
173  workdx = pow( 10.0, (double)integral ) * fractional;
174 
175  /* Apply the MIN and DX values to the users input data */
176  for ( i=0; i<elements; i++ ) {
177  if ( mode == 'f' )
178  odata[i] = (ifloatp[i] - xmin) / workdx;
179  else
180  if ( mode == 'd' )
181  odata[i] = (idoublep[i] - xmin) / workdx;
182  else
183  odata[i] = (idata[i] - xmin) / workdx;
184  }
185 
186  /* Send MIN and DX back to the user */
187  *min = xmin;
188  *dx = workdx;
189 }
190 
191 
192 /*
193  * FORTRAN Interface
194  */
195 void
196 PL_FORTRAN(fscale, FSCALE)(int idata[], int *elements, char *mode, int *length, int odata[], double *min, double *dx)
197 {
198  tp_scale( idata, *elements, *mode, *length, odata, min, dx );
199 }
200 
201 /** @} */
202 /*
203  * Local Variables:
204  * mode: C
205  * tab-width: 8
206  * indent-tabs-mode: t
207  * c-file-style: "stroustrup"
208  * End:
209  * ex: shiftwidth=4 tabstop=8
210  */
Header file for the BRL-CAD common definitions.
void tp_scale(int *idata, int elements, register int mode, int length, int *odata, double *min, double *dx)
This routine is intended to take an array of data points as input (either integer, floating, or double), and scale it to fit in a space of LENGTH units.
Definition: scale.c:98
void PL_FORTRAN(fscale, FSCALE)
Definition: scale.c:196