00001
00016 #ifdef _MSC_VER
00017
00018 #include "msdevstudio/MSconfig.h"
00019 #endif //_MSC_VER
00020
00021 #include "AxisModelLinear.h"
00022
00023 #include "AxisTick.h"
00024
00025 #include <algorithm>
00026
00027 #include <cmath>
00028 #include <cstdio>
00029
00030 using std::abs;
00031 using std::ceil;
00032 using std::floor;
00033 using std::log10;
00034 using std::max;
00035 using std::min;
00036 using std::pow;
00037 using std::string;
00038 using std::vector;
00039
00040 namespace hippodraw {
00041
00042 AxisModelLinear::AxisModelLinear ( AxisLoc label_loc,
00043 AxisLoc scale_loc )
00044 : AxisModelBase ( label_loc, scale_loc )
00045 {
00046 }
00047
00048 AxisModelLinear::AxisModelLinear( const AxisModelBase & axis_model )
00049 : AxisModelBase( axis_model )
00050 {
00051 }
00052
00053 AxisModelLinear::~AxisModelLinear()
00054 {
00055 }
00056
00057
00058 AxisModelBase * AxisModelLinear::clone() const
00059 {
00060 return new AxisModelLinear( *this );
00061 }
00062
00063
00064
00065
00066
00067
00068 bool AxisModelLinear::isLog() const
00069 {
00070 return false;
00071 }
00072
00073 bool AxisModelLinear::needPMag () const
00074 {
00075 return m_use_pmag;
00076 }
00077
00078 const Range &
00079 AxisModelLinear::adjustValues ( const Range & limit )
00080 {
00081
00082
00083
00084 double mylow, myhigh;
00085
00086
00087
00088 double step, magnitude;
00089
00090 adjustLogValues();
00091 const int N_NICE = 6;
00092 #ifndef __STDC__
00093 static
00094 #endif
00095 float nice[N_NICE] = { 1.0, 2.0, 2.5,
00096 4.0, 5.0, 7.5 };
00097
00098 const Range & init_range = getRange ( false );
00099 double low = init_range.low ();
00100 double high = init_range.high ();
00101 if ( low == high ) {
00102 if ( low > 0.0 ) low *= 0.95;
00103 else low *= 1.05;
00104
00105 if ( high > 0.0 ) high *= 1.05;
00106 else high *= 0.95;
00107
00108 setRange ( low, high, low );
00109 }
00110
00111 double range_length;
00112
00113 int i;
00114
00115
00116
00117
00118
00119
00120
00121
00122 mylow = low - 0.05*(high-low);
00123 myhigh = high + 0.05*(high-low);
00124
00125 range_length = myhigh - mylow;
00126
00127
00128
00129
00130
00131 if( low >= 0.0 && range_length > ( 1.05 * high ) ) {
00132 Range range ( 0.0, range_length );
00133 setIntersectRange ( range, limit );
00134 return m_range;
00135 }
00136 if( high <= 0.0 && -range_length < ( 1.05 * low ) ) {
00137 Range range ( -range_length, 0.0 );
00138 setIntersectRange ( range, limit );
00139 return m_range;
00140 }
00141
00142
00143
00144 i = N_NICE - 1;
00145 if( myhigh != 0.0 )
00146 magnitude = ceil( log10( abs( myhigh ) ) );
00147 else
00148 magnitude = ceil( log10( abs( mylow ) ) );
00149
00150
00151
00152
00153 do {
00154 step = nice[i] * pow( 10.0, magnitude );
00155 mylow = floor( low / step ) * step;
00156 myhigh = mylow + 1.05 * range_length;
00157 i--;
00158 if( i < 0 ) {
00159 i = N_NICE - 1;
00160 magnitude--;
00161 }
00162 } while( myhigh < high );
00163
00164 Range range ( mylow, myhigh, init_range.pos() );
00165
00166 setIntersectRange ( range, limit );
00167
00168 return m_range;
00169 }
00170
00171 const Range &
00172 AxisModelLinear::adjustLogValues()
00173 {
00174
00175 return getRange(false);
00176 }
00177
00180 Range AxisModelLinear::calcLow ( int parm, bool dragging )
00181 {
00182 startDragging ( dragging );
00183
00184 double length = m_start_range.length ();
00185 double low = m_start_range.low ();
00186 double high = m_start_range.high ();
00187
00188 double multiplier = ( parm - 50 ) / 50.0;
00189 double new_low = min ( low + length * multiplier, high );
00190
00191 if( new_low == m_range.high() ) return m_range;
00192
00193 return Range ( new_low, high, m_range.pos() );
00194 }
00195
00198 Range AxisModelLinear::calcHigh ( int parm, bool dragging )
00199 {
00200 startDragging ( dragging );
00201
00202 double length = m_start_range.length ();
00203 double low = m_start_range.low ();
00204 double high = m_start_range.high ();
00205
00206 double multiplier = ( parm - 50 ) / 50.0;
00207 double new_high = max ( high + length * multiplier, low );
00208
00209 if( new_high == m_range.low() ) return m_range;
00210
00211 return Range ( low, new_high, m_range.pos() );
00212 }
00213
00214 }