Einzelnen Beitrag anzeigen

Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.429 Beiträge
 
Delphi 10.4 Sydney
 
#19

AW: Probleme mit Sinus Darstellung

  Alt 26. Feb 2015, 16:09
An der Sinusfunktion is ja erst mal nichts besonderes:

y := f(x)

Dann haben wir ein Rechteck als Zeichenfläche:

R: TRect

Den Wert von X für die erste linke Pixelspalte und Y für die oberste Pixelzeile auf der Zeichenfläche:

x0: Double
y0: Double

Die Breite und Höhe eines Pixels in unserem skalliertem Koordinatensystem:

dx: Double
dy: Double

Die verallgemeinerte Aufgabe ist die Berechnung der Punkte für die Darstellung einer beliebigen f(x)-Funktion:
Delphi-Quellcode:
type
  TFxFuntion = function(const x: Extended): Extended;
  TPointDynArray = array of TPoint;

function BerechnePunkteDarstellung(AFunc: TFxFuntion; const ARect: TRect; x0, y0, dx, dy: Double): TPointDynArray;
var
  x, y: Double;
  i: Integer;
begin
  {für jede Spalte einen Punkt}
  SetLength(Result, ARect.Right - ARect.Left + 1);
  {Punkte berechnen}
  x := x0;
  for i := Low(Result) to High(Result) do
  begin
    y := AFunc(x);
    {unser Koordinatensystem steht auf dem Kopf}
    y := -y;
    {oberen Rand addieren}
    y := y0 + y;
    {skallieren}
    y := y / dy;
    {runden}
    Result[i].x := ARect.Left + i;
    Result[i].y := ARect.Top + Round(y);
    {nächster Punkt}
    x := x + dx;
  end;
end;

procedure ZeichnePunkteDarstellung(ACanvas: TCanvas; const ARect: TRect; const APoints: TPointDynArray);
var
  h: THandle;
begin
  h := SaveDC(ACanvas.Handle);
  try
    {Zeichenfläche einschränken}
    IntersectClipRect(ACanvas.Handle, ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
    Polyline(ACanvas.Handle, APoints[0], Length(APoints));
  finally
    RestoreDC(ACanvas.Handle, h);
  end;
end;

procedure TFTest.PaintBox1Paint(Sender: TObject);
var
  R: TRect;
  x0, y0, dx, dy: Double;
  P: TPointDynArray;
begin
  with TPaintBox(Sender) do
  begin
    R := ClientRect;
    {Hintergrund}
    Canvas.Brush.Color := clGray;
    Canvas.Brush.Style := bsSolid;
    Canvas.FillRect(R);
    Canvas.Brush.Style := bsClear;
    {ein Rechteck}
    InflateRect(R, -10, -10);
    Canvas.Pen.Color := clBlack;
    Canvas.Pen.Width := 1;
    Canvas.Rectangle(R);
    {darin der Graph}
    InflateRect(R, -1, -1);
    {Parameter initialisieren}
    x0 := 0;
    y0 := 3;
    dx := 0.05;
    dy := 0.05;
    P := BerechnePunkteDarstellung(sin, R, x0, y0, dx, dy);
    Canvas.Pen.Color := clLime;
    ZeichnePunkteDarstellung(Canvas, R, P);
  end;
end;

Geändert von Blup (26. Feb 2015 um 16:13 Uhr)
  Mit Zitat antworten Zitat