inlib  1.2.0
/Users/barrand/private/dev/softinex/old/inexlib-1.2/inlib/inlib/sg/axis
Go to the documentation of this file.
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
00002 // See the file inlib.license for terms.
00003 
00004 #ifndef inlib_sg_axis
00005 #define inlib_sg_axis
00006 
00007 #include "../fmath"
00008  
00009 namespace inlib {
00010 namespace sg {
00011 
00012 class axis {
00013 public:
00014   axis()
00015   :m_min_value(0)
00016   ,m_max_value(0)
00017   ,m_steps(0)
00018   ,m_is_log(false)
00019   {}
00020   virtual ~axis(){}
00021 public:
00022   axis(const axis& a_from)
00023   :m_min_value(a_from.m_min_value)
00024   ,m_max_value(a_from.m_max_value)
00025   ,m_steps(a_from.m_steps)
00026   ,m_is_log(a_from.m_is_log)
00027   {}
00028   axis& operator=(const axis& a_from){
00029     m_min_value = a_from.m_min_value;
00030     m_max_value = a_from.m_max_value;
00031     m_steps = a_from.m_steps;
00032     m_is_log = a_from.m_is_log;
00033     return *this;
00034   }
00035 public:
00036   bool is_log(bool a_v){
00037     if(m_is_log==a_v) return false; 
00038     m_is_log = a_v;
00039     return true;
00040   }
00041   bool min_value(float a_v) {
00042     if(m_min_value==a_v) return false; 
00043     m_min_value = a_v;
00044     return true;
00045   }
00046   bool max_value(float a_v) {
00047     if(m_max_value==a_v) return false; 
00048     m_max_value = a_v;
00049     return true;
00050   }
00051   float min_value() const {return m_min_value;}
00052   float max_value() const {return m_max_value;}
00053   bool is_log() const {return m_is_log;}
00054 
00055   void adjust_axis() { //from hippodraw.
00056     int axis = 0;
00057     float step;
00058     float mylow, myhigh;
00059 #define N_NICE 4
00060     static const float nice[N_NICE] = { 1.0,2.0,2.5,5.0 };
00061   
00062     if (m_min_value > m_max_value) {
00063       float low = m_min_value;
00064       m_min_value = m_max_value;
00065       m_max_value = low;  
00066     } else if (m_min_value == m_max_value) {
00067       float value = m_min_value;  
00068       m_min_value = value - 1;
00069       m_max_value = value + 1;
00070       return;
00071     }
00072   
00073     //if (m_steps <= 0) {
00074       axis    = 1;
00075       m_steps = 10;
00076     //}
00077 
00078     // Round the "bin width" to a nice number.
00079     // If this is being done for an axis (ie m_steps was 0 , then
00080     // we don't have to go > *m_max_value.
00081     //
00082     float w = (m_max_value - m_min_value)/((float)m_steps);
00083     float mag = ffloor(flog10(w));  
00084     int i = 0;
00085     do {
00086       step   = nice[i] * fpow(10.0,mag);
00087     
00088       mylow  = ffloor(m_min_value/step) * step;
00089       myhigh = axis==1 ? fceil(m_max_value/step) * step : 
00090                          mylow + step * m_steps;
00091     
00092       i++;
00093       if (i>=N_NICE) {
00094         i = 0;
00095         mag++;
00096       }
00097     }
00098     while ( ( (axis==1) && myhigh < m_max_value) || 
00099             ( (axis==0) && myhigh <= m_max_value) );
00100   
00101     float range = myhigh - mylow;
00102   
00103     // we now have decided on a range. Try to move 
00104     // m_min_value/m_max_value a little
00105     // to end up on a nice number.
00106     //
00107     // first check if either end is near 0.0
00108     if ( !m_is_log && (m_min_value >= 0.0) && 
00109         (( (axis==1) && (range>=m_max_value) ) || 
00110          ( (axis==0) && (range>m_max_value) )) ) {  
00111       m_min_value = 0.0;
00112       m_max_value = range;
00113       return;
00114     }
00115   
00116     if ( (( (axis==1) && (m_max_value<=0.0) ) || 
00117           ( (axis==0) && (m_max_value<0.0) )) 
00118          && (-range<=m_min_value)) {     
00119       m_max_value = 0.0;
00120       m_min_value = -range;
00121       return;
00122     }
00123  
00124     // try to round *m_min_value.
00125     // correction
00126     if( m_is_log && (m_min_value<=0.0)) {  
00127       m_min_value = 1.0;
00128     }
00129     
00130     i   = N_NICE-1;
00131     mag = myhigh != 0.0 ? fceil(flog10(ffabs(myhigh))) : 
00132                           fceil(flog10(ffabs(mylow)));
00133     
00134     do {
00135       step   = nice[i] * fpow(10.0,mag);        
00136       mylow  = ffloor(m_min_value/step) * step;
00137       myhigh = mylow + range;      
00138       i--;
00139       if (i<0) {
00140         i = N_NICE-1;
00141         mag--;
00142       }
00143     } 
00144     while (( m_is_log && (mylow  <= 0.0)     ) || 
00145            ( (axis==1)  && (myhigh < m_max_value)  ) || 
00146            ( (axis==0)  && (myhigh <= m_max_value) ) );
00147     
00148     m_min_value = mylow;
00149     m_max_value = myhigh;    
00150   }
00151 
00152 
00153 protected:
00154   float m_min_value;
00155   float m_max_value;
00156   int m_steps;
00157   bool m_is_log;
00158 };
00159 
00160 }}
00161 
00162 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines