Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Canvas- Problem mit Parabel zeichnen (https://www.delphipraxis.net/164193-canvas-problem-mit-parabel-zeichnen.html)

Blubbel 2. Nov 2011 11:16

Delphi-Version: 5

Canvas- Problem mit Parabel zeichnen
 
Hallo leute!

Habe ein kleines Problem. Ich versuche mein Programm zu verbessern. Habe da jetzt was versucht und meine Parabel wird nicht richtig gezeichnet. also statt "normal" werden diagonale Striche gezeichnet. Kann den Fehler nicht finden... Könnt ihr mir helfen?
Delphi-Quellcode:
for lIndex := 0 to high(AFuncData) do
  begin
    case round(AFuncData[lIndex][0]) of
      0:
      begin
        for i := 0 to GetWidth(ACanvas.ClipRect) do
        begin
          x:=round((i - (GetWidth(PaintBox1.Canvas.ClipRect) div 2)) / GetScaleValue(TrackBar1.Position));
          y:=round(CalcX2(x));
          j:=(GetHeight(PaintBox1.Canvas.ClipRect) div 2) - y * GetScaleValue(TrackBar1.Position);
          PaintBox1.Canvas.Pixels[i,j]:=clblue;

Bummi 2. Nov 2011 11:32

AW: Canvas- Problem mit Parabel zeichnen
 
1. Fehler : Pixels[i,j]

Blubbel 2. Nov 2011 11:38

AW: Canvas- Problem mit Parabel zeichnen
 
Nee, das ist es nicht. er zeichnet es schon richtig nur eben statt punkten oder wie auch immer mit waagerechten strichen....

Bummi 2. Nov 2011 11:55

AW: Canvas- Problem mit Parabel zeichnen
 
Na dann step mal mit dem Debugger durch und lass Dir i,x,y,j anzeigen, dann wird klar was da passiert....

Blubbel 2. Nov 2011 12:01

AW: Canvas- Problem mit Parabel zeichnen
 
versteh ich trotzdem nicht wieso das nicht funktioniert

die gleiche prozedur funktioniert ja aber auch bei anderen parabeln wieso denn da jezz nicht

Blubbel 2. Nov 2011 12:32

AW: Canvas- Problem mit Parabel zeichnen
 
also die gleiche prozedur habe ich vorher auch schon benutzt und da hat sie einwandfrei funktioniert... ich weiß nicht wieso hier nicht und wenn ich es durch steppe werd ich auch nicht schlauer

Bummi 2. Nov 2011 12:33

AW: Canvas- Problem mit Parabel zeichnen
 
Zitat:

ich weiß nicht wieso hier nicht und wenn ich es durch steppe werd ich auch nicht schlauer
doch, solltest Du ....

Aphton 2. Nov 2011 13:01

AW: Canvas- Problem mit Parabel zeichnen
 
Zeig mal ein Bild vom Fehler.

Btw. ich tippe auf Folgendes:
Pixels[x,j]
als Verbesserung!

DeddyH 2. Nov 2011 13:12

AW: Canvas- Problem mit Parabel zeichnen
 
Das Du einmal auf ACanvas und einmal auf PaintBox1.Canvas zugreifst ist beabsichtigt?

Blubbel 2. Nov 2011 13:19

AW: Canvas- Problem mit Parabel zeichnen
 
Liste der Anhänge anzeigen (Anzahl: 1)
@ Deddyh das hab ich schon behoben


also so zeichnet er die parabel

Blubbel 2. Nov 2011 13:48

AW: Canvas- Problem mit Parabel zeichnen
 
aber wie kann das denn sein dass es vorher funktionierte und jetzt nicht mehr?

Jumpy 2. Nov 2011 14:08

AW: Canvas- Problem mit Parabel zeichnen
 
Ein Strich scheint immer von Zahl,50000 bis (Zahl+1),49999 zu gehen. Könnte das am Runden liegen?

Blubbel 2. Nov 2011 14:09

AW: Canvas- Problem mit Parabel zeichnen
 
das hatte ich heute morgen meinen lehrer gefragt und er meinte am runden liegts nicht

Jumpy 2. Nov 2011 14:12

AW: Canvas- Problem mit Parabel zeichnen
 
Sicher? Setz das round mal beim j ein und nicht beim y.

himitsu 2. Nov 2011 14:12

AW: Canvas- Problem mit Parabel zeichnen
 
Und das Canvas.ClipRect ist auch nicht statisch ... es gibt nur den neuzueichnenden Bereich an und nicht den ganzen Clientbereich der Zeichenfläche.

Blubbel 2. Nov 2011 14:17

AW: Canvas- Problem mit Parabel zeichnen
 
@ jumpy wenn ich das mache kommt diese meldung


Zitat:

[Pascal Fehler] main.pas(179): E2010 Inkompatible Typen: 'Integer' und 'Real'
Ich mein, es funktioniert ja alles nur die parabel zeichnet sich eben nicht als "parabel". habe ja ein screen mit eingebunden wie er es zeichnet

Jumpy 2. Nov 2011 14:22

AW: Canvas- Problem mit Parabel zeichnen
 
Es sieht ja schon nach Parabelform aus, nur dass er halt für viele X-Werte den selben Y-Wert zeichnet. Vllt. darf X nicht gerundet werden?

Blubbel 2. Nov 2011 14:25

AW: Canvas- Problem mit Parabel zeichnen
 
Nee, kommt zimlich das gleiche raus

Bummi 2. Nov 2011 14:38

AW: Canvas- Problem mit Parabel zeichnen
 
x,y : Double;

nicht Runden, erst bei

j:=Round(

verwenden ...

Blubbel 2. Nov 2011 14:43

AW: Canvas- Problem mit Parabel zeichnen
 
Och man das geht alles nicht :(

Jumpy 2. Nov 2011 14:51

AW: Canvas- Problem mit Parabel zeichnen
 
Vllt. zeigst du mal den ganzen Code?

Worauf Bummi und auch ich hinauswollen, ist, dass das Round die ganze Zeit gar nicht sein muss. Es dient ja nur dazu, die Nachkommastellen loszuwerden, sprich aus den Real-Werten Integerwerte zu machen, als Koordinaten für das zeichnen. Statt Round hätte man also genausogut auch Trunc nehmen können und es sollte vor dem j reichen.

Mavarik 2. Nov 2011 14:55

AW: Canvas- Problem mit Parabel zeichnen
 
Gib doch mal nen Wertetabelle aus...

Blubbel 2. Nov 2011 14:59

AW: Canvas- Problem mit Parabel zeichnen
 
Delphi-Quellcode:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Printers, Jpeg, phpUtils, ComCtrls, math;

type
  TForm1 = class(TForm)
    edtEingabe: TEdit;
    lblFX: TLabel;
    lbl_X: TLabel;
    btn_Zeichne: TButton;
    edt_Bx: TEdit;
    lbl_bx: TLabel;
    edt_C: TEdit;
    lbl_C: TLabel;
    Label2: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    edtFx: TEdit;
    edt_X: TEdit;
    edt_B: TEdit;
    edt_Cx: TEdit;
    btn_Zeichne1: TButton;
    btn_neu: TButton;
    btn_close: TButton;
    Label1: TLabel;
    Label3: TLabel;
    btnPrint: TButton;
    btnSave: TButton;
    SaveDialog1: TSaveDialog;
    PrintDialog1: TPrintDialog;
    TrackBar1: TTrackBar;
    PaintBox1: TPaintBox;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btn_ZeichneClick(Sender: TObject);
    procedure btn_Zeichne1Click(Sender: TObject);
    procedure btn_closeClick(Sender: TObject);
    procedure btn_neuClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
    procedure btnPrintClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    FFuncData: TphFuncData;
    procedure Draw(ACanvas: TCanvas; AScaleFactor: Integer; AFuncData: TphFuncData);
    procedure Reset;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  a,b,c: Real;

implementation

uses
  Types;

{$R *.dfm}

procedure TForm1.btnPrintClick(Sender: TObject);
var x,y:integer;
begin
  if PrintDialog1.Execute then
  begin
    Printer.BeginDoc;
    for x:=0 to Paintbox1.Height-1 do
    for y:=0 to Paintbox1.Width-1 do
    Printer.Canvas.Pixels[5*x,5*y]:=Paintbox1.Canvas.Pixels[x,y];
    Printer.EndDoc;
  end;
end;

procedure TForm1.btnSaveClick(Sender: TObject);
var
  Bitmap : TBitmap;
begin
  if SaveDialog1.Execute then
  begin
    Bitmap:=TBitmap.Create;
    Try
      Bitmap.Width:=PaintBox1.ClientWidth;
      Bitmap.Height:=PaintBox1.ClientHeight;
      BitBlt(Bitmap.Canvas.Handle,0,0,Bitmap.Width,Bitmap.Height, PaintBox1.Canvas.Handle,0,0,SRCCOPY);
      Bitmap.SaveToFile(SaveDialog1.FileName + '.bmp');
    Finally
      Bitmap.Free;
    end;
  end;
end;

procedure TForm1.Draw(ACanvas: TCanvas; AScaleFactor: Integer; AFuncData: TphFuncData);
var
  lPoint: TPoint;
  lCount, lScale, i, j, y, x: Integer;
  lIndex: Integer;
begin
  ACanvas.Brush.Style:= bsSolid;
  ACanvas.Brush.Color:= clWhite;
  ACanvas.FillRect(ACanvas.ClipRect);
                //X-Achse
  ACanvas.TextOut(0,0, RectToStr(ACanvas.ClipRect));
  ACanvas.MoveTo(0, GetHeight(ACanvas.ClipRect) div 2); //Graph
  ACanvas.LineTo(GetWidth(ACanvas.ClipRect), GetHeight(ACanvas.ClipRect) div 2);
  //Mittelpunkt ausrechnen
  lPoint:= GetCenter(ACanvas.ClipRect);
  //Scalierungswert festlegen

  //Mittelpunkt bis Rechts - X-Achse
  i:= lPoint.X;
  lCount:= 0;
  lScale:= AScaleFactor;
  while i < ACanvas.ClipRect.Right do
  begin
    inc(i,lScale);
    inc(lCount,1);

    DrawGridCaption(ACanvas, Point(i, lPoint.Y), 0, IntToStr(lCount));
  end;

  //Mittelpunkt bis Links der X-Achse
  i:= lPoint.X;
  lScale:= AScaleFactor;
  lCount:= 0;
  while i > ACanvas.ClipRect.Left do
  begin
    dec(i, lScale);
    dec(lCount, 1);

    DrawGridCaption(ACanvas, Point(i, lPoint.Y), 2, IntToStr(lCount));
  end;

  //Y-Achse Von Mittelpunkt nach unten
  lPoint:= GetCenter(ACanvas.Cliprect);
  lScale:= AScaleFactor;
  i:=lPoint.Y;
  lCount:= 0;
  while i < ACanvas.ClipRect.Bottom do
  begin
    inc(i, lScale);
    inc(lCount, -1);

    DrawGridCaption(ACanvas, Point(lPoint.X, i), 1, IntToStr(lCount));
  end;

  //Y-Achse von Mittelpunkt nach oben
  lPoint:= GetCenter(ACanvas.Cliprect);
  lScale:= AScaleFactor;
  i:=lPoint.Y;
  lCount:= 0;
  while i > ACanvas.ClipRect.Top do
  begin
    dec(i, lScale);
    dec(lCount, -1);

    DrawGridCaption(ACanvas, Point(lPoint.X, i), 3, IntToStr(lCount));
  end;
       //Y-Achse
  ACanvas.MoveTo(GetWidth(ACanvas.ClipRect) div 2, 0);  //Graph
  ACanvas.LineTo(GetWidth(ACanvas.ClipRect) div 2, GetHeight(ACanvas.ClipRect));

  for lIndex := 0 to high(AFuncData) do
  begin
    case round(AFuncData[lIndex][0]) of
      0:
      begin
        for i := 0 to GetWidth(ACanvas.ClipRect) do
        begin
          x:=(i - (GetWidth(ACanvas.ClipRect) div 2)) div GetScaleValue(TrackBar1.Position);
          y:=round(CalcX2(x));
          j:=round(GetHeight(ACanvas.ClipRect) div 2) - y * GetScaleValue(TrackBar1.Position);
          ACanvas.Pixels[i, j]:=clblue;

          OutputDebugString(PChar(IntToStr(x) +'x'+ IntToStr(y)));
        end;
      end;
      1:
      begin
//        for i := 0 to high - 1 do //?????????????????????????
        begin
          //CalcX2(a * sqr (x) + b * x + c)
          ACanvas.Pixels[i,j]:=clblue;
        end;
      end;
      2:
      begin
//        for i := 0 to high -1 do  //????????????????????????
        begin
          //CalcX2(a * sqr (x + b) + c);
          ACanvas.Pixels[i,j]:=clblue;
        end;
      end;
    end;
  end;
end;

procedure TForm1.Reset;
begin
  SetLength(Self.FFuncData, 0);
  Draw(PaintBox1.Canvas, GetScaleValue(TrackBar1.Position), Self.FFuncData);

  TrackBar1.Position := 0;
  edtEingabe.Text := '';
  edt_Bx.Text := '';
  edt_C.Text := '';
  edtFx.Text := '';
  edt_X.Text := '';
  edt_B.Text := '';
  edt_Cx.Text := '';
end;

procedure TForm1.btn_closeClick(Sender: TObject);
begin
 Form1.Close;
end;

procedure TForm1.btn_ZeichneClick(Sender: TObject);
var
  i,j:Integer;
  x,y: Real;
begin
  a:= StrToFloatDef(edtEingabe.Text, 0);
  b:= StrToFloatDef(edt_Bx.Text, 0);
  c:= StrToFloatDef(edt_C.Text, 0);
  i:=0;

  for i := 0 to GetWidth(PaintBox1.Canvas.ClipRect) do
  begin
    x:=(i - (GetWidth(PaintBox1.Canvas.ClipRect) div 2) / GetScaleValue(TrackBar1.Position));
    y:= (a * sqr (x) + (b * x) + c);          //???????????????????????????????????????????
    j:=round((GetHeight(PaintBox1.Canvas.ClipRect) div 2) - y * GetScaleValue(TrackBar1.Position));
    PaintBox1.Canvas.Pixels[i,j]:=clblue;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SetLength(Self.FFuncData, high(FFuncData) +2);
  SetLength(Self.FFuncData[high(FFuncData)], 1);

  Self.FFuncData[high(FFuncData)][0] := 0;

  Draw(PaintBox1.Canvas, GetScaleValue(TrackBar1.Position), Self.FFuncData);
end;

procedure TForm1.btn_neuClick(Sender: TObject);
begin
  Paintbox1.Canvas.Rectangle(0,0,width,height);
  Reset;
end;

procedure TForm1.btn_Zeichne1Click(Sender: TObject);
var
  i,j:Integer;
  x,y: Real;
begin
  a:= StrToFloatDef(edt_X.Text, 0);
  b:= StrToFloatDef(edt_B.Text, 0);
  c:= StrToFloatDef(edt_Cx.Text, 0);
  i:=0;

  for i := 0 to GetWidth(PaintBox1.Canvas.ClipRect) do
  begin
    x:= (i-(GetWidth(PaintBox1.Canvas.ClipRect) div 2)) / GetScaleValue(TrackBar1.Position);
    y:= (a * sqr (x + b) + c);
    j:= round((GetHeight(PaintBox1.Canvas.ClipRect) div 2) - y * GetScaleValue(TrackBar1.Position));
    PaintBox1.Canvas.Pixels[i,j]:=clred;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  self.Reset;

  Draw(PaintBox1.Canvas, GetScaleValue(TrackBar1.Position), Self.FFuncData);
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Draw(PaintBox1.Canvas, GetScaleValue(TrackBar1.Position), Self.FFuncData);
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  Draw(PaintBox1.Canvas, GetScaleValue(TrackBar1.Position), Self.FFuncData);
end;

procedure TForm1.TrackBar1Change(Sender: TObject);
begin
  Draw(PaintBox1.Canvas, GetScaleValue(TrackBar1.Position), Self.FFuncData);
end;

end.




unit phpUtils;

interface

uses
  Windows, SysUtils,Types, Graphics, Dialogs, math;

type
  TphFuncParams = array of real;
  TphFuncData = array of TphFuncParams;


  function GetWidth(AValue: TRect): Integer;
  function GetHeight(AValue: TRect): Integer;
  function RectToStr(AValue: TRect): String;
  function GetCenter(AValue: TRect): TPoint;
  function DrawGridCaption(ACanvas: TCanvas; APoint: TPoint; APos: Integer; AText: String): Boolean;
  function GetScaleValue(APos: Integer): Integer;

  function CalcX2(AXValue: real): real;

implementation

  function CalcX2(AXValue: real): real;
  begin
    result:= Power(AXValue, 2)
  end;


  function GetScaleValue(APos: Integer): Integer;
  begin
    Result:= ((APos + 10) + 1) * 10;
  end;

  function GetWidth(AValue: TRect): Integer;
  begin
    Result:= (AValue.Right - AValue.Left);
  end;

  function GetHeight(AValue: TRect): Integer;
  begin
    Result:= (AValue.Bottom - AValue.Top);
  end;

  function RectToStr(AValue: TRect): String;
  begin
    Result:= IntToStr(GetWidth(AValue)) + 'x' + IntToStr(GetHeight(AValue));
  end;

  function GetCenter(AValue: TRect): TPoint;
  begin
    Result.X := (GetWidth(AValue) div 2);
    Result.Y := (GetHeight(AValue) div 2);
  end;

  function DrawGridCaption(ACanvas: TCanvas; APoint: TPoint; APos: Integer; AText: String): Boolean;
  begin
    Result:= false;

    if Assigned(ACanvas) and (AText <> '') then
    begin
      case APos of
        0:
        begin
          ACanvas.TextOut(APoint.X-3, APoint.Y+5, AText);

          ACanvas.MoveTo(APoint.X, APoint.Y - 5);
          ACanvas.LineTo(APoint.X, APoint.Y + 5);

          Result:= true;
        end;
        1:
        begin
          ACanvas.TextOut(APoint.X+5, APoint.Y-3, AText);

          ACanvas.MoveTo(APoint.X - 5, APoint.Y);
          ACanvas.LineTo(APoint.X + 5, APoint.Y);

          Result:= true;
        end;
        2:
        begin
          ACanvas.TextOut(APoint.X-3, APoint.Y+5, AText);

          ACanvas.MoveTo(APoint.X, APoint.Y - 5);
          ACanvas.LineTo(APoint.X, APoint.Y + 5);

          Result:= true;
        end;
        3:
        begin
          ACanvas.TextOut(APoint.X+5, APoint.Y-3, AText);

          ACanvas.MoveTo(APoint.X - 5, APoint.Y);
          ACanvas.LineTo(APoint.X + 5, APoint.Y);

          Result:= true;
        end;
      end;
    end;
  end;

end.

Luckie 2. Nov 2011 15:08

AW: Canvas- Problem mit Parabel zeichnen
 
Pack das Berechnen der Punkte mal in eine eigene Klasse. Dann kann man das auch besser debuggen.

Jumpy 2. Nov 2011 15:26

AW: Canvas- Problem mit Parabel zeichnen
 
Hier in der Funktion haste das round zumindest nur beim j:=...

Delphi-Quellcode:
procedure TForm1.btn_Zeichne1Click(Sender: TObject);
var
  i,j:Integer;
  x,y: Real;
begin
  a:= StrToFloatDef(edt_X.Text, 0);
  b:= StrToFloatDef(edt_B.Text, 0);
  c:= StrToFloatDef(edt_Cx.Text, 0);
  i:=0;

  for i := 0 to GetWidth(PaintBox1.Canvas.ClipRect) do
  begin
    x:= (i-(GetWidth(PaintBox1.Canvas.ClipRect) div 2)) / GetScaleValue(TrackBar1.Position);
    y:= (a * sqr (x + b) + c);
    j:= round((GetHeight(PaintBox1.Canvas.ClipRect) div 2) - y * GetScaleValue(TrackBar1.Position));
    PaintBox1.Canvas.Pixels[i,j]:=clred;
  end;
end;

Blubbel 2. Nov 2011 15:49

AW: Canvas- Problem mit Parabel zeichnen
 
@ jumpy

ja ich weiß ich habe ja, um alle graphen die gezeichnet wurden auch zoomen zu können, ein array angelegt. deswegen ja round.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:46 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