AxisModelLinear.cxx
Go to the documentation of this file.
1 
16 #ifdef _MSC_VER
17 // Include max() and min() missing from MicroSoft Visual C++.
18 #include "msdevstudio/MSconfig.h"
19 #endif //_MSC_VER
20 
21 #include "AxisModelLinear.h"
22 
23 #include "AxisTick.h"
24 
25 #include <algorithm>
26 
27 #include <cmath>
28 #include <cstdio>
29 
30 using std::abs;
31 using std::ceil;
32 using std::floor;
33 using std::log10;
34 using std::max;
35 using std::min;
36 using std::pow;
37 using std::string;
38 using std::vector;
39 
40 namespace hippodraw {
41 
43  AxisLoc scale_loc )
44  : AxisModelBase ( label_loc, scale_loc )
45 {
46 }
47 
49  : AxisModelBase( axis_model )
50 {
51 }
52 
54 {
55 }
56 
57 /* virtual */
59 {
60  return new AxisModelLinear( *this );
61 }
62 
63 // bool FLT_EQUAL( double x, double y )
64 // {
65 // return ( abs( x - y ) <= 100.0 * DBL_EPSILON );
66 // }
67 
69 {
70  return false;
71 }
72 
74 {
75  return m_use_pmag;
76 }
77 
78 const Range &
80 {
81  //Because the low value, the high value, and the length value of the
82  //range were so frequently used, I added those three fields. There
83  //should be an improvement in performance.
84  double mylow, myhigh;
85 
86  //The use of a step field and of a mag field will be explained when
87  //they are first initialized.
88  double step, magnitude;
89 
91  const int N_NICE = 6;
92 #ifndef __STDC__
93  static
94 #endif
95  float nice[N_NICE] = { 1.0, 2.0, 2.5,
96  4.0, 5.0, 7.5 };
97 
98  const Range & init_range = getRange ( false );
99  double low = init_range.low ();
100  double high = init_range.high ();
101  if ( low == high ) { // all values in same bin
102  if ( low > 0.0 ) low *= 0.95;
103  else low *= 1.05;
104 
105  if ( high > 0.0 ) high *= 1.05;
106  else high *= 0.95;
107 
108  setRange ( low, high, low );
109  }
110  //setTickStep();
111  double range_length;
112 
113  int i;
114 
115  //double tick_step = getTickStep();
116  //tick_step /= m_scale_factor;
117  //myhigh = mylow = floor( low / tick_step ) * tick_step;
118 
119  // This increases myhigh so that "myrange" covers the whole range
120  // and then some.
121  //while( myhigh <= high ) myhigh += tick_step;
122  mylow = low - 0.05*(high-low);
123  myhigh = high + 0.05*(high-low);
124 
125  range_length = myhigh - mylow;
126 
127  // We have now decided on a range. This tries to move low/high a
128  // little to end up on a nice number.
129 
130  // First checks if either end is near 0.0
131  if( low >= 0.0 && range_length > ( 1.05 * high ) ) {
132  Range range ( 0.0, range_length );
133  setIntersectRange ( range, limit );
134  return m_range;
135  }
136  if( high <= 0.0 && -range_length < ( 1.05 * low ) ) {
137  Range range ( -range_length, 0.0 );
138  setIntersectRange ( range, limit );
139  return m_range;
140  }
141 
142  // magnitude is used to hold the magnitude of the high or low values.
143 
144  i = N_NICE - 1;
145  if( myhigh != 0.0 )
146  magnitude = ceil( log10( abs( myhigh ) ) );
147  else
148  magnitude = ceil( log10( abs( mylow ) ) );
149 
150  // What this part does is go through the low, giving it round
151  // numbers first, but more coarse over time.
152 
153  do {
154  step = nice[i] * pow( 10.0, magnitude );
155  mylow = floor( low / step ) * step;
156  myhigh = mylow + 1.05 * range_length;
157  i--;
158  if( i < 0 ) {
159  i = N_NICE - 1;
160  magnitude--;
161  }
162  } while( myhigh < high );
163 
164  Range range ( mylow, myhigh, init_range.pos() );
165 
166  setIntersectRange ( range, limit );
167 
168  return m_range;
169 }
170 
171 const Range &
173 {
174  // This doesn't do jack.
175  return getRange(false);
176 }
177 
180 Range AxisModelLinear::calcLow ( int parm, bool dragging )
181 {
182  startDragging ( dragging );
183 
184  double length = m_start_range.length ();
185  double low = m_start_range.low ();
186  double high = m_start_range.high ();
187 
188  double multiplier = ( parm - 50 ) / 50.0;
189  double new_low = min ( low + length * multiplier, high );
190 
191  if( new_low == m_range.high() ) return m_range;
192 
193  return Range ( new_low, high, m_range.pos() );
194 }
195 
198 Range AxisModelLinear::calcHigh ( int parm, bool dragging )
199 {
200  startDragging ( dragging );
201 
202  double length = m_start_range.length ();
203  double low = m_start_range.low ();
204  double high = m_start_range.high ();
205 
206  double multiplier = ( parm - 50 ) / 50.0;
207  double new_high = max ( high + length * multiplier, low );
208 
209  if( new_high == m_range.low() ) return m_range;
210 
211  return Range ( low, new_high, m_range.pos() );
212 }
213 
214 } // namespace hippodraw

Generated for HippoDraw Class Library by doxygen