![]() |
Kreisbogen direkt zeichnen (ohne canvas.arc)
Hallo DP,
folgende Sache: ich möchte genau das, was die Funktion canvas.arc kann, manuell nachbauen. Also ein Kreissegment (oder einen Kreisbogen) zeichnen und zwar zwischen zwei Punkten P1 und P2. Warum nicht arc nehmen? Ich brauche die Koordinaten einzelner Kreispunkte explizit, nicht das fertige Ding. Jetzt kann ich mit der Kreisgleichung anfangen: (x-xm)² + (y-ym)² = r² Die Frage aber dann: wie kann ich den relevanten Teil des Kreises herausnehmen? Den ganzen Kreis durchgehen und prüfen ... ja, aber was? Ich sehe hier keine sinnvolle Prüfung. Alternative Kreisgleichung: x = xm + r * cos phi y = ym + r * sin phi mit phi = 0 .. 2pi Die Idee hier: ich rechne mir von P1 und P2 jeweils phi aus und prüfe, ob phi im gegebenen Bereich liegt. Im Grunde rolle ich also den Kreis auf eine Strecke von 0 bis 2 pi ab und lasse nur jene werte durch, die zwischen P1 und P2 liegen. Das Problem dabei: nach der Umkehrung des Cos mit dem ArcCos kann ich ja nicht mehr sagen, ob der ursprüngliche Wert zB: pi/2 oder 3pi/2 war. Eine einfache Prüfung geht also so auch nicht. So, und hier stecke ich einmal. Aber dieses Problem hat doch bestimmt schon irgendwer einmal gelöst. Nicht zuletzt die Leute von Borland (oder vermutlich Microsoft), die den arc geschrieben haben. kann mir jemand weiterhelfen? danke! gruß tom |
Re: Kreisbogen direkt zeichnen (ohne canvas.arc)
Hallo,
Falls du English kannst, lies dir doch mal den Artikel ![]() Die Delphi Umsetzung würde etwa so aussehen:
Delphi-Quellcode:
procedure drawArc(Canvas: TCanvas; centerX, centerY, radius, startAngle, arcAngle: Real; steps: Word);
var angleStep, angle, twoPI, xx, yy: Real; i: Word; begin // // For convenience, store the number of radians in a full circle. twoPI := 2 * PI; // // To determine the size of the angle between each point on the // arc, divide the overall angle by the total number of points. angleStep := arcAngle / steps; // // Determine coordinates of first point using basic circle math. xx := centerX + cos(startAngle * twoPI) * radius; yy := centerY + sin(startAngle * twoPI) * radius; // // Move to the first point. Canvas.moveTo(Trunc(xx), Trunc(yy)); // // Draw a line to each point on the arc. for i := 1 to steps - 1 do begin // // Increment the angle by "angleStep". angle := startAngle + i * angleStep; // // Determine next point's coordinates using basic circle math. xx := centerX + cos(angle * twoPI) * radius; yy := centerY + sin(angle * twoPI) * radius; // // Draw a line to the next point. Canvas.lineTo(Trunc(xx), Trunc(yy)); end; end; procedure TForm1.Button1Click(Sender: TObject); begin drawArc(Canvas, 250, 250, 200, 45 / 360, -90 / 360, 20); end; |
Re: Kreisbogen direkt zeichnen (ohne canvas.arc)
Welche Punkte brauchst du denn genau? Um einen Kreisbogen (oder eine Linie oder einen Kreis) zu zeichnen geht man normalerweise nicht von dieser Figur aus und zeichnet jeden x-ten Punkt, sondern man geht von den Pixeln des Ziels aus. Damit vermeidet man dann nämlich sowohl Lücken als auch doppelt gezeichnete Pixel, hat also das beste Ergebnis und die beste Geschwindigkeit. Wenn das für dich ok wäre, dann wären die Linien- und Kreisalgorithmen vom guten alten Bresenham für dich vielleicht einen Blick wert. Vielleicht kannst du den Kreisalgorithmus für einen Bogen adaptieren.
Wenn du hingegen ganz bestimmte Punkte auf dem Bogen brauchst, ist toms' Lösung natürlich günstiger. |
Re: Kreisbogen direkt zeichnen (ohne canvas.arc)
Danke für die Tipps!
Bei meiner Suche bin ich nun auch schon auf Bresenham gestossen, das dürfte ziemlich genau sein, was ich brauche, wenngleich ich noch keine implementierung eines kreisbogens mit Bresenham in Pascal gefunden habe. Aber gut, das lässt sich durch Such- oder Überlegarbeit auch noch lösen. danke jedenfalls! gruß tom |
Re: Kreisbogen direkt zeichnen (ohne canvas.arc)
Hmm, also vielleicht hat jemand noch Rat:
Zeichnen eines Kreises mit Bresenham geht soweit. Wie schränke ich nun aber auf die Strecke zwischen P1 und P2 ein? hier: ![]() steht mal ganz entspannt: Zitat:
|
Re: Kreisbogen direkt zeichnen (ohne canvas.arc)
@toms
die Lösung wäre an sich schön, mein Problem damit ist, dass nur die Punkte P1 und P2 bekannt sind, zwischen denen der Kreisbogen gezeichnet werden soll, nicht die Winkel. Jetzt kann man zwar aus den Punkten die Winkel errechnen (als Winkel zwischen zwei Vektoren), was ich auch so mache. Allerdings kommen da eben Winkel zwischen 0 und 180 heraus. Das heisst, die Punkte P1 = (10 | 20) und P2 = (10 | -20) ergeben den gleichen Winkel und damit keinen Kreisbogen. |
Re: Kreisbogen direkt zeichnen (ohne canvas.arc)
Zitat:
Da du aber deine Punkte kennst, weisst du somit auch ganz genau, in welchem Quadranten deines Einheitskreises du dich befindest. Darauf musst du dann deine Winkel mappen. |
Re: Kreisbogen direkt zeichnen (ohne canvas.arc)
Oder einfach
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:42 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