Autor Beitrag
Jann1k
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 866
Erhaltene Danke: 43

Win 7
TurboDelphi, Visual Studio 2010
BeitragVerfasst: So 07.01.07 18:17 
Für meinen Spaceshooter wollte ich jetzt die Flugbahn von Geschossen und Gegnern nicht länger durch einfaches Subtrahieren bzw. Addieren von Integerwerten steuern, sondern durch Funktionen.

Ich stelle mir das Vefahren so vor, dass jeder Gegner abhängig von seiner Geschwindigkeit um ein paar Pixel auf dem Bildschirm verschoben wird, seine Position auf der X-Achse liefert mir den X-Wert, den ich in die jeweilige Funktion einsetzen will, damit diese mir als Ergebnis die Y-Koordinate des Gegners ausgibt. Die Funktionen werden dabei natürlich so gewählt, dass sie die Grenzen des Bildschirm nicht übertreten.

Mein Problem liegt genau an dieser Stelle:

"X-Wert, den ich in die Funktion einsetzen will"

Wie mach ich Delphi klar, dass er in einem String (als dieses sind die Funktionen atm gespeichert - gibt es da was besseres?) alle X (oder y, da X wohl von dem Multiplikationszeichen nicht zu unterscheiden ist) durch einen Integer ersetzt und dann den Funktionswert ausrechnet?

Die Suche hat mir nur Threads geliefert, die sich mit der Berechnung von Null- oder Extremstellen beschäftigten, dass will ich aber nicht, ich brauche "nur" das Einsetzen und Ausrechnen von Funktionswerten.

Falls das wichtig ist: Die Funktionen, die ich im Auge hab, sind ganzrationale Funktionen nicht über den 4. Grad, wenn es mit Sinus auch ginge, wäre das schön, müsste aber nicht unbedingt sein.
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: So 07.01.07 18:25 
Wenn die Funktionen zur Compile-Zeit bekannt sind, sehe ich eigentlich keinen Grund, diese als String einzubauen. Da würde ich sie als Code reinmachen, was deutlich schneller ist.

Wenn Du sie wirklich als String einbauen willst, dann such mal nach Suche in der Entwickler-Ecke MATH* PARSER.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
Jann1k Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 866
Erhaltene Danke: 43

Win 7
TurboDelphi, Visual Studio 2010
BeitragVerfasst: So 07.01.07 18:38 
Wie meinst du das als Code?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 07.01.07 18:41 
Naja, er meint sowas:
ausblenden Delphi-Quelltext
1:
2:
3:
function f(uValue: Integer): Integer;
  Result := uValue * uValue + 1;
end;

Für f(x) = x^2 + 1 ;-)
Dann kannst du ja f einfach irgendwo aufrufen.
Allesquarks
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 510

Win XP Prof
Delphi 7 E
BeitragVerfasst: So 07.01.07 18:42 
Also gut bei Geschossen klingt das logisch aber wieso bewegen sich deine Gegner auf festen Bahnen? gerade für ein Spiel sollte man vielleicht deine bisherige Methode bevorzugen, da die neue wahrscheinlich weit rechenaufwendiger ist.

Zum Funktionen ausrechnen:

Wieso benutzt du x als Multiplikationszeichen? Das "*" sollte es doch auch tuen und der Konflikt ist weg.
Dann musst du nur noch alle x durch deine Zahl ersetzen. das ist nicht so schwierig pos und insert tuen da Wunder. Dennoch ist der String wohl die langsamste Methode.

Wie schon gesagt solltest du keinen Parser verwenden wenn die Funktion vorher bekannt ist. Denn dieser soll eben gerade zur Laufzeit Funktionen analysieren.
also aus (3+x^3)^(0,5+x) machst du dann im code: meinergebnis:=exp(ln(3+xvar*xvar*xvar)*(0,5+xvar)) so ungefähr

Falls du doch einen Formelparser brauchst kannst ja mal nach meinem Taschenrechner suchen (RaFX). Wenn du die Unit Parser benutzt einfach Funktion parsetotree benutzen. Dieser parst die Funktion in einen Baum und kann diesen mit evaluate auch auswerten.
Er ist allerdings noch nicht fertig und der Variablen support ist noch nicht implementiert. Entweder fütterst du das Ding immer mit einem neuen String (langsamer) oder du gehst den Baum entlang zu der Zahl die eigentlich deine Variable sein soll und veränderst diese nach jedem Durchgang.
Für die Ausgabe machst du am besten (TZahl(meinergebnis).convertto(TExtendedzahl)).zahl das ist dann eine Extendedvariable. Das convertieren ist nötig, da der interne Typ variieren kann.
Jann1k Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 866
Erhaltene Danke: 43

Win 7
TurboDelphi, Visual Studio 2010
BeitragVerfasst: So 07.01.07 18:53 
Zitat:

Naja, er meint sowas:
Delphi-Quelltext
ausgeblendet markieren
1:
2:
3:
function f(uValue: Integer): Integer;
Result := uValue * uValue + 1;
end;



Für f(x) = x^2 + 1
Dann kannst du ja f einfach irgendwo aufrufen.


Hmm, auf die Idee bin ich gar nicht gekommen, dann bräuchte ich für jede Funktion eine function in Delphi, dann wird es wohl jetzt echt Zeit eine eigene Unit für die Gegner zu erstellen. Ich denke so werd ich es dann machen, die Sache mit dem Formelparser scheint dagegen die aufwändigere und langsamere Methode zu sein.

Naja, ich bedanke mich dann mal bei allen Beteiligten und mach mich an die Arbeit *denhutziehundverbeug*