| //===========================================================================// |
| // Purpose : Method definitions for a TC_MinGrid minimum grid class. |
| // |
| // Public methods include: |
| // - NewInstance, DeleteInstance, GetInstance |
| // - SetGrid |
| // - IntToFloat, UnsignedIntToFloat, LongIntToFloat |
| // - FloatToInt, FloatToUnsignedInt, FloatToLongInt |
| // - SnapToGrid |
| // - SnapToGridCeil |
| // - IsOnGrid |
| // |
| // Protected methods include: |
| // - TC_MinGrid_c, ~TC_MinGrid_c |
| // |
| //===========================================================================// |
| |
| //---------------------------------------------------------------------------// |
| // Copyright (C) 2012-2013 Jeff Rudolph, Texas Instruments (jrudolph@ti.com) // |
| // // |
| // Permission is hereby granted, free of charge, to any person obtaining a // |
| // copy of this software and associated documentation files (the "Software"),// |
| // to deal in the Software without restriction, including without limitation // |
| // the rights to use, copy, modify, merge, publish, distribute, sublicense, // |
| // and/or sell copies of the Software, and to permit persons to whom the // |
| // Software is furnished to do so, subject to the following conditions: // |
| // // |
| // The above copyright notice and this permission notice shall be included // |
| // in all copies or substantial portions of the Software. // |
| // // |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // |
| // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // |
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // |
| // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // |
| // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // |
| // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // |
| // USE OR OTHER DEALINGS IN THE SOFTWARE. // |
| //---------------------------------------------------------------------------// |
| |
| #include <climits> |
| #include <cmath> |
| using namespace std; |
| |
| #include "TCT_Generic.h" |
| |
| #include "TC_Typedefs.h" |
| #include "TC_MinGrid.h" |
| |
| // Initialize the min grid "singleton" class, as needed |
| TC_MinGrid_c* TC_MinGrid_c::pinstance_ = 0; |
| |
| //===========================================================================// |
| // Method : TC_MinGrid_c |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| TC_MinGrid_c::TC_MinGrid_c( |
| void ) |
| : |
| grid_( 0.1 ), |
| units_( 10 ), |
| magnitude_( 10 ), |
| precision_( 1 ) |
| { |
| this->SetGrid( TC_MIN_GRID_DEF ); |
| } |
| |
| //===========================================================================// |
| // Method : ~TC_MinGrid_c |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| TC_MinGrid_c::~TC_MinGrid_c( |
| void ) |
| { |
| } |
| |
| //===========================================================================// |
| // Method : NewInstance |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| void TC_MinGrid_c::NewInstance( |
| void ) |
| { |
| pinstance_ = new TC_NOTHROW TC_MinGrid_c; |
| } |
| |
| //===========================================================================// |
| // Method : DeleteInstance |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| void TC_MinGrid_c::DeleteInstance( |
| void ) |
| { |
| if( pinstance_ ) |
| { |
| delete pinstance_; |
| pinstance_ = 0; |
| } |
| } |
| |
| //===========================================================================// |
| // Method : GetInstance |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| TC_MinGrid_c& TC_MinGrid_c::GetInstance( |
| void ) |
| { |
| if( !pinstance_ ) |
| { |
| NewInstance( ); |
| } |
| return( *pinstance_ ); |
| } |
| |
| //===========================================================================// |
| // Method : SetGrid |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| void TC_MinGrid_c::SetGrid( |
| double grid ) |
| { |
| this->grid_ = grid; |
| if( this->grid_ > TC_FLT_EPSILON ) |
| { |
| // Compute database units (integer) based on min grid value |
| double units = ( 1.0 / this->grid_ ) + TC_FLT_EPSILON; |
| this->units_ = static_cast< unsigned int >( units ); |
| |
| // Compute format precision (integer) based on min grid value |
| double precision = 10.0; |
| while( precision <= 1000000.0 + TC_FLT_EPSILON ) |
| { |
| double f = this->grid_ * precision; |
| double c = ceil( f - TC_FLT_EPSILON ); |
| if( fabs( c - f ) < TC_FLT_EPSILON ) |
| break; |
| |
| precision *= 10.0; |
| } |
| precision = ceil( log10( precision )); |
| this->precision_ = static_cast< unsigned int >( precision ); |
| |
| // Compute database magnitude (integer) based on precision value |
| this->magnitude_ = 1; |
| for( unsigned int n = 1; n <= this->precision_; ++n ) |
| { |
| this->magnitude_ *= 10; |
| } |
| } |
| } |
| |
| //===========================================================================// |
| // Method : IntToFloat |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| double TC_MinGrid_c::IntToFloat( |
| int i ) const |
| { |
| double f; |
| TCT_UnitToFloat( i, &f, this->units_ ); |
| |
| return( f ); |
| } |
| |
| //===========================================================================// |
| // Method : UnsignedIntToFloat |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| double TC_MinGrid_c::UnsignedIntToFloat( |
| unsigned int ui ) const |
| { |
| double f; |
| TCT_UnitToFloat( ui, &f, this->units_ ); |
| |
| return( f ); |
| } |
| |
| //===========================================================================// |
| // Method : LongIntToFloat |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| double TC_MinGrid_c::LongIntToFloat( |
| long int li ) const |
| { |
| double f; |
| TCT_UnitToFloat( li, &f, this->units_ ); |
| |
| return( f ); |
| } |
| |
| //===========================================================================// |
| // Method : FloatToInt |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| int TC_MinGrid_c::FloatToInt( |
| double f ) const |
| { |
| int i; |
| if( f < static_cast< double >( INT_MIN ) - TC_FLT_EPSILON ) |
| { |
| i = INT_MIN; |
| } |
| else if( f > static_cast< double >( INT_MAX ) - TC_FLT_EPSILON ) |
| { |
| i = INT_MAX; |
| } |
| else |
| { |
| TCT_FloatToUnit( f, &i, this->units_ ); |
| } |
| return( i ); |
| } |
| |
| //===========================================================================// |
| // Method : FloatToUnsignedInt |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| unsigned int TC_MinGrid_c::FloatToUnsignedInt( |
| double f ) const |
| { |
| unsigned int ui; |
| if( f < static_cast< double >( 0 ) - TC_FLT_EPSILON ) |
| { |
| ui = UINT_MAX; |
| } |
| else if( f > static_cast< double >( UINT_MAX ) - TC_FLT_EPSILON ) |
| { |
| ui = UINT_MAX; |
| } |
| else |
| { |
| TCT_FloatToUnit( f, &ui, this->units_ ); |
| } |
| return( ui ); |
| } |
| |
| //===========================================================================// |
| // Method : FloatToLongInt |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| long int TC_MinGrid_c::FloatToLongInt( |
| double f ) const |
| { |
| long int li; |
| if( f < static_cast< double >( LONG_MIN ) - TC_FLT_EPSILON ) |
| { |
| li = LONG_MIN; |
| } |
| else if( f > static_cast< double >( LONG_MAX ) - TC_FLT_EPSILON ) |
| { |
| li = LONG_MAX; |
| } |
| else |
| { |
| TCT_FloatToUnit( f, &li, this->units_ ); |
| } |
| return( li ); |
| } |
| |
| //===========================================================================// |
| // Method : SnapToGrid |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| double TC_MinGrid_c::SnapToGrid( |
| double f ) const |
| { |
| int i = this->FloatToInt( f ); |
| |
| double fdelta = 0.0; |
| if(( i == INT_MIN ) || ( i == INT_MAX )) |
| { |
| double fmin = static_cast< double >( INT_MIN ); |
| double fmax = static_cast< double >( INT_MAX ); |
| if( TCTF_IsGT( f, fmin ) && TCTF_IsLT( f, fmax )) |
| { |
| fdelta = floor( f ); |
| i = this->FloatToInt( f - fdelta ); |
| } |
| } |
| |
| double fprime = 0.0; |
| if( i == INT_MIN ) |
| { |
| fprime = static_cast< double >( INT_MIN ); |
| } |
| else if( i == INT_MAX ) |
| { |
| fprime = static_cast< double >( INT_MAX ); |
| } |
| else |
| { |
| fprime = this->IntToFloat( i ) + fdelta; |
| } |
| return( fprime ); |
| } |
| |
| //===========================================================================// |
| // Method : SnapToGridCeil |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| double TC_MinGrid_c::SnapToGridCeil( |
| double f ) const |
| { |
| int i = static_cast< int >( ceil( f / this->grid_ - TC_FLT_EPSILON )); |
| |
| return( static_cast< double >( i ) * this->grid_ ); |
| } |
| |
| //===========================================================================// |
| // Method : IsOnGrid |
| // Author : Jeff Rudolph |
| //---------------------------------------------------------------------------// |
| // Version history |
| // 05/30/12 jeffr : Original |
| //===========================================================================// |
| bool TC_MinGrid_c::IsOnGrid( |
| double f, |
| double* pf ) const |
| { |
| double fprime = this->SnapToGrid( f ); |
| |
| if( pf ) |
| { |
| *pf = fprime; |
| } |
| return( fabs( f - fprime ) < TC_FLT_EPSILON ? true : false ); |
| } |