Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Funktion wird nicht gezeichnet (https://www.delphipraxis.net/131682-funktion-wird-nicht-gezeichnet.html)

Fuchspower 28. Mär 2009 22:05


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:
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;
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.

Anmerkung: Ich weiß, dass das Programm abstürzt, wenn keine Zahlen eingegeben werden, aber darum kümmere ich mich, wenn der Rest funktioniert.

SimStar001 29. Mär 2009 14:24

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:
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;
dies ist code aus meinem Funktionsplotter!


der Plotter hängt auch mit an!

Fuchspower 29. Mär 2009 18:46

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.

blink182 29. Mär 2009 19:05

Re: Funktion wird nicht gezeichnet
 
Zitat:

Zitat von Fuchspower
Delphi-Quellcode:
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;

hi
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

SimStar001 30. Mär 2009 15:22

Re: Funktion wird nicht gezeichnet
 
ich würds dann so machen:

Delphi-Quellcode:
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;
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!


hier mal ein bissl besser Formatiert:


Delphi-Quellcode:
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;
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.


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!

Jakob Ullmann 30. Mär 2009 15:53

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??

hoika 30. Mär 2009 16:29

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 11:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz