8.1 Lineare Interpolation
Nach Start des folgenden Programms kann der Benutzer Spannungen U eingeben und erhält den zugehörigen Abstand.
Das ganze funktioniert so, dass für die eingegebene Spannung u geschaut wird, zwischen welchen beiden Messwerten u1 und u2 sie liegt. Dann wird mit Hilfe des Dreisatzes der zugehörige Abstand s bestimmt. Wenn s1 und s2 die u1 und u2 zugehörigen Entfernungen sind, dann gilt unter der Annahme, dass die Kurve durch (u1,s1) und (u2,s2) linear verläuft, also eine Gerade ist:
(s2-s1)/(u2-u1) = (s-s1)/(u-u1)
Damit erhält man für s:
s = (s2-s1)*(u-u1)/(u2-u1) + s1
Es werden mit diesem Ansatz aber nicht Fälle abgedeckt, bei denen u kleiner als das kleinste gemessene, oder größer als das größte gemessene ist. Bei diesen Fällen gibt das folgende Programm einen Hinweis an den Benutzer:
#include <iostream>
#include <fstream>
#include <vector>
#include "vektordef.h"
#include "lesen.h"
using namespace std;
double interpoliereX(double y, Doublevektor paare)
{
double x,x1,x2,y1,y2;
int index = 1;
for(int i=1;i<paare.size()-2;i+=2)
{
if(y>=paare.at(i) && y<=paare.at(i+2) ||
y<=paare.at(i) && y>=paare.at(i+2) )
{
index = i;
break;
}
}
//(y2-y1)/(x2-x1) == (y-y1)/(x-x1)
x1 = paare.at(index-1);
y1 = paare.at(index);
x2 = paare.at(index+1);
y2 = paare.at(index+2);
x = (y-y1)*(x2-x1)/(y2-y1) + x1;
return x;
}
int main(void)
{
Doublevektor messungen = lesen("daten.txt");
double u;
double umin = messungen.at(1);
double umax = messungen.at(1);
for(int i=1;i<messungen.size()-1;i+=2)
if(messungen.at(i)<umin)
umin = messungen.at(i);
for(int i=1;i<messungen.size()-1;i+=2)
if(messungen.at(i)<umin)
umin = messungen.at(i);
while(true)
{
cout<<"Geben Sie eine Spannung U an:"<<endl<<"U=";
cin>>u;
if(u>=umin && u<=umax)
{
cout<<"Der zugehoerige interpolierte Abstand betraegt:"<<endl;
cout<<"s="<<interpoliereX(u,messungen)<<"mm."<<endl;
}
else
{
cout<<endl<<"U liegt ausserhalb des interpolierbaren Bereichs"<<endl;
}
}
return 0;
}
Code 8.1-1: C++ Programm "linear.cpp"
Um einen Double-Vektor (und andere) verwenden zu können, wurde noch folgende Include-Datei "vektordef.h" geschrieben:
using namespace std; typedef vector<int> Intvektor; typedef vector<double> Doublevektor; typedef vector<string> Stringvektor;
Code 8.1-2: Header-Datei "vektordef.h"
Der Ladevorgang der Daten erfolgt mit der Funktion lesen(..) in "lesen.h":
Doublevektor lesen(string filename)
{
Doublevektor zahlen;
char zeichenkette[200];
ifstream einlesen(filename.data());
if(einlesen)
{
ifstream einlesen(filename.data());
while(einlesen >> zeichenkette)
zahlen.push_back(atof(zeichenkette));
einlesen.close();
}
return zahlen;
}
Code 8.1-3: Header-Datei "lesen.h"
Programm linear, .cpp, .h und .exe - Dateien gepackt