X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fmath%2Finterpolater.cxx;h=1bbbadc801d2a427ccd91cb8ac66cb3ef18d7f6e;hb=7a52c2fa71355631a559d74e0860fa6c5efa424e;hp=206e99a723e5e5c839782e820dd6060e87eb5657;hpb=75911b6c643d8e5597565bc63c34bdc2009a037a;p=simgear.git diff --git a/simgear/math/interpolater.cxx b/simgear/math/interpolater.cxx index 206e99a7..1bbbadc8 100644 --- a/simgear/math/interpolater.cxx +++ b/simgear/math/interpolater.cxx @@ -4,7 +4,7 @@ // // Written by Curtis Olson, started April 1998. // -// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu +// Copyright (C) 1998 Curtis L. Olson - http://www.flightgear.org/~curt // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -16,92 +16,106 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // $Id$ +#ifdef HAVE_CONFIG_H +# include +#endif #include -#include // for exit() +#include -#include STL_STRING - -// depricated - #include #include -#include +#include +#include #include "interpolater.hxx" -SG_USING_STD(string); +#include + +using std::string; +// Constructor -- starts with an empty table. +SGInterpTable::SGInterpTable() +{ +} + +SGInterpTable::SGInterpTable(const SGPropertyNode* interpolation) +{ + if (!interpolation) + return; + std::vector entries = interpolation->getChildren("entry"); + for (unsigned i = 0; i < entries.size(); ++i) + addEntry(entries[i]->getDoubleValue("ind", 0.0), + entries[i]->getDoubleValue("dep", 0.0)); +} // Constructor -- loads the interpolation table from the specified // file -SGInterpTable::SGInterpTable( const string& file ) { +SGInterpTable::SGInterpTable( const string& file ) +{ SG_LOG( SG_MATH, SG_INFO, "Initializing Interpolator for " << file ); - fg_gzifstream in( file ); + sg_gzifstream in( file ); if ( !in.is_open() ) { SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file ); - exit(-1); + return; } - size = 0; in >> skipcomment; while ( in ) { - if ( size < MAX_TABLE_SIZE ) { - in >> table[size][0] >> table[size][1]; - in >> skipws; - size++; - } else { - SG_LOG( SG_MATH, SG_ALERT, - "fgInterpolateInit(): Exceed max table size = " - << MAX_TABLE_SIZE ); - exit(-1); - } + double ind, dep; + in >> ind >> dep; + in >> skipws; + _table[ind] = dep; } } -// Given an x value, linearly interpolate the y value from the table -double SGInterpTable::interpolate(double x) { - int i; - double y; - - i = 0; - - while ( (x > table[i][0]) && (i < size) ) { - // cout << " i = " << i << " table[i][0] = " << table[i][0] << endl; - // cout << " size = " << size << endl; - i++; - } - - // printf ("i = %d ", i); - - if ( (i == 0) && (x < table[0][0]) ) { - SG_LOG( SG_MATH, SG_DEBUG, - "interpolate(): lookup error, x to small = " << x ); - return table[0][1]; - } - - // cout << " table[size-1][0] = " << table[size-1][0] << endl; - if ( x > table[size-1][0] ) { - SG_LOG( SG_MATH, SG_DEBUG, - "interpolate(): lookup error, x to big = " << x ); - return table[size-1][1]; - } - - // y = y1 + (y0 - y1)(x - x1) / (x0 - x1) - y = table[i][1] + - ( (table[i-1][1] - table[i][1]) * - (x - table[i][0]) ) / - (table[i-1][0] - table[i][0]); +// Add an entry to the table. +void SGInterpTable::addEntry (double ind, double dep) +{ + _table[ind] = dep; +} - return(y); +// Given an x value, linearly interpolate the y value from the table +double SGInterpTable::interpolate(double x) const +{ + // Empty table?? + if (_table.empty()) + return 0; + + // Find the table bounds for the requested input. + Table::const_iterator upBoundIt = _table.upper_bound(x); + // points to a value outside the map. That is we are out of range. + // use the last entry + if (upBoundIt == _table.end()) + return _table.rbegin()->second; + + // points to the first key must be lower + // use the first entry + if (upBoundIt == _table.begin()) + return upBoundIt->second; + + // we know that we do not stand at the beginning, so it is safe to do so + Table::const_iterator loBoundIt = upBoundIt; + --loBoundIt; + + // Just do linear interpolation. + double loBound = loBoundIt->first; + double upBound = upBoundIt->first; + double loVal = loBoundIt->second; + double upVal = upBoundIt->second; + + // division by zero should not happen since the std::map + // has sorted out duplicate entries before. Also since we have a + // map, we know that we get different first values for different iterators + return loVal + (upVal - loVal)*(x - loBound)/(upBound - loBound); }