Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

BinsFunction.cxx

Go to the documentation of this file.
00001 
00016 #ifdef HAVE_CONFIG_H
00017 #include "config.h"
00018 #else
00019 #ifdef _MSC_VER
00020 // For abs.
00021 #include "msdevstudio/MSconfig.h"
00022 #endif
00023 #endif
00024 
00025 #include "BinsFunction.h"
00026 
00027 #include "datasrcs/DataPointTuple.h"
00028 #include "functions/FunctionBase.h"
00029 
00030 #include <algorithm>
00031 
00032 #include <cmath>
00033 #include <cassert>
00034 
00035 using namespace hippodraw;
00036 
00037 #ifdef ITERATOR_MEMBER_DEFECT
00038 using namespace std;
00039 #else
00040 using std::atan;
00041 using std::abs;
00042 using std::list;
00043 using std::vector;
00044 #endif
00045 
00046 BinsFunction::BinsFunction ( int nb, double ml, double mh )
00047   : m_x_range ( ml, mh )
00048 {
00049   setNumberOfBins ( Axes::X, nb );
00050   m_values_dirty = true;
00051 }
00052 
00053 BinsFunction::BinsFunction ( const BinsFunction & binner )
00054   : m_num_bins ( binner.m_num_bins ), 
00055     m_x_range ( binner.m_x_range )
00056 {
00057 }
00058 
00059 BinsFunction::~BinsFunction ()
00060 {
00061 }
00062 
00063 BinsFunction * BinsFunction::clone () const
00064 {
00065   return new BinsFunction ( *this );
00066 }
00067 
00068 void
00069 BinsFunction::
00070 setNumberOfBins ( hippodraw::Axes::Type axis, int nb )
00071 {
00072   assert ( axis == Axes::X );
00073 
00074   m_num_bins = nb;
00075 
00076   m_values_dirty = true;
00077 }
00078 
00079 namespace dp = hippodraw::DataPoint2DTuple;
00080 
00081 void 
00082 BinsFunction::
00083 resize ( unsigned int new_size, 
00084          std::list < std::vector < double > > & values )
00085 {
00086   vector < double > row ( dp::SIZE );
00087   values.resize ( new_size, row );
00088 }
00089 
00090 void
00091 BinsFunction::
00092 createValuesArray ( std::list < std::vector < double > > & values )
00093 {
00094   resize ( m_num_bins, values );
00095 
00096   double delta = m_x_range.length () / ( m_num_bins - 1 );
00097   double x = m_x_range.low ();
00098   list < vector < double >  > ::iterator it = values.begin();
00099   for ( ; it != values.end (); ++it ) {
00100     double y = m_function->operator() ( x );
00101 
00102     if ( y > DBL_MAX ) {
00103       y = m_function -> operator () ( x + 0.1 * delta );
00104     }
00105 
00106     vector < double > & row = *it;
00107     row [ dp::X ] = x;
00108     row [ dp::Y ] = y;
00109 
00110     x += delta;
00111   }
00112   smoothCurve ( values );
00113   m_values_dirty = false;
00114 }
00115 
00116 
00131 void
00132 BinsFunction::
00133 smoothCurve ( std::list < std::vector < double > > & values )
00134 {
00135   double x_length = m_x_range.length ();
00136   double xv_length = m_xv_range.length ();
00137   double min_delta = 7.0 * x_length / xv_length;
00138   double maxKink = 5.0 * M_PI / 180.0;
00139   double kinkScale 
00140     = m_yv_range.length () / m_y_range.length ()
00141     * x_length / xv_length;
00142 
00143   vector < double > row ( dp::SIZE );
00144   list < vector < double > >:: iterator p = values.begin ();
00145   for ( ; ; p++ ) {
00146     list < vector < double>  >:: iterator it1, it2;
00147     it1 = p; it1++;
00148     it2 = p; it2++; it2++;
00149     if ( it2 == values.end () ) break;
00150 
00151     while ( true ) {
00152 
00153       const vector < double > & pv = *p;
00154       const vector < double > & pv1= *it1;
00155       const vector < double > & pv2 = *it2;
00156 
00157       double x0 = pv [ dp::X ];
00158       double x1 = pv1 [ dp::X ];
00159       double x2 = pv2 [ dp::X ];
00160 
00161       double delta1 = x1 - x0;
00162       double delta2 = x2 - x1;
00163 
00164       double ydelta1 = pv1 [ dp::Y ] - pv [ dp::Y ];
00165       double ydelta2 = pv2 [ dp::Y ] - pv1 [ dp::Y ];
00166 
00167       double kink 
00168         = atan ( ydelta2 / delta2 * kinkScale )
00169         - atan ( ydelta1 / delta1 * kinkScale );
00170 
00171       if ( abs ( kink ) <= maxKink
00172            || ( delta1 <= min_delta && delta2 <= min_delta ) ) {
00173         break;
00174       }
00175       if ( delta1 <= delta2 ) {
00176         double tx = 0.5 * ( x2 + x1 );
00177         double ty = m_function->operator () ( tx );
00178         row [ dp::X ] = tx;
00179         row [ dp::Y ] = ty;
00180 
00181         it2 = values.insert ( it2, row );
00182       }
00183       else {
00184         double tx = 0.5 * ( x1 + x0 );
00185         double ty = m_function->operator () ( tx );
00186         row [ dp::X ] = tx;
00187         row [ dp::Y ] = ty;
00188         it2 = it1;
00189         it1 = values.insert ( it1, row );
00190       }
00191     } // end while
00192   } // end for
00193 }
00194 
00195 void
00196 BinsFunction::
00197 setRangeOn ( hippodraw::Axes::Type axis, 
00198              const Range & d_range,
00199              const Range & v_range )
00200 {
00201   assert ( axis == Axes::X || axis || Axes::Y );
00202   if ( axis == Axes::X ) {
00203     m_x_range = d_range;
00204     m_xv_range = v_range;
00205   }
00206   else { // Y
00207     m_y_range = d_range;
00208     m_yv_range = v_range;
00209   }
00210   m_values_dirty = true;
00211 }
00212 
00213 const Range &
00214 BinsFunction::
00215 setRange ( hippodraw::Axes::Type axis, 
00216            const Range & range, 
00217            bool )
00218 {
00219   assert ( axis == Axes::X || axis == Axes::Y );
00220   if ( axis == Axes::X ) {
00221       m_x_range = range;
00222   }
00223   else { // Y
00224       m_y_range = range;
00225   }
00226   m_values_dirty = true;
00227   return range;
00228 }
00229 
00230 void BinsFunction::setFunction ( FunctionBase * function )
00231 {
00232   m_function = function;
00233   m_values_dirty = true;
00234 }

Generated for HippoDraw-1.14.8.5 by doxygen 1.4.3