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