kramann.info
© Guido Kramann

Login: Passwort:










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"