Einzelnen Beitrag anzeigen

HTC_Magic

Registriert seit: 30. Mär 2010
Ort: Sendenhorst
3 Beiträge
 
#1

Funktionsplotter: Graph falsch herum

  Alt 30. Mär 2010, 18:32
Hallo Leute

Wir machen momentan im Infounterricht (Stufe 12)das Projekt Funktionsplotter, für Funktionen 3. Grades. Ich bin schon recht weit(genauer gesagt der der am weitesten ist im Kurs^^), und habe jetzt in den Ferien mal ein bisschen weiter gemacht. Nur habe ich momentan ein fettes Problem: Mein Graph ist immer falsch rum! Es muss sich irgendwo ein Minus eingeschlichen haben - aber ich find's nicht

Hier mal der Quelltext.
Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls,Math;

type
  TFktPlotter = class(TForm)
    ImgGraph: TImage;
    ScrA: TScrollBar;
    ScrB: TScrollBar;
    ScrC: TScrollBar;
    ScrD: TScrollBar;
    LbA: TLabel;
    LbB: TLabel;
    LbC: TLabel;
    LbD: TLabel;
    BtZeichnen: TButton;
    LbTitel: TLabel;
    BtReset: TButton;
    BtBeenden: TButton;
    PnFkt: TPanel;
    LbFunktion: TLabel;
    PnWertA: TPanel;
    PnWertB: TPanel;
    PnWertC: TPanel;
    PnWertD: TPanel;
    Button1: TButton;
    ScrDef: TScrollBar;
    Label1: TLabel;
    PnWertDef: TPanel;
    procedure BtZeichnenClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure BtBeendenClick(Sender: TObject);
    procedure ScrAChange(Sender: TObject);
    procedure ScrBChange(Sender: TObject);
    procedure ScrCChange(Sender: TObject);
    procedure ScrDChange(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ScrDefChange(Sender: TObject);
    procedure BtResetClick(Sender: TObject);

  private
    { Private declarations }
    procedure ZeichneKS;
    procedure Initialisieren;
    procedure ZeichneGraph;
    procedure BeschriftungXAchse;
    //procedure BeschriftungYAchse;
    function XPix(xP:Extended):Integer;
    function YPix(yP:Extended):Integer;
    function f(x:Extended):Extended;
  public
    { Public declarations }
  end;

var
  FktPlotter: TFktPlotter;
  a,b,c,d,def: Extended;

implementation

{$R *.dfm}

procedure TFktPlotter.BtZeichnenClick(Sender: TObject);
begin
  Initialisieren;
  ZeichneKS;
  BeschriftungXAchse;
  //BeschriftungYAchse;
  ZeichneGraph;
end;

procedure TFktPlotter.Initialisieren;
begin
  //Variablen von Scrollbar beziehen
  a:=ScrA.Position/20;
  b:=ScrB.Position/20;
  c:=ScrC.Position/20;
  d:=ScrD.Position/20;
  // Schon eingführt, aber noch deaktiviert
  //def:=ScrDef.Position;
  def:=10;

  PnWertA.Caption:=FloatToStr(a);
  PnWertB.Caption:=FloatToStr(b);
  PnWertC.Caption:=FloatToStr(c);
  PnWertD.Caption:=FloatToStr(d);
  PnWertDef.Caption:=FloatToStr(def);

  LbFunktion.Caption:='f(x)='+FloatToStr(a)+'x³+'+FloatToStr(b)+'x²+'+FloatToStr(c)+'x+'+FloatToStr(d);
end;

procedure TFktPlotter.ZeichneKS;
begin
  ImgGraph.Canvas.Rectangle(0,0,imgGraph.Width-1,ImgGraph.Height-1);
  ImgGraph.Canvas.MoveTo(200,0);
  ImgGraph.Canvas.LineTo(200,400);
  ImgGraph.Canvas.MoveTo(0,200);
  ImgGraph.Canvas.LineTo(400,200);
end;

procedure TFktPlotter.FormActivate(Sender: TObject);
begin
  ZeichneKS;
end;

procedure TFktPlotter.BtBeendenClick(Sender: TObject);
begin
  close;
end;

function TFktPlotter.XPix(xP:Extended):Integer;
begin
  result:=round(200+xP*200/def)
end;

function TFktPlotter.YPix(yP:Extended):Integer;
begin
  result:=round(200+yP*200/def)
end;


function TFktPlotter.f(x:Extended):Extended;
begin
  result:=a*power(x,3)+b*power(x,2)+c*x+d
end;

procedure TFktPlotter.Zeichnegraph;
var
  xP,yP:Integer;
  x,y:Real;
begin
  x:=-1*(def);
  y:=f(x);
  xP:=XPix(x);
  yP:=yPix(y);
  ImgGraph.Canvas.MoveTo(xP,yP);
  x:=x+0.1;
  repeat
    begin
      y:=f(x);
      xP:=XPix(x);
      yP:=XPix(y);
      ImgGraph.Canvas.LineTo(xP,yP);
      x:=x+0.1
    end
  until x>def;
end;

procedure TFktPlotter.ScrAChange(Sender: TObject);
begin
  PnWertA.Caption:=FloatToStr(ScrA.Position/20);
end;

procedure TFktPlotter.ScrBChange(Sender: TObject);
begin
  PnWertB.Caption:=FloatToStr(ScrB.Position/20);
end;

procedure TFktPlotter.ScrCChange(Sender: TObject);
begin
  PnWertC.Caption:=FloatToStr(ScrC.Position/20);
end;

procedure TFktPlotter.ScrDChange(Sender: TObject);
begin
  PnWertD.Caption:=FloatToStr(ScrD.Position/20);
end;

procedure TFktPlotter.ScrDefChange(Sender: TObject);
begin
  PnWertDef.Caption:=FloatToStr(ScrDef.Position);
end;

procedure TFktPlotter.BeschriftungXAchse;
var
ONEstep,StandortX:extended;
ObenY,UntenY:Integer;
begin
  //Breite einer Einheit berechnen
  ONEstep:=200/def;
  StandortX:=200;
  //Y-Koordinaten für Strich
  ObenY:=195;
  UntenY:=205;
  //Bei (0|0) Anfangen, nach links arbeiten
  repeat
    ImgGraph.Canvas.MoveTo(trunc(StandortX),200);
    StandortX:=StandortX-ONEstep;
    ImgGraph.Canvas.MoveTo(trunc(StandortX),200);
    //Strich zeichnen
    ImgGraph.Canvas.LineTo(trunc(StandortX),ObenY);
    ImgGraph.Canvas.LineTo(trunc(StandortX),UntenY);
  until StandortX<0;
  StandortX:=200;
  //Bei (0|0) Anfangen, nach rechts arbeiten
  repeat
    ImgGraph.Canvas.MoveTo(trunc(StandortX),200);
    StandortX:=StandortX+ONEstep;
    ImgGraph.Canvas.MoveTo(trunc(StandortX),200);
    //Strich zeichnen
    ImgGraph.Canvas.LineTo(trunc(StandortX),ObenY);
    ImgGraph.Canvas.LineTo(trunc(StandortX),UntenY);
  until StandortX>400

end;

{procedure TFktPlotter.BeschriftungYAchse;
var
ONEstep,StandortY:extended;
LinksX,RechtsX:Integer;
begin
  //Breite einer Einheit berechnen
  ONEstep:=200/def;
  /////////////////////
  StandortY:=200;
  //X-Koordinaten für den Strich
  LinksX:=195;
  RechtsX:=205;
  //Bei (0|0) Anfangen, nach unten arbeiten
  repeat
    ImgGraph.Canvas.MoveTo(200,trunc(StandortY));
    StandortY:=StandortY-ONEstep;
    ImgGraph.Canvas.MoveTo(200,trunc(StandortY));
    //Strich zeichnen
    ImgGraph.Canvas.LineTo(LinksX,trunc(StandortY));
    ImgGraph.Canvas.LineTo(RechtsX,trunc(StandortY));
  until StandortY>400;
  /////////////////////
  StandortY:=200;
  //Bei (0|0) Anfangen, nach oben arbeiten
  repeat
    ImgGraph.Canvas.MoveTo(200,trunc(StandortY));
    StandortY:=StandortY+ONEstep;
    ImgGraph.Canvas.MoveTo(200,trunc(StandortY));
    //Strich zeichnen
    ImgGraph.Canvas.LineTo(LinksX,trunc(StandortY));
    ImgGraph.Canvas.LineTo(RechtsX,trunc(StandortY));
  until StandortY<0
  ///////////////////
end;        }

procedure TFktPlotter.Button1Click(Sender: TObject);
// Nur für Testzwecke, zum schnelleren Arbeiten
begin
  ScrC.Position:=20;
  ScrD.Position:=20;
  Initialisieren;
  ZeichneKS;
  BeschriftungXAchse;
  //BeschriftungYAchse;
  ZeichneGraph;
end;



procedure TFktPlotter.BtResetClick(Sender: TObject);
begin
  ScrA.Position:=0;
  ScrB.Position:=0;
  ScrC.Position:=0;
  ScrD.Position:=0;
  ScrDef.Position:=0;
  ZeichneGraph;
end;

end.
Nicht wundern, der Regler für den Definitionsbereich ist noch nicht implementiert, und beim zurücksetzten gibts auch noch nen Bug bei der Aktualisierung des Graphs, aber das egal.

Achja, ein weiteres Problem zeigt sich beim Beschriften der Y-Achse, habe da einfach die Prozedur von der Beschriftung der X-Achse umgeschrieben, aber irgendwie klappt es nicht! Das Programm hängt sich, wenn es mit kompiliert wird, auf! Die Beschriftung der X-Achse funktioniert einwandfrei...ich glaube ich hab da irgendwo einen Denkfehler

Könnt ihr da mal drüber gucken Das fuchst mich^^

grüße
HTC_Magic
  Mit Zitat antworten Zitat