![]() |
Funktion wird nicht gezeichnet
Meine Aufgabe ist es ein Programm zu schreiben, das eine Funktion fünften Grades mit änderbaren Koordinaten zeichnet.
Die relevanten Quelltexte lauten wie folgt:
Delphi-Quellcode:
Sobald ich fixe Werte in die jeweiligen Editfelder eingebe und den Graphen zeichnen lassen möchte, ist lediglich für einen minimalen Zeitraum ein Strich an der Funktion x=1 zu sehen. Die procedure des Timers habe ich (angepasst) aus meinem Schulbuch abgeschrieben, ich denke, dass da der Fehler liegt.
var
Form1: TForm1; x1, x2, x3, x4, x5, x, y: real; x0, y0, xEins, yEins, xB, yB: integer; procedure TForm1.Button1Click(Sender: TObject); begin if edit1.text='' then x1:=0 else x1:=strtofloat(edit1.text); if edit2.text='' then x1:=0 else x2:=strtofloat(edit2.text); if edit3.text='' then x3:=0 else x3:=strtofloat(edit3.text); if edit4.text='' then x4:=0 else x4:=strtofloat(edit4.text); if edit5.text='' then x5:=0 else x5:=strtofloat(edit5.text); with image1.canvas do begin pen.color:=clwhite; canvas.rectangle(-1,-1,2*x0+1,2*y0+1); pen.color:=clblack; moveto(x0,0); lineto(x0,2*y0); moveto(0,y0); lineto(2*x0,y0); moveto(x0+xeins,y0-5); lineto(x0+xEins,y0+6); moveto(x0-5,y0-yEins); lineto(x0+6,y0-yEins); xB:=0; timer1.enabled:=true; end; end; procedure TForm1.Timer1Timer(Sender: TObject); begin if xB <2*x0 then timer1.enabled:=false; exit; x:=(xb-x0)/(xEins-x0); y:=x1*x*x*x*x+x2*x*x*x+x3*x*x+x4*x+x5; yB:= Round(y*(YEins-y0)+y0); if xB=0 then Image1.canvas.MoveTo(xB,yB) else Image1.canvas.lineto(xB,yB); xB:=xB+1; end; Anmerkung: Ich weiß, dass das Programm abstürzt, wenn keine Zahlen eingegeben werden, aber darum kümmere ich mich, wenn der Rest funktioniert. |
Re: Funktion wird nicht gezeichnet
Liste der Anhänge anzeigen (Anzahl: 1)
irgendwie haut das ganze net wirklich hin: was ist x0? diese variable wird nirgends belegt, ist also 0, sprich du zeichnest ein rechteck von -1 bis 0?
Hier mal Code aus meinem Plotter:
Delphi-Quellcode:
dies ist code aus meinem Funktionsplotter!
function Graph2D : ErrorCode;
var ImageHeight : integer; ImageLength : integer; YAchse : integer; XAchse : integer; XGitterabstand : extended; YGitterabstand : extended; u : integer; x : extended; xmin,xmax,ymin,ymax : extended; begin xmin := Graph_xmin; xmax := Graph_xmax; ymin := Graph_ymin; ymax := Graph_ymax; ImageLength := graph_image_2D.Width; ImageHeight := graph_image_2D.Height; // Berechen der y_Achse und X_Achse YAchse := Round(ImageLength - ImageLength / abs(xmax - xmin) * xmax) ; XAchse := Round(ImageHeight + ImageHeight / abs(ymax - ymin) * ymin) ; XGitterabstand := ImageLength / abs(xmax - xmin); YGitterabstand := ImageHeight / abs(ymax - ymin); // Gitterabstände anpassen if XGitterabstand < 25 then XGitterabstand := 25; if XGitterabstand > 250 then XGitterabstand := 250; if YGitterabstand < 20 then YGitterabstand := 20; if YGitterabstand > 150 then YGitterabstand := 150; with graph_image_2D.canvas do begin brush.color := clwhite; rectangle(0,0,ImageLength + 1,ImageHeight + 1); // Gitternetz zeichnen pen.Color := $00E0E0E0; pen.width := 1; u := 1; repeat moveto(YAchse - round(u * XGitterabstand),0); lineto(YAchse - round(u * XGitterabstand),ImageHeight); inc(u); until YAchse - round(u * XGitterabstand) < 0; u := 1; repeat moveto(YAchse + round(u * XGitterabstand),0); lineto(YAchse + round(u * XGitterabstand),ImageHeight); inc(u); until YAchse + round(u * XGitterabstand) > ImageLength; u := 1; repeat moveto(0,XAchse - round(u * YGitterabstand)); lineto(ImageLength,XAchse - round(u * YGitterabstand)); inc(u); until XAchse - round(u * YGitterabstand) < 0; u := 1; repeat moveto(0,XAchse + round(u * YGitterabstand)); lineto(ImageLength,XAchse + round(u * YGitterabstand)); inc(u); until XAchse + round(u * YGitterabstand) > ImageHeight; pen.Color := clblack; // Striche für Zahlen zeichnen u := 1; repeat moveto(YAchse - round(u * XGitterabstand),XAchse - 5); lineto(YAchse - round(u * XGitterabstand),XAchse + 5); inc(u); until YAchse - round(u * XGitterabstand) < 0; u := 1; repeat moveto(YAchse + round(u * XGitterabstand),XAchse - 5); lineto(YAchse + round(u * XGitterabstand),XAchse + 5); inc(u); until YAchse + round(u * XGitterabstand) > ImageLength; u := 1; repeat moveto(YAchse - 5,XAchse - round(u * YGitterabstand)); lineto(YAchse + 5,XAchse - round(u * YGitterabstand)); inc(u); until XAchse - round(u * YGitterabstand) < 0; u := 1; repeat moveto(YAchse - 5,XAchse + round(u * YGitterabstand)); lineto(YAchse + 5,XAchse + round(u * YGitterabstand)); inc(u); until XAchse + round(u * YGitterabstand) > ImageHeight; // X-Achse + Y-Achse zeichnen pen.Color := clblack; pen.Width := 2; moveto(0,XAchse); lineto(ImageLength + 1,XAchse); moveto(YAchse,0); lineto(YAchse,ImageHeight + 1); brush.Color := clblack; polygon([point(YAchse - 4,12),point(YAchse + 4,12),point(YAchse,0),point(YAchse - 4,12)]); polygon([point(ImageLength - 12,XAchse - 4),point(ImageLength - 12,XAchse + 4),point(ImageLength,XAchse),point(ImageLength - 12,XAchse - 4)]); // Beschriftung font.Height := 10; font.Color := clblack; brush.Color := clwhite; font.Name := 'MS Sans Serif'; u := 1; repeat if XGitterabstand = 25 then textout(YAchse - round(u * XGitterabstand) + 4,XAchse + 10, floattostr(round(x_wert(xmin,xmax,YAchse - u * XGitterabstand,ImageHeight,ImageLength)))) else if XGitterabstand = 250 then textout(YAchse - round(u * XGitterabstand) + 4,XAchse + 10, floattostr(roundto(x_wert(xmin,xmax,YAchse - u * XGitterabstand,ImageHeight,ImageLength),-3))) else textout(YAchse - round(u * XGitterabstand) + 4,XAchse + 10, floattostr(- u)); inc(u); until YAchse - round(u * XGitterabstand) < 0; u := 1; repeat if XGitterabstand = 25 then textout(YAchse + round(u * XGitterabstand) + 4,XAchse + 10, floattostr(round(x_wert(xmin,xmax,YAchse + u * XGitterabstand,ImageHeight,ImageLength)))) else if XGitterabstand = 250 then textout(YAchse + round(u * XGitterabstand) + 4,XAchse + 10, floattostr(roundto(x_wert(xmin,xmax,YAchse + u * XGitterabstand,ImageHeight,ImageLength),-3))) else textout(YAchse + round(u * XGitterabstand) + 4,XAchse + 10, floattostr( u)); inc(u); until YAchse + round(u * XGitterabstand) > ImageLength; u := 1; repeat if YGitterabstand = 20 then textout(YAchse - 17,XAchse - round(u * YGitterabstand) - 15, floattostr(round(y_wert(ymin,ymax,XAchse - round(u * YGitterabstand),ImageHeight,ImageLength)))) else if YGitterabstand = 150 then textout(YAchse - 17,XAchse - round(u * YGitterabstand) - 15, floattostr(roundto(y_wert(ymin,ymax,XAchse - round(u * YGitterabstand),ImageHeight,ImageLength),-3))) else textout(YAchse - 17,XAchse - round(u * YGitterabstand) - 15, floattostr( u)); inc(u); until XAchse - round(u * YGitterabstand) < 0; u := 1; repeat if YGitterabstand = 20 then textout(YAchse - 17,XAchse + round(u * YGitterabstand) - 15, floattostr(round(y_wert(ymin,ymax,XAchse + round(u * YGitterabstand),ImageHeight,ImageLength)))) else if YGitterabstand = 150 then textout(YAchse - 17,XAchse + round(u * YGitterabstand) - 15, floattostr(roundto(y_wert(ymin,ymax,XAchse + round(u * YGitterabstand),ImageHeight,ImageLength),-3))) else textout(YAchse - 17,XAchse + round(u * YGitterabstand) - 15, floattostr(- u)); inc(u); until XAchse + round(u * YGitterabstand) > ImageHeight; end; end; function Tfrm2D.Graph2D_Funktion(Funktion : string ;Farbe : TColor; Breite : integer; ClearGraph : boolean): ErrorCode ; var ImageHeight : integer; ImageLength : integer; YAchse : integer; XAchse : integer; tmp_x : extended; u : integer; x, y : extended; Variable : char; xmin,xmax,ymin,ymax : extended; begin xmin := Graph_xmin; xmax := Graph_xmax; ymin := Graph_ymin; ymax := Graph_ymax; Variable := Funktionsvariable; Funktion := SyntaxPruefung(Funktion,Variable); ImageLength := graph_image_2D.Width; ImageHeight := graph_image_2D.Height; // Berechen der y_Achse und X_Achse YAchse := Round(ImageLength - ImageLength / abs(xmax - xmin) * xmax) ; XAchse := Round(ImageHeight + ImageHeight / abs(ymax - ymin) * ymin) ; if ClearGraph then Graph2D(); graph_image_2D.Canvas.Pen.Color := Farbe; graph_image_2D.Canvas.Pen.Width := Breite; tmp_x := abs(xmax - xmin) / ImageLength; x := xmin - tmp_x ; if Funktion = '' then exit; y := EF32_Funktionswert(Funktion,Variable,x); graph_image_2D.Canvas.MoveTo(x_pixel(xmin,xmax,x,ImageHeight,ImageLength),y_Pixel(ymin,ymax,y,ImageHeight,ImageLength)); x := xmin; for u := - 1 to ImageLength do begin y := EF32_Funktionswert(Funktion,Variable,x); graph_image_2D.Canvas.LineTo(x_pixel(xmin,xmax,x,ImageHeight,ImageLength),y_Pixel(ymin,ymax,y,ImageHeight,ImageLength)); x := x + tmp_x; end; end; der Plotter hängt auch mit an! |
Re: Funktion wird nicht gezeichnet
Die Variablen x0 und y0 werden im Formcreate festgelegt, das ich nicht eingefügt hatte. x0 und y0 sind die Koordinaten des Ursprungs.
|
Re: Funktion wird nicht gezeichnet
Zitat:
also da ich vermute, dass deine Bedingung NIE erfüllt wird nie etwas gezeichnet d.h. ich geh jetzt mal davon aus dass x0 und y0 jeweils die hälfte vom bildbreite bzw höhe sind, und beim buttonklick xb:=0 steht wird der timer immer wieder deaktiviert d.h. if 0 <2*(image1.width) then was im Normallfall ja so sein wird. deswegen geschieht auch nichts. btw wäre es nicht auch sinnvoll in der IF-Abfrage ein Begin und End zu nutzen, da sonst Exit immer ausgeführt wird und somit das eigentliche Zeichnen vernachlässigt wird? Das solltest du ggf. nochmal überdenken :) Hoffe das hilft dir etwas. MfG blink182 |
Re: Funktion wird nicht gezeichnet
ich würds dann so machen:
Delphi-Quellcode:
PS. Bitte gewöhn dir doch gleich an Aussagekräftigere Variablennamen zu wählen, und ggf. an wichtigen Stellen auch Kommentare einzufügen. Das wird dir später deine Fehlersuche, sowie anderen das Lesen und Verstehen erheblich vereinfachen!
procedure Zeichne_Graph;
begin for i := 0 to (2 * x0) do begin x:=(xb-x0)/(xEins-x0); y:=x1*x*x*x*x+x2*x*x*x+x3*x*x+x4*x+x5; yB:= Round(y*(YEins-y0)+y0); if xB=0 then Image1.canvas.MoveTo(xB,yB) else Image1.canvas.lineto(xB,yB); xB:=xB+1; end; end; hier mal ein bissl besser Formatiert:
Delphi-Quellcode:
Bitte gib doch deinen Variablen xB , xEins, x1, yEins, yB, x2, x3, x4, x5 mal aussagekräftige Namen. Habs dir ja mal mit x0 uny y0 sowie x, und y vorgemacht.
procedure Zeichne_Graph;
begin for i := 0 to (2 * xKoordinatenursprung) do begin xWert := (xb - xKoordinatenursprung) / (xEins - xKoordinatenursprung); yWert := x1*x*x*x*x+x2*x*x*x+x3*x*x+x4*x+x5; yB := Round( yWert * (YEins - yKoordinatenursprung) + yKoordinatenursprung); if xB = 0 then Image1.canvas.MoveTo(xB,yB) else Image1.canvas.lineto(xB,yB); inc(xB); //ist dasselbe wie xB := xB + 1; und viel schneller... end; end; EDIT: vielleicht überarbeitest du ja deinen Quellcode mal dahingehend, und stellst dann hier deinen komplette code mal rein, ich denke dann würde es auch einfacher fallen den Fehler zu finden... Bis dahin! |
Re: Funktion wird nicht gezeichnet
Beim Überarbeiten könntest du gleich deinen Quellcode formatieren, dann würde ich mich auch bemühen, deinen Quellcode zu verstehen.
edit: und was ist x0?? |
Re: Funktion wird nicht gezeichnet
Hallo,
das Zeichnen muss in OnPaint erfolgen. Nach erfolgreicher Eingabe aller Zahlen rufst du deshalb Invalidate (das ist ein Form-Methoden) auf. Heiko |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:14 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz