![]() |
Ellipsenalgo aus Formelsammlung kreieren
Hallo
Ich habe ausgehend von der Ellipsengleichung: (Quelle: Hans Jochen Bartsch "Taschenbuch Mathematische Formeln für Ingenieure und Naturwissenschaftler" sqr(x)/sqr(a) + sqr(y)/sqr(b) = 1 nach y aufgelöst: y = +/- (b/a)*sqrt(sqr(a)-sqr(x)) folgendes Programm erstellt:
Delphi-Quellcode:
Da wird aber x ncht verändert, was naxh meinem Verständnis aber der Fall sein sollte wenn ich weigstens eine halbe Ellipse zeichnen will.
procedure DrawEllipse(xm,ym,xR,yR,stangle,endangle: Extended);
var angle: extended; a,b,x: extended; yp,yn: Extended; px,py: int64; begin angle := 0.0; angle := stangle; x := xm; y := ym; //Mittelpinkt der Ellipse a := xR; b := yR; //a und b --- x- und y Readien der Ellipse while angle < endangle do //hier aber Winkel als Laufvariable benutzt begin a := x / cos(angle); b := y / sin(angle); //x = a * cos(angle); y = b * sin(angle) yp := b/a * sqrt(sqr(a)-sqr(x)); //der Punkt der Ellipse an der Position X py := Round(yp); //auf Integer gerundet und wegen Int64 als Rückgabewert DrawPixel(x,Longword(yp)) //auf Longword gecastet yn := -b/a * sqrt(sqr(a)-sqr(x)); //gleicher Ablauf py := round(yp); //für die negative Halbachse end; end; Ich verwende den Winkel als Laufvariable, habe aber ein "Brett vorm Kopp" wegen Laufvariale x die ja mit dem Winkel verändert werden muss. wie kann ich möglichst effektiv die Gleicung so umstellen dass ich trotz Winkel als Laufvarible den Parameter X ebenfalls weiter zähle. Irgendwie habe ich im Moment einen Knoten im Kopf. |
AW: Ellipsenalgo aus Formelsammlung kreieren
Du musst x und y als Funktion von angle haben, dann kannst Du für jeden Wert von angle den Punkt (x,y) zeichnen.
Hier ist ein bisschen Mathe dafür, kannst aber auch Ellipse und Polarkoordinaten googeln. r ist der Abstand vom Mittelpunkt. X = x-xm Y = y - xm X = r*cos(angle) Y = r* sin(angle) Löse X^2/a^2 + Y^2/b^2 = 1 nach r auf: r = a*b/(sqrt(sqr(b*cos(angle))+ sqr(a*sin(angle))) Dabei kann man auch noch sqr(sin(angle)) durch 1 - sqr(cos(angle)) ersetzen. Jetzt (x,y) = (xm,ym) + (r*cos(angle), r*sin(angle)) in Abhängigkeit von angle zeichen. |
AW: Ellipsenalgo aus Formelsammlung kreieren
Hi,
You have to distinguish (x,y) from (x0,y0) "ellipse center", you already have (xm,ym) which is (x0,y0). After than it is easy to draw the pixel (X,Y) X = x0 + x(angle) Y = y0 + y(angle) In other words, the naming of the variables is deceiving you, if it is yp or yn ?! Another thing: you are drawing both +- values so it will mirrored, use one value (the positive) and walk the angle with refined (small enough) step per radius. |
AW: Ellipsenalgo aus Formelsammlung kreieren
Wirklich unbedingt "selbst Pixel für Pixel" :?:
TCanvas.Ellipse für einen Kreis, bzw. eine Ellipse und Vcl.Graphics.TCanvas.Arc für einen Bogen (Teil eines Kreises/Ellipse) ![]() ![]() PS: py und yn sind doch etwas "nutzlos", da sie (ihr Inhalt) niemals verwendet werden, und ich bin mir fast sicher, dass der Compilier es dir eigentlich auch mitteilen sollte. (falls jemand die Compilerwarnungen liest) py, vor dem DrawPixel ist auch nutzlos. Sicher, dass danach bei Longword(yp) nicht py anstatt yp gemeint ist? Sowie die a und b, vor der Schleife, auch noch. Wobei es ja bereits beim invaliden "CAST"
Delphi-Quellcode:
abgeraut sein wird
Longword(yp)
und natürlich beim nichtdeklarieren
Delphi-Quellcode:
.
y
Sicher, dass deine Übersetzung so wirklich allgemein nicht irgendwelche groben Überlegungs-/Übersetzungsfehler (Formel zu Code) besitzt, als nur das eine fehlende X? |
AW: Ellipsenalgo aus Formelsammlung kreieren
Wenn zu Beginn diese Bedingung
Delphi-Quellcode:
erfüllt ist, müsstest Du in eine Endlosschleife laufen, da angle in der Schleife nicht verändert wird und von daher die Abbruchbedingung der Schleife nie erfüllt sein wird.
while angle < endangle do
Eine Zuweisung auf x erfolgt nur vor der Schleife:
Delphi-Quellcode:
. Danach wird x nicht mehr verändert, von daher muss x immer gleich bleiben.
x := xm;
Gibt der Kompiler irgendwelche Warnungen aus, z. B. dass der auf eine Variabel zugewiesene Wert nie benutzt wird? Das sollte (mindestens) bei angel, a, b und py eigentlich der Fall sein. Bist Du sicher, dass die Formelauflösung nach y korrekt ist?
Delphi-Quellcode:
y = ±b * sqrt(1 - sqr(x) / sqr(a))
|
AW: Ellipsenalgo aus Formelsammlung kreieren
Der code muss sowieso neu geschrieben werden. Hier ist ein Beispiel (ungetestet)
Delphi-Quellcode:
extended ist meiner Meinung nach übertrieben genau.
//Zeichne Ellispe zwischen stangle und endangle mit Winkelschrittweite AngleStep
procedure DrawEllipse(xm,ym,xR,yR,stangle,endangle,AngleStep: Extended); var angle: extended; a,b,x,y,r: extended; begin angle := stangle; a := xR; b := yR; //a und b --- x- und y Readien der Ellipse while angle < endangle do begin r := a*b/sqrt(sqr(b*cos(angle))+sqr(a*sin(angle))); x := xm + r*cos(angle); y := ym + r*sin(angle); DrawPixel(round(x), round(y)); //was auch immer das ist :) angle:=angle+AngleStep; end; end; Achtung: angle muss in radians angegeben werden, also 360° = 2*Pi Statt sin, cos kann man auch SinCos aus der math-unit verwenden. Renate |
AW: Ellipsenalgo aus Formelsammlung kreieren
Vielleicht ist es besser, die Laufvariable parametrisch zu Normieren und nicht als Winkel zu übernehmen.
Dann kann man das Rendering etwass besser steuern. So ungefähr meine ich, ungetestet:
Delphi-Quellcode:
// Zeichnet eine Ellipse mit Mittelpunkt (xm, ym), Radien xR, yR,
// zwischen Startwinkel stangle und Endwinkel endangle (in Grad), // mit numSteps Schritten für gleichmäßigere Punktverteilung procedure DrawEllipse(xm, ym, xR, yR, stangle, endangle: Extended; numSteps: Integer); var t, tStart, tEnd, tStep: Extended; i: Integer; x, y: Extended; begin if numSteps < 1 then Exit; // Sicherheitsprüfung // Winkel in Radiant umrechnen tStart := DegToRad(stangle); tEnd := DegToRad(endangle); // Normierter Parameter t von tStart bis tEnd tStep := (tEnd - tStart) / numSteps; // Zeichne Punkte entlang der Ellipse for i := 0 to numSteps do begin t := tStart + i * tStep; // Parametrische Darstellung der Ellipse x := xm + xR * Cos(t); y := ym + yR * Sin(t); DrawPixel(Round(x), Round(y)); // Zeichne Pixel end; end; |
AW: Ellipsenalgo aus Formelsammlung kreieren
Zitat:
Das hatte ich glatt vergessen ... Ja, die Schritte eingeben ist immer besser. |
AW: Ellipsenalgo aus Formelsammlung kreieren
Danke an Euch alle! So wird meine Ellipse gezeichnet. Mit 4096 Schritten passiert das lückenlos.
Wenn ich dieStart und Endwinkel direkt eingebe wird erst der untere Ellipsenbogen gezeichnet, dann der obere. Wenn ich zuerst den oberen Ellipsenbogen oder Teile davon gezeichnet haben will, muss ich die Einkelangaben noch mit (-1) multiplizieren. @himitsu: Ja, Delphi kann das auch aber ich wollte ja gerade wissen wie das Delphi intern macht und dazu ist die Ellipsengleiching notwendig. Dennoch Danke, wie auch an alle Anderen hier die mir geholfen haben. Ich habe jetzt @Renate Schaaf's Entwurf ergänzt um @Rolle72's NumStep im Test. Danke wie verrückt. Morgen guck ich mir die nach x und y aufgelösten Gleichungen an und gehe das noch mal auf dem Papier durch. :bounce1: |
AW: Ellipsenalgo aus Formelsammlung kreieren
Zitat:
Natürlich! Canvas-y geht ja von oben nach unten. Also angle für wie die Uhr geht, und -angle andersrum. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:48 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