Stoppt die Vorratsdatenspeicherung! Jetzt klicken && handeln!Willst du auch bei der Aktion teilnehmen? Hier findest du alle relevanten Infos und Materialien:
 
Funktionsplotter
von Plapperkatze am 18.Februar 2006 um 18:12
zurück zur Kategorie "Tutorials"

Ein weiterer Leckerbissen aus der Katzenfabrik!

Grafikfähige Taschenrechner können mathemathische Funktionen darstellen. Warum also wir nicht? Der Funktionsparser stammt im Original von B.Stroustrup und wurde um ein paar kleine Funktionen erweitert bzw verändert. Die Drehknöpfe sind hier erklärt: http://katze.dead-men.de/index.php?tutorial=47

Wie sieht das nun aus?



Wie funktioniert es?
Funktion mit Variable x eingeben (exp(x) zB) und den -> Button betätigen. Skalieren mit den Drehreglern.

Wie einbinden?
Euer Quelltext ist C++ und ihr habt ein Fenster erzeugt. Nun muss in den Header ein:
#include "solverclass.cpp"
und ein
function_plotter plotter(320,240); // name (plotter) und groesse (320x240)

Nun kann eine Funktion wie f(x)=sin(x) geplottet werden:
plotter.plot_function(hWnd,c,-2,-1,2,1,.1,1);
Hier wird der Graph in einem Bereich von -2 bis +2 (X) und -1 bis +1 (Y) gezeichnet.

Der letzte Parameter ist hier 1, also wird die erste Ableitung der Funktion (die Steigung) rot gezeichnet. Bei plot_function(hWnd,c,-2,-1,2,1,.1,0), also letzter Parameter = 0 wird sie nicht dargestellt.

Der Graph ist nun in plotter.hBmp, um ihn zu zeichnen kann man folgendes verwenden:
  case WM_PAINT:
     hDC = BeginPaint(hWnd, &ps);
     hBmpDC=CreateCompatibleDC(hDC);
     SelectObject(hBmpDC,plotter.hBmp);
     BitBlt(hDC,10,10,320,240,hBmpDC,0,0,SRCCOPY);
     DeleteDC(hBmpDC);
     EndPaint(hWnd, &ps);
     break;

Und wie funktioniert es nun wirklich?

Ein Bitmap zum zeichnen, ein Edit-Feld für die Formel und 2 Buttons für die Skalierung. Und dann eben solverclass.cpp, das unsere Formel (char*) in einen Graphen verwandelt. Dort rufen wir plot_function() mit unsrer Funktion als char* auf. Der Parser wühlt sich nun nach allgemeinen Rechenregeln durch diese Funktion, und versucht Funktionswerte zu ermitteln, um diese als Graph in das Bitmap zu zeichnen.

Hier die wesentlichen Funktionen des Parsers:
   map<string,double> table;

   char my_function[MAXLENGTH];

   Token_value curr_tok;

   int no_of_errors;

   double expr(bool get,double x);
   double term(bool get,double x);
   double prim(bool get,double x);

   Token_value get_token();

   double number_value;
   string string_value;

   void del_first_letter(char *function);
   void eat_number();
   void eat_word();

Hier der Zeichenloop:
 HBRUSH hBrush;
 HPEN hPen;
 HDC hDC,hBmpDC;
 PAINTSTRUCT ps;

 double old1=0,old2=0,d1;

     hDC = BeginPaint(hWnd, &ps);
     hBmpDC=CreateCompatibleDC(hDC);
     SelectObject(hBmpDC,hBmp);

        hPen=CreatePen(PS_SOLID,1,RGB(0,0,0));
        SelectObject(hBmpDC,hPen);

        hBrush=CreateSolidBrush(RGB(255,255,255));
        SelectObject(hBmpDC,hBrush);

        Rectangle(hBmpDC,0,0,width,height);

        DeleteObject(hPen);

        hPen=CreatePen(PS_DOT,1,RGB(0,0,0));
        SelectObject(hBmpDC,hPen);

        MoveToEx(hBmpDC,0,height/2,NULL);
        LineTo(hBmpDC,width,height/2);

        MoveToEx(hBmpDC,width/2,0,NULL);
        LineTo(hBmpDC,width/2,height);

        DeleteObject(hPen);

 // maybe x1 smaller than x2!
 double hstep=width/(x2-x1);
 double vstep=height/(y2-y1);
 double y=calc_function(function,x1);

 old1=y;
 old2=y-=calc_function(function,x1-step);

 for(double x=x1+step;x<x2;x+=step)
 {
   hPen=CreatePen(PS_SOLID,1,RGB(0,0,0));
   SelectObject(hBmpDC,hPen);

   y=calc_function(function,x);
   MoveToEx(hBmpDC,(x-x1-step)*hstep,height/2-(old1)*vstep,NULL);
   LineTo(hBmpDC,(x-x1)*hstep,height/2-(y)*vstep);

   DeleteObject(hPen);

   if(mode==1)
   {
     hPen=CreatePen(PS_SOLID,1,RGB(255,0,0));
     SelectObject(hBmpDC,hPen);  
     d1=y-old1;
     MoveToEx(hBmpDC,(x-x1-step)*hstep,height/2-old2*vstep,NULL);
     LineTo(hBmpDC,(x-x1)*hstep,height/2-d1*vstep);
     DeleteObject(hPen);
     old2=d1;
   }
   old1=y;
 }

 DeleteObject(hPen);
 DeleteObject(hBrush);
 DeleteDC(hBmpDC);
 EndPaint(hWnd, &ps);

y=calc_function(function,x) entspricht y=f(x) mit f als funktion.

Der Parser kennt PI und e, ausserdem sin, cos und exp. Weitere Funktionen sind einfach zu implementieren.

Wo?

Den Sourcecode (und Exe, 44kB als .rar) gibt es hier:
http://katze.dead-men.de/upload/22_fplot.rar

gruesse, die plapperkatz

zurück zur Kategorie "Tutorials"
[0 Kommentare]

Name


Kommentar




Bitte abtippen


 
(C) 2006-20012 Plapperkatze - 215314 Besucher seit dem 23.01.2012 Login