![]() |
Funktion graphisch aufzeichnen (Polarkoordinaten)
Analog zu meinem Projekt JTM habe ich mich gefragt, wie ich in ein Polarkoordinatensystem zeichnen könnte. Die Lösung ist nicht so einfach wie bei einem kartesischen Koordinatensystem. Mein Lösungsansatz wäre der folgende:
Delphi-Quellcode:
Damit haben wir unsere Variablen. oX und oY sind jeweils origin-x und origin-y, also die Mitte in diesem Fall (genau gesagt der Koordinatenursprung). Mit StepOne wird der Abstand zwischen zwei Ticks festgelegt, wobei der numerische Abstand zwischen zwei Ticks immer 1 ist. Nun zeichnen wir erstmal das leere Koordinatensystem ohne Inhalt:
var
... stepOne: Integer; oX, oY: Integer; wh: Integer; // wh = WidthHeight because it's the same // But we only want the smaller one, so we // save it in a variable that we don't always // have to ask for it.
Delphi-Quellcode:
Bis dahin ist alles fröhliches Zeichnen ohne große Rechnerei. Ring1 ist bei mir ein Menu-Item, aber es kann genauso eine Checkbox oder ein Radiobutton (wobei das nicht sinnvoll wäre) sein. Wie der Name schon sagt, wird angegeben, ob man einen grauen Ring außen herum haben möchte. :zwinker: can ist als MetafileCanvas deklariert. Warum? Weil eine Vektorgraphik praktisch ist, wenn man Drucken möchte oder die Graphik verlustfrei ins Word kopieren möchte. Und da das für uns keine großen Umstände sind, lohnt es sich, von Anfang an mit Vektorgraphiken zu arbeiten. Nun kommt der Teil, der die Funktionen aufzeichnen:
procedure TForm1.DrawPlot;
var x, y, i: Integer; _x, _y: Single; can: TMetafileCanvas; begin try if Image1.Width > Image1.Height then wh := Image1.Height else wh := Image1.Width; Image1.Picture.Metafile.Width := wh; Image1.Picture.Metafile.Height := wh; can := TMetafileCanvas.Create(Image1.Picture.Metafile, 0); oX := wh div 2; // find the origin (x) oY := wh div 2; // find the origin (y) can.Pen.Color := clSilver; can.Pen.Style := psClear; can.Brush.Color := clWhite; can.Rectangle(0, 0, wh, wh); if Ring1.Checked then // draw the gray circle around the graph, as you // can se it in most of the graphs you find. begin can.Pen.Style := psSolid; can.Ellipse(0, 0, wh, wh); end; can.Pen.Style := psSolid; can.Font.Name := 'Arial'; can.Font.Size := 10; for x := -(wh div stepOne div 2) to (wh div stepOne div 2) do // Draw ticks begin can.Pen.Color := clBlack; can.MoveTo(oX + x * stepOne, oX - 2); // ticks on the x-axis can.LineTo(oX + x * stepOne, oX + 3); can.TextOut(oX + x * stepOne + 5, oX + 5, // draw the labels IntToStr(x)); can.MoveTo(oY - 2, oY + x * stepOne); // ticks on the y-axis can.LineTo(oY + 3, oY + x * stepOne); can.TextOut(oY + 5, oY + x * stepOne + 5, // draw the labels IntToStr(x)); end; can.MoveTo(0, oX); // The lines of the y- and x-axis can.LineTo(wh, oX); can.MoveTo(oY, 0); // the other line can.LineTo(oY, wh);
Delphi-Quellcode:
Genau genommen ist es der zweite Teil der Prozedur DrawPlot, also mit Freigabe von can. Parser1 ist vom Typ TParser aus der Unit Parser10. Einfach mal bei torry.net nach "parser" suchen, dann wird man schnell fündig. Wenn man einen anderen Parser benutzt, einfach die entsprechenden Aufrufe ersetzen. Was die Eigenschaften bedeuten, sollte sich eigentlich von selbst erklären.
// No go through all items and draw them
for i := 0 to ListBox1.Items.Count - 1 do begin Parser1.Expression := ListBox1.Items[i]; Parser1.X := 0; try can.Pen.Color := StrToInt('$00'+Copy(ColorDialog1.CustomColors[i], 8, 6)); except can.Pen.Color := clBlack; end; can.MoveTo(oX + round(cos(_x) * Parser1.Value * stepOne), oY - round(sin(_x) * Parser1.Value * stepOne)); for x := 1 to round(2 * Pi * 100) do begin _x := x / 100; Parser1.X := _x; can.LineTo(oX + round(cos(_x) * Parser1.Value * stepOne), oY - round(sin(_x) * Parser1.Value * stepOne)); can.MoveTo(oX + round(cos(_x) * Parser1.Value * stepOne), oY - round(sin(_x) * Parser1.Value * stepOne)); end; end; finally can.Free; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:08 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz