Autor |
Beitrag |
wayne123
      
Beiträge: 52
|
Verfasst: Mo 17.01.11 20:39
Ok, jetzt weiß ich, wie man Potenzen in Delphi macht, aber noch bin ich mit den Parabeln nicht so weit. Jetzt will ich erstmal nur mit ^2 rechnen, hab da aber trotzdem ein Problem. Wenn ich negative Werte eingebe, kommt überhaupt keine Parabel und manchmal ist MoveTo an der falschen Stelle. Ich hab mit der Formel a*(x-d)^2+e gerechnet, gibt es da eig. eine bessere Formel für Parabeln?
Ich hoffe mal das funktioniert
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:
| unit Unit2Parabeln;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Math;
type TForm1 = class(TForm) Label1: TLabel; Edit1: TEdit; Label2: TLabel; Label3: TLabel; Label4: TLabel; Edit2: TEdit; Edit3: TEdit; Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var x,y: integer; a,d,e: extended; begin Canvas.MoveTo(0,Clientheight div 2); Canvas.LineTo(Clientwidth,Clientheight div 2); Canvas.MoveTo(Clientwidth div 2,0); Canvas.LineTo(Clientwidth div 2,Clientheight);
a:= StrToFloat(Edit1.Text); d:= StrToFloat(Edit2.Text); e:= StrToFloat(Edit3.Text); Canvas.MoveTo(0,round(-a*(0-d)*(0-d)-e)); for x:=0 to Clientheight do begin y:= round(-a*((x-d)*(x-d))-e); Canvas.LineTo(x+Clientwidth div 2,y+ Clientheight div 2) end; end; end. | Moderiert von Martok: Topic aus Sonstiges (Delphi) verschoben am Mo 17.01.2011 um 21:32
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Mo 17.01.11 21:05
Du hast da einen kleinen Fehler gemacht:
Die x-Werte fangen erst bei 0 an: Wenn Du schreibst:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure TForm1.Button1Click(Sender: TObject); var x, y: integer; a, d, e: extended; begin Canvas.MoveTo(0, Clientheight div 2); Canvas.LineTo(Clientwidth, Clientheight div 2); Canvas.MoveTo(Clientwidth div 2, 0); Canvas.LineTo(Clientwidth div 2, Clientheight);
a := StrToFloat(Edit1.Text); d := StrToFloat(Edit2.Text); e := StrToFloat(Edit3.Text);
for x := -ClientWidth div 2 to ClientWidth div 2 do begin y := round(-a * ((x - d) * (x - d)) - e); if x = -ClientWidth div 2 then Canvas.MoveTo(0,y + ClientHeight div 2) else Canvas.LineTo(x + Clientwidth div 2, y + Clientheight div 2) end; end; |
dann geht das! Ich habe auch die Startposition gleich mit in die Schleife genommen. Ist sicher nicht unbedingt notwendig, aber Du brauchst dann y nur einmal zu berechnen.
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
wayne123 
      
Beiträge: 52
|
Verfasst: Mo 17.01.11 21:13
ahh, danke, dass hatte ich auch schon bei den Geraden verpennt. Und wenn ich jetzt mit Power oder exp noch eine veränderbare Hochzahl reinbringen möchte, müsste ich da viel ändern? Wenn ja, dann würd ich nämlich lieber mit einem neuem Projekt anfangen und dann irgendwie so ne Formel, wie: y=a*x^f+b*x^g+c. Aber das dürfte ja viel komplizierter werden.
Wie y nur einmal berechnen? Sieht für mich komplizierter aus, würde sich denn da irgendein Vorteil ergeben, für den es sich lohnen würde, das eher so zu machen, weil ich ja gerade es endlich so geschafft habe.
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: Di 18.01.11 09:12
Am Besten, Du gehst wie folgt vor:
Du schreibst eine Funktion, in der Du die zu plottende Funktion schreibst. Dann ist das einfacher zu verwalten.
Außerdem habe ich zwei Funktionen definiert Transform und Retransform. Mit Transform wandelst Du einen Wert in eine Position im Plot um und mit Retransform umgekehrt eine Plotposition in einen Wert.
Was soll das? Nun, ganz einfach, wenn Du a) nicht den ganzen Formularbereich (Canvas) übermalen willst, musst Du den Plot eingrenzen. Das ist noch klar. Aber was ist, wenn Du Grafiken zeichnen willst, die schnell große y-Werte annehmen (y = x^7 z.B.). Dann müsstest Du jedesmal das Programm kompilieren, um den Graph dann zu zeichnen. So könntest Du einfach zusätzliche Editfelder einfügen, in denen Du die Min- und Max-Werte der Koordinatenachsen eingibst und dann die Funktion neu zeichnest, ohne gleich das Programm zu kompilieren.
Außerdem habe ich Dir hier noch ein kleines Beispiel gezeigt, was man mit Delphi so alles treiben kann: überladene Funktionen z.B.
Wenn Du Funktionen mit vorher nicht bekannten Anzahlen von Parametern, z.B.
y = ax^4 + bx^3 + cx^2 + dx + e zeichen willst und gleichzeitig nur ax^2 + bx + c, dann lohnt es sich, darüber nachzudenken:
yWert wäre im Fall 1: yWert := f(x, [a,b,c,d,e], [4,3,2,1,0]) und im zweiten Fall yWert := f(x, [a,b,c], [2,1,0])
Du benötigst dann nicht mehr eine Neukompilierung, wenn Du eine kompliziertere oder weniger komplizierte Funktion wählst. Du solltest aber in jedem Fall beiden Arrays gleich viele Parameter zuordnen.
Wegen der möglichen fehlenden Wertebereiche (-1^0,5 ist im Zahlenraum der einfachen Zahlen nicht definiert) bei negativen x-Werten für die Funktion Power(x,n) habe ich mich auf Intpower beschränkt, weil diese Funktion keinen eingeschränkten Wertebereich hat.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113:
| unit GraphUnit;
interface
uses Math, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
var nf : extended = 4.0; ng : extended = 1.5; type TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
function Transform(Value, Vmin, Vmax : extended; MinPos, MaxPos : integer) : integer; function Retransform(Value : integer; Vmin, Vmax : extended; MinPos, MaxPos : integer) : extended;
function f(x, a, b, c : extended) : extended; overload; function f(x : extended; a : array of extended; n : array of integer) : extended; overload;
implementation
{$R *.DFM}
function f(x : extended; a : array of extended; n : array of integer) : extended; var w : extended; i : integer; begin w := 0.0; for i := 0 to high(a) do begin w := w + a[i]*IntPower(x,n[i]); end; Result := w; end;
function f(x, a, b, c : extended) : extended;
begin Result := a * intPower(x, 3) + b * intPower(x, 2) + c; end;
function Transform(Value, Vmin, Vmax : extended; MinPos, MaxPos : integer) : integer; begin Result := round((Value - Vmin)/(Vmax - Vmin)*(MaxPos - MinPos))+MinPos; end;
function Retransform(Value : integer; Vmin, Vmax : extended; MinPos, MaxPos : integer) : extended; begin
Result := ((Value - MinPos)/(MaxPos - MinPos)*(Vmax - Vmin))+Vmin;; end;
procedure TForm1.Button1Click(Sender: TObject); var x, y: integer; xW, yW, a, d, e: extended; xMinPos, xMaxPos, yMinPos, yMaxPos : integer; const ymin : extended = -60.0; ymax : extended = 60.0; xmin : extended = -4.0; xmax : extended = 4.0; begin xMinPos := ClientWidth div 8; yMinPos := ClientHeight - ClientHeight div 5; xMaxPos := ClientWidth - ClientWidth div 8; yMaxPos := 0; a := StrToFloat(Edit1.Text); d := StrToFloat(Edit2.Text); e := StrToFloat(Edit3.Text);
for x := xMinPos to xMaxPos do begin xW := RetransForm(x, xmin, xmax, xMinPos, xMaxPos); yW := f(xW, [a, d, e, 4.0], [3, 2, 1, 0]); y := Transform(yW, ymin, ymax, yMinPos, yMaxPos);
if x = xMinPos then Canvas.MoveTo(x,y) else Canvas.LineTo(x,y); end; y := Transform(0.0, ymin, ymax, yMinPos, yMaxPos); x := Transform(0.0, xmin, xmax, xMinPos, xMaxPos); Canvas.MoveTo(xMinPos, y); Canvas.LineTo(xMaxPos, y); Canvas.MoveTo(x, yMinPos); Canvas.LineTo(x, yMaxPos); end;
end. |
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
|
|
wayne123 
      
Beiträge: 52
|
Verfasst: Di 18.01.11 16:14
Kannst du mir das irgendwie als Datei geben, damit ich mir das angucken kann? Ich werds nicht einfach so benutzen, sondern will mir das wirklich angucken, damit ich das verstehe, weil so versteh ich das noch nicht ganz.
|
|
|