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
unsigned int i
virtual Range calcHigh(int parm, bool dragging=false)
double high() const
Returns the maximum of the range object.
Definition: Range.cxx:100
virtual const Range & adjustLogValues()
Adjusts the range for nice logging.
hippodraw::AxisModelLinear class interface
virtual bool needPMag() const
The following functions are used by the AxisRepBase * object.
virtual bool isLog() const
Returns false because this class represents a linear scale.
Range m_start_range
The starting range before start of dragging events.
Definition: AxisModelBase.h:46
~AxisModelLinear()
The destructor.
void setRange(double low, double high, double pos)
Sets the Range to the low and high values.
AxisLoc
The base class for the binner hierarchy.
Definition: AxisLoc.h:17
The AxisModelBase class maintains the Range and scaling of an axis.
Definition: AxisModelBase.h:33
double length() const
Returns the length of the range object.
Definition: Range.h:156
void startDragging(bool dragging)
Sets the member m_start_dragging to the current range if dragging is starting.
virtual const Range & adjustValues(const Range &)
Sets the number of minor ticks that are between the major ones.
virtual Range calcLow(int parm, bool dragging=false)
bool m_use_pmag
A flag to indicate that one will using scientific notation.
Definition: AxisModelBase.h:93
const Range & getRange(bool scaled) const
Returns the range represented by this AxisModel.
double low() const
Returns the minimum of the range object.
Definition: Range.cxx:87
Expresses a range of values.
Definition: Range.h:33
Range m_range
The current range of the axis.
Definition: AxisModelBase.h:38
void setIntersectRange(const Range &, const Range &)
Sets the Range to overlap of the two ranges.
double pos() const
Returns the first positive element in range.
Definition: Range.cxx:113
virtual AxisModelBase * clone() const
The clone function returns an object of its own kind which is a copy of this object at this moment...
AxisModelLinear(AxisLoc label, AxisLoc scale)
The constructor sets the location of the ticks, labels, and scale.
AxisTick class interface.

Generated for HippoDraw Class Library by doxygen