Ellipsenumfangberechnung - Fehler?
-
Hey, hab ein Programm für die Uni geschrieben, dass mir den Umfang einer Ellipse näherungsweise berechnet. Dabei wird die Ellipse in n Geradenstücke aufgeteilt, dessen Länge bestimmt und am Ende zum Umfang aufsummiert.
Nun ist es so, dass ab einem bestimmten Wert u0 auf einmal größer ist als u1, was aber nach logischer Betrachtung eigentlich nicht sein dürfte (wegen Annäherung).
Eingegeben werden die Halbachsen a und b, sowie der relative Fehler ((x1-x0)/x1).
Das Programm soll stoppen, sobald entweder n = 2^24 erreicht ist, oder der rel. Fehler (Ist) kleiner ist als der rel. Fehler (Soll, bzw. Eingabe).#include <stdio.h> #include <math.h> double laenge(double x1, double y1, double x2, double y2) { return sqrt((y2-y1) * (y2-y1) + (x1-x2) * (x1-x2)); //Länge über Pythagoras } void ellipse(double a, double b, double t, double* x, double* y) //Koordinaten der Punkte { *x = a * cos(t); *y = b * sin(t); } int main(void) { double a, b, t, //Längen und Abschnittsparameter x1, y1, x2, y2,//Koordinaten u0, u1, //Umfang n und Umfang n*2 e, eps; //rel. Fehler (Ist), rel. Fehler (Soll) int n, n0; //n in 1. Quadrant; n0 gesamt printf("Halbachsen a und b eingeben: "); scanf("%lf %lf", &a, &b); printf("Relativen Fehler e eingeben: "); scanf("%lf", &e); for(n = 4, n0 = 4, eps = 1; n <= (64*64*64*64) /*&& e <= eps*/ ; n0 *= 2) //bis e <= eps oder n = 2^24; n0 wird verdoppelt { n = n0 / 4; //Umfang >> u0 << bei n/4 Geradenstücke for(t = 0, u0 = 0; t < M_PI / 2; t += (M_PI / 2) / n) { ellipse(a, b, t, &x1, &y1); //P1 ellipse(a, b, t + (M_PI / 2) / n, &x2, &y2);//P2 u0 += laenge(x1, y1, x2, y2); //Aufsummation } n = n0 / 2; //Umfang >> u1 << bei n/2 Geradenstücke for(t = 0, u1 = 0; t < M_PI / 2; t += (M_PI / 2) / n) { ellipse(a, b, t, &x1, &y1); //P1 ellipse(a, b, t + (M_PI / 2) / n, &x2, &y2);//P2 u1 += laenge(x1, y1, x2, y2); //Aufsummation } u0 *= 4; u1 *= 4; eps = (u1 - u0) / u1; //Gemäß (x1 - x0) / x1 printf("U0 = %.15lf\n", u0); printf("U1 = %.15lf\n\n", u1); } printf("Umfang = %.15lf\n", u0); printf("Relativer Fehler = %.25lf\n", eps); printf("n = %i\n", n); return 0; }
u0 ist der Umfang bei n/4 und u1 bei n/2 .
Die Längen werden nur für den ersten Quadranten berechnet (Symmetrie) und zum Schluss mit 4 multipliziert.Hier ein Teil der Ausgabe (Diese Ausgabe wurde aus dem obigen Code wieder entfernt, war nur zur Überprüfung gedacht) für n = 16 bis n = 512:
U0 = 45.732250080830433 U1 = 45.952325632195659 U0 = 45.952325632195659 U1 = 46.007743505572165 U0 = 46.007743505572165 U1 = 46.021604352373600 U0 = 46.021604352373600 U1 = 47.006730924295546 U0 = 47.006730924295546 U1 = 46.516799390660779 U0 = 46.516799390660779 U1 = 46.271588559358030
Hat jmd ne Idee, warum auf einmal U0 größer ist als U1?
MfG
-
Durch Rundungsfehler bei der Berechnung von t.
Du hast da dann nicht 64 Durchläufe sondern 63.
Und da du nur ein Viertel berechnest, vervierfacht sich der Fehler.Zähle die Durchläufe (du willst ja n haben) und bereche t jedesmal neu
t = i * ((M_PI / 2) / n)
-
Top, danke!
Hat was gebracht, nur leider setzt dasselbe Problem nun etwas später bei genaueren Werten ein. Ich denke mal aufgrund der Aufsummierung des Umfangs:for(t = 0, i = 0, u0 = 0; t < M_PI / 2; t = i * (M_PI / 2) / n) { ellipse(a, b, t, &x1, &y1); //P1 ellipse(a, b, t + (M_PI / 2) / n, &x2, &y2);//P2 u0 += laenge(x1, y1, x2, y2); //Aufsummation ++i; }
oder? Aber die kann ich ja schlecht als Produkt berechnen, ist ja im Endeffekt näherungsweise ein Integral... long double hab ich auch schon versucht^^
-
DirkB schrieb:
Zähle die Durchläufe (du willst ja n haben) ...
Du musst i überprüfen, nicht t.
for(i = 0, t = 0, u0 = 0; i < n ; ++i) { t = i * (M_PI / 2) / n ellipse(a, b, t, &x1, &y1); //P1 ellipse(a, b, t + (M_PI / 2) / n, &x2, &y2);//P2 u0 += laenge(x1, y1, x2, y2); //Aufsummation }
-
Hm das macht nun auch keinen Unterschied zu der Schleife, die ich oben hatte... Ausgabe sieht so aus (mit rel. Fehler für jedes n):
eps = 0.041713584569423 eps = 0.016960237953730 eps = 0.004789214655352 eps = 0.001204533610082 eps = 0.000301181303792 eps = 0.000075298160853 eps = 0.000018824717399 eps = 0.000004706190423 eps = 0.000001176548315 eps = 0.000000294137095 eps = 0.000000073534333 eps = 0.000000018383606 eps = 0.000000004595637 eps = 0.000000001149343 eps = 0.000000000286451 eps = 0.000000000071172 eps = 0.000000000017731 eps = 0.000000000004377 eps = 0.000000000018650 eps = -0.000000000022917 eps = -0.000000000019566 eps = -0.000000000006715 eps = 0.000000000278440 Umfang = 46.026225189782515 Relativer Fehler = 0.000000000278440 n = 16777216