00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef HAVE_CONFIG_H
00026 # include <simgear_config.h>
00027 #endif
00028
00029 #include <simgear/compiler.h>
00030
00031 #include <string>
00032
00033 #include <simgear/debug/logstream.hxx>
00034 #include <simgear/misc/sgstream.hxx>
00035 #include <simgear/props/props.hxx>
00036
00037 #include "interpolater.hxx"
00038
00039 #include <simgear/math/SGMath.hxx>
00040
00041 using std::string;
00042
00043
00044 SGInterpTable::SGInterpTable()
00045 {
00046 }
00047
00048 SGInterpTable::SGInterpTable(const SGPropertyNode* interpolation)
00049 {
00050 if (!interpolation)
00051 return;
00052 std::vector<SGPropertyNode_ptr> entries = interpolation->getChildren("entry");
00053 for (unsigned i = 0; i < entries.size(); ++i)
00054 addEntry(entries[i]->getDoubleValue("ind", 0.0),
00055 entries[i]->getDoubleValue("dep", 0.0));
00056 }
00057
00058
00059
00060 SGInterpTable::SGInterpTable( const string& file )
00061 {
00062 SG_LOG( SG_MATH, SG_INFO, "Initializing Interpolator for " << file );
00063
00064 sg_gzifstream in( file );
00065 if ( !in.is_open() ) {
00066 SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
00067 return;
00068 }
00069
00070 in >> skipcomment;
00071 while ( in ) {
00072 double ind, dep;
00073 in >> ind >> dep;
00074 in >> skipws;
00075 _table[ind] = dep;
00076 }
00077 }
00078
00079
00080
00081 void SGInterpTable::addEntry (double ind, double dep)
00082 {
00083 _table[ind] = dep;
00084 }
00085
00086
00087 double SGInterpTable::interpolate(double x) const
00088 {
00089
00090 if (_table.empty())
00091 return 0;
00092
00093
00094 Table::const_iterator upBoundIt = _table.upper_bound(x);
00095
00096
00097 if (upBoundIt == _table.end())
00098 return _table.rbegin()->second;
00099
00100
00101
00102 if (upBoundIt == _table.begin())
00103 return upBoundIt->second;
00104
00105
00106 Table::const_iterator loBoundIt = upBoundIt;
00107 --loBoundIt;
00108
00109
00110 double loBound = loBoundIt->first;
00111 double upBound = upBoundIt->first;
00112 double loVal = loBoundIt->second;
00113 double upVal = upBoundIt->second;
00114
00115
00116
00117
00118 return loVal + (upVal - loVal)*(x - loBound)/(upBound - loBound);
00119 }
00120
00121
00122
00123 SGInterpTable::~SGInterpTable() {
00124 }
00125
00126