Hat jemand von euch schon mal einen Funktionsinterpreter(User gibt eine Funktion ein und Computer zeichnet Graph) gebastelt?
Wenn ja, kann er mir mal bitte die Herangehensweise schildern? So, dass ich einen Ansatztpunkt habe.
Danke im Vorraus.
_________________ Es gibt eine Theorie, die besagt, wenn jemals irgendwer genau rausfindet, wozu das Universum da ist und warum es da ist, dann verschwindet es auf der Stelle und wird durch etwas noch Bizarreres ersetzt.
Es gibt eine andere Theorie, die besagt, dass das schon passiert ist.
Der Trick ist, daß man sich einen Parser für die Formeln schreibt, der diese so zerlegt, daß man die Variablen einsetzen und losrechnen kann. Da Parser in die Kategorie Compilerbau gehören, ist man gar nicht so dumm dran, sich dort einmal umzusehen. Man trennt also den Teil des Plotters auf, der sich mit der eingegebenen Funktion beschäftigt in einen Lexer, der die Formel in ihre niedrigen Bestandteile zerlegt: ("+","*", "/", "Zeichenkette", "(", "Variable", ecc. ) und einen Parser, der die Formel dann interpretiert, also erkennt, was wie zusammengehört (Summen binden weniger Stark als Produkte, Klammern bilden am Stärksten, etc. ) und diese Information dann z:b in "Auswertungsobjekten" ablegt. So hat man z.B: eine abstrakte Oberklasse FormelTeil, die eine Auswertfunktion beitet, in die man seine Variable(n) einsetzen kann. Dann leitet man davon Klassen für Summen, Produkte, Variablen, ecc. ab und Organisiert die Berechnung einfach rekursiv.
Ein paar der Bestandteile kannst du dir ja mal im Skriptsprachen-Tutorial 1 ansehen
http://wiki.delphigl.com/index.php/Tuto ... hen_Teil_1 . Den Lexer und den Parser der Sprache musst du halt um den ganzen Programmiersprachen-Kram erleichtert vorstellen, und statt daß das gute Stück am Ende auf Codegenerierung ausgelegt wird (Tutorial 2), müssen halt die oben beschriebenen Objekte erzeugt werden.
Wenn du es dann selbst ausprobierst, ist es sicher nicht dumm, mithilfe von EBNF oder einer ähnlichen Beschreibungssprache, eine Definition für die möglichen Formeln deines Plotters aufzustellen und wenn du bis dahin das eigentlich recht naheliegende, rekursive Prinzip vom Zusammenspiel zwischen Lexer und Parser verstanden hast, dürfte das selber Programmieren (Ohne Copy&Paste) ein leichtes werden.
Ein gutes Buch zu diesem Thema ist:
ISBN: 3-89319-931-4
Niklaus Wirth, Grundlagen und Techniken des Compilerbaus.
http://www.amazon.de/Grundlagen-Technik ... 56-9218416 Ist sicherlich in der nächsten Unibib zu haben, ggf. über Fernleihe (die machen das auch für Nichtstudenten, muss man nur hingehen.) Zu Kaufen wird man es aber wenn nur zufällig bekommen. Das Buch sit zwar für dein Vorhaben schon etwas overkill, aber die Prinzipien für einen Formelzerleger udn einen Compiler sind nunmal die selben.
Zuletzt geändert von Delphic am So Nov 12, 2006 20:34, insgesamt 1-mal geändert.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Hallo hustler1,
dazu fällt mir Folgendes ein: man braucht vermutlich einen Matheparser (ein Programm, das den Input, der ja in Form von mathematischen Formeln hereinkommt, interpretieren kann; Googlestichworth eventuell " math parser"). Das Zeichnen (Pixel plotten) kann man auf ganz verschiedene Arten erledigen, z.B. mit TCanvas in Windows, SDL kann auch zeichnen (habe ich gehört, kenn mich da aber nicht aus), in Linux bin ich leider nicht beschlagen, aber da müsste es etwas Ähliches geben. Was Opengl betrifft, denk ich da an glDrawPixels(Beschreibung siehe Wiki), um einen Funktionsgraphen zu plotten, ist aber meiner Meinung nach für diese Aufgabe etwas überdimensioniert.
Ich hoffe, das hilft Dir weiter.
Traude
@edit: Tja, Nico war schneller (und wahrscheinlich auch fundierter)
Registriert: So Sep 26, 2004 05:57 Beiträge: 190 Wohnort: Linz
Wenn es nicht sehr benutzerfreundlich sein muss kannst du auch die polnischebzw. umgekehrte polnische Notation verwenden, die lässt sich etwas leichter ausprogrammieren. Da hast du dann statt
(3 + 4) * sin( x+ 3)
stehen:
3 4 + x 3 + sin *
Löst du dann so auf:
3 auf den Zahlenstack
4 auf den Zahlenstack
+ ist ein Operator der 2 Operanden erwartet => nimm die oberen beiden Operanden vom Stack und gib das Ergebnis von 3+4 wieder auf den Zahlenstack
Wert von x auf den Stack
3 auf den Stack
+ wiederum 3 und x vom Stack nehmen, Ergebnis von x+3 auf den Stack
sin benötigt nur einen Operanden => nur einen Wert vom Stack nehmen (Ergebnis von x+3), sinus berechnen, Ergebnis wieder auf den Zahlenstack
Für das * nimmst du wiederum die beiden obersten Operanden her, und legst das Ergebnis wieder oben auf den Stack.
Nun ist die Formel zu ende, dein Ergebnis liegt nun oben auf dem Zahlenstack.
Als Trennzeichen zwischen den Operanden und Operatoren wurde hier ein Leerzeichen verwendet, also du suchst immer das Wort bis zum nächsten Leerzeichen, überprüfst ob es eine Zahl ist. Wenn es eine Zahl ist auf den Zahlenstack drauf legen. Wenn es keine Zahl ist so überprüfst du ob es ein gültiger Operator ist, wenn es ein gültiger Operator ist, dann nimmst du dir die Anzahl der Operanden die dieser Operator benötigt vom Stack (sin nur 1 Operand, +, -, *, / 2 Operanden, ...) berechnest die Funktion und gibst das Ergebnis wieder auf den Stack.
Wenn du "normale" Formeln angeben willst, so würde es das parsen auch etwas vereinfachen wenn du fixe Trennzeichen (zB Leerzeichen) verwendest. Also nicht
(3+4)*sin(x+3)
schreiben sondern
( 3 + 4 ) * sin ( x + 3 )
Geht halt auch wiederum etwas auf Kosten der Benutzerfreundlichkeit.
Ich habe mir mal für einen Taschenrechner eine dreifach verkettete Liste angelegt: Jedes Element hat einen Wert oder eine Unterkette, eventuell eine Funktion und einen Operator zum nächsten Element. Gelesen habe ich den String sequentiell immer bis zum nächsten Trennzeichen (Operator oder Klammer).
Bein Berechnen geht man wie folgt vor:
-Hat das Element eine Unterkette, wird erst diese berechnet. (Damit ergibt sich dann der Wert des Elements)
- Hat das Element eine Funktion, wird der Wert des Elements mit dieser verwurstelt.
- Sind alle Werte einer Kette berechnet, werden die Operatoren nach Ihrer Gewichtung (Punkt Vor Strich, Potenzen vor Punkt) verwurstelt (in der ganzen Kette), indem bei jedem Element, das einen entsprechend gewerteten Operator hat, sein Wert mit dem des Folgenden Elements 'operiert' wird, das folgende aus der Kette entfernt wird und der Operator des folgenden übernommen wird.
Am Ende der Geschichte hast Du genau ein Element mit dem Ergebnis.
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Danke ersteinmal an alle, die geholfen haben.
Ich werde in nächster Zeit die Vorschläge bearbeiten und versuchen umzusetzen. Ich werde ggf. bei Unklarheiten nochmal nachfragen und ein eventuelles Ergebnis posten.
_________________ Es gibt eine Theorie, die besagt, wenn jemals irgendwer genau rausfindet, wozu das Universum da ist und warum es da ist, dann verschwindet es auf der Stelle und wird durch etwas noch Bizarreres ersetzt.
Es gibt eine andere Theorie, die besagt, dass das schon passiert ist.
Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.