00001 00011 // for math defect 00012 #ifdef HAVE_CONFIG_H 00013 #include "config.h" 00014 #endif 00015 00016 #include "BinnerAxisLinear.h" 00017 00018 #include <algorithm> 00019 00020 #include <cmath> // for ciel() 00021 00022 #include <cassert> 00023 00024 00025 using namespace hippodraw; 00026 00027 BinnerAxisLinear::BinnerAxisLinear () 00028 : BinnerAxis ( "BinnerLinear" ) 00029 { 00030 m_width = m_range.length() / m_num_bins; 00031 } 00032 00034 BinnerAxisLinear::BinnerAxisLinear ( const BinnerAxisLinear & binner ) 00035 : BinnerAxis ( binner ) 00036 { 00037 } 00038 00039 BinnerAxisLinear::~BinnerAxisLinear() 00040 { 00041 } 00042 00043 BinnerAxis * 00044 BinnerAxisLinear::clone() 00045 { 00046 return new BinnerAxisLinear( *this ); 00047 } 00048 00049 bool 00050 BinnerAxisLinear::hasEqualWidths () const 00051 { 00052 return true; 00053 } 00054 00055 void 00056 BinnerAxisLinear::axisSetNumberOfBins ( int nb ) 00057 { 00058 m_num_bins = nb; 00059 m_width = m_range.length() / m_num_bins; 00060 } 00061 00066 int 00067 BinnerAxisLinear::axisBinNumber ( double x ) const 00068 { 00069 double lo = m_range.low (); 00070 double width = axisBinWidth ( 1 ); 00071 double f = 1.0 + ( x - lo ) / width; 00072 int i = static_cast < int > ( f ); 00073 i = std::max ( i, 0 ); 00074 i = std::min ( i, m_num_bins + 1 ); 00075 00076 return i; 00077 } 00078 00079 double 00080 BinnerAxisLinear:: 00081 getCoordinate ( int i ) const 00082 { 00083 return m_range.low() + i * ( m_range.length () / m_num_bins ); 00084 } 00085 00086 double 00087 BinnerAxisLinear::axisBinWidth ( int ) const 00088 { 00089 double width = m_range.length() / m_num_bins; 00090 00091 return width; 00092 } 00093 00094 const Range & 00095 BinnerAxisLinear:: 00096 setBinWidth ( double width ) 00097 { 00098 assert ( width > 0.0 ); 00099 00100 m_width = width; 00101 00102 m_num_bins = getNob ( width ); 00103 m_range.setLength ( m_num_bins * width ); 00104 return m_range; 00105 } 00106 00107 double 00108 BinnerAxisLinear:: 00109 calcWidthParm ( int number ) const 00110 { 00111 double new_width = ( m_range.high() - m_range.low () ) / 00112 ( static_cast < double > ( number ) ); 00113 00114 return new_width; 00115 } 00116 00117 double 00118 BinnerAxisLinear::calcOffset ( int parm, bool dragging ) const 00119 { 00120 setStartRange ( dragging ); 00121 00122 return ( parm - 50 ) / 50.0; 00123 } 00124 00125 double 00126 BinnerAxisLinear::getOffset () const 00127 { 00128 return m_offset; 00129 } 00130 00131 const void 00132 BinnerAxisLinear::setOffset ( double offset ) 00133 { 00134 double oldoff = m_offset; 00135 m_offset = offset; 00136 double change = offset - oldoff; 00137 00138 if( offset == 0.0 ) return; // resetting... 00139 Range r( m_range.low() + change * m_width, 00140 m_range.high() + change * m_width ); 00141 00142 m_range = r; 00143 } 00144 00151 const Range & 00152 BinnerAxisLinear:: 00153 setRange ( const Range & range, bool hold_width ) 00154 { 00155 m_range = range; 00156 00157 if ( hold_width && m_width < m_range.length() ) { 00158 #ifdef MATH_DEFECT 00159 double number = std::ceil ( m_range.length() / m_width ); 00160 #else 00161 double number = ceil ( m_range.length() / m_width ); 00162 #endif 00163 m_num_bins = static_cast< int > ( number ); 00164 m_range.setLength ( m_num_bins * m_width ); 00165 } 00166 else { // calc new width. 00167 m_width = m_range.length() / m_num_bins; 00168 } 00169 return m_range; 00170 } 00171 00172 double 00173 BinnerAxisLinear::getConstWid ( ) const 00174 { 00175 return axisBinWidth( 1 ); 00176 //This should really return the const width variable... but this 00177 //raises issues with when the variable needs to be recalculated. 00178 //return m_const_wid; 00179 } 00180 00181 double 00182 BinnerAxisLinear:: 00183 getBinWidth ( ) const 00184 { 00185 return getConstWid (); 00186 } 00187 00188 void 00189 BinnerAxisLinear::setConstWid ( ) 00190 { 00191 m_width = axisBinWidth( 1 ); 00192 } 00193 00194 double 00195 BinnerAxisLinear::scaleFactorWid ( ) 00196 { 00197 return getConstWid(); 00198 } 00199 00200 int BinnerAxisLinear::getNob ( const Range & range ) const 00201 { 00202 double width = getConstWid (); 00203 #ifdef MATH_DEFECT 00204 int tmp 00205 = static_cast < int > ( std::floor ( range.length () / width + 0.5 ) ); 00206 #else 00207 int tmp 00208 = static_cast < int > ( floor ( range.length() / width + 0.5 ) ); 00209 #endif 00210 00211 return tmp ? tmp : 1; 00212 } 00213 00214 int BinnerAxisLinear::getNob ( double wid ) const 00215 { 00216 int tmp = m_range.numberOfBins( wid ); 00217 00218 return tmp ? tmp : 1; 00219 }