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;