![]() |
Tangeskurve
Hallo!
Ich stell' mich anscheinend gerade etwas dumm an, aber ich versuche das jetzt schon seit über zwei Stunden und ich hab anscheinend einen Denkfehler:
Delphi-Quellcode:
Zur Zeile 9:
procedure TForm1.DrawTangens;
var x, y: Integer; begin with Image1.Canvas do begin MoveTo(0, Image1.Height div 2); for x := 0 to Image1.Width do if x mod 90 mod 2 = 0 then //Hier will ich sicherstellen, dass der Tangeswert ein gültiger ist begin y := round(Amp.Value * tan(x / Image1.Width * Frq.Value * pi)); //Amp und Frq sind zwei SpinEdits LineTo(x, Image1.Height div 2 - y); //Hier ziehe ich den Wert von der Nullinie der Funktion ab end; end; end; cos ist null, bei 90, 270, 450, etc. und tan = sin / cos
Delphi-Quellcode:
Das ganze funktioniert mal, wenn Frq.Val 4 ist. Verändere ich Frq aber, gibts wieder einen Fehler...
function tan(const X: Extended): Extended;
begin result := sin(X) / cos(X) end; Warum aber? Wo liegt mein Fehler? Danke für die Antwort. |
Re: Tangeskurve
Achtung: Die Winkel der sin(x) und cos(x) werden in rad (0 bis 2*Pi) angegeben und nicht in Grad!
Carsten |
Re: Tangeskurve
|
Re: Tangeskurve
OK, das ist klar...
Da lag mein Denkfehler. Danke. |
Re: Tangeskurve
OK, ich komm nicht weiter...
Es kommt immer folgender Fehler:
Code:
Project Functioneer.exe raised exception class EInvalidOp with message 'Invalid floating point operation'.
|
Re: Tangeskurve
Mit Debugger (IDE) laufen lassen. Dann bekommst du auch die Stelle, wo es passiert. Das hilft dir weiter. Falls nicht, zeig uns die Stelle.
|
Re: Tangeskurve
Das ist ja das Komische, der Debugger zeigt die STelle nicht an, er bricht nur ab....
Ich kapier den Delphi 2005 Debugger sowieso nicht ganz, da kann man zum Beispiel keine Lokalen Variablen wärend der Laufzeit abfragen... EDIT: Ich habs mit dem Delphi 7 Debugger nochmals probiert und der bringt mich auch nicht an die Richtige Stelle.... |
Re: Tangeskurve
könnte irgendwann eine division durch 0 erfolgen ??
|
Re: Tangeskurve
wie wäre es denn mit einzelschritten!
|
Re: Tangeskurve
wieso eigentlich:
Delphi-Quellcode:
wäre es nicht eher:
for x := 0 to Image1.Width
Delphi-Quellcode:
for x := 0 to Image1.Width - 1
|
Re: Tangeskurve
Zitat:
Um das abzufangen kann man folgendes machen:
Delphi-Quellcode:
MfG
var x: Integer;//Winkel in Grad
... if (x-90) mod 180 = 0 then begin //Tangens ist an dieser Stelle nicht definiert ... end else begin //Kurve zeichnen end; Binärbaum |
Re: Tangeskurve
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo!
Also eine Division schließe ich mal aus, denn dann würde die Fehlermeldung ja "Division by Zero" lauten... Zur Sicherheit hab ich das mal mit folgender Anweisung ausgeschlossen:
Delphi-Quellcode:
Also ich hab die Stelle jetzt:
for x := 0 to Image1.Width do
if cos(x / Image1.Width * Frq.Value * pi) <> 0 then begin y := round(Amp.Value * tan(x / Image1.Width * Frq.Value * pi)); LineTo(x, Image1.Height div 2 - y); end;
Delphi-Quellcode:
Den Wert hab ich noch nicht herausgefunden, aber vielleicht bringt da ja jemand zusammen...
for x := 0 to Image1.Width do
begin y := round(Amp.Value * tan(x / Image1.Width * Frq.Value * pi)); //Hier ist es.... LineTo(x, Image1.Height div 2 - y); end; |
Re: Tangeskurve
Zitat:
Delphi-Quellcode:
heißen...
for x := 1 to Image1.Width - 1
Aber es ist schon so in Ordnung. Denn 1. zeichnet Delphi die Werte trotzdem, und außerdem ist der Wert Image1.Width IMHO noch im Bild. |
Re: Tangeskurve
Zitat:
Ich vermute mal, dass das Ergebnis der Division, wenn 0 schon ausgeschlossen ist, zu groß für den Datentyp wird, und deshalb abgebrochen wird. Du solltest also Divisionen von -0.0...01 bis +0.0...01 ausschließen, und nicht nur 0 selbst. Gruss, Fabian |
Re: Tangeskurve
was ist mit den x-werten, wo tangens unendlich ist (cos(x)=0)! wo filterst du die in deinem code aus?
|
Re: Tangeskurve
Hallo!
Ich hab die FOR - Schleife jetzt Schritt für Schritt nachgerechnet (*g*)... Und bin auch mit meinem TR bei 61 auf eine Polstelle gestoßen... Und siehe da: Bei X = 61 hängt das Programm.... Wieso ist das so? Deswegen: Formel: tan(X / Image1.Width * 4 * Pi) Image1.Width ist 488 Rechengang: tan(X) = sin(X) / cos(x) cos(61 / 488 * 4 * Pi) = 0 Wieso erkennt das mein Programm nicht, wenn ich schreibe:
Delphi-Quellcode:
if cos(X / Image1.Width * 4 * Pi) <> 0
|
Re: Tangeskurve
Zitat:
MfG Binärbaum |
Re: Tangeskurve
Zitat:
Delphi-Quellcode:
for x := 0 to Image1.Width do
begin if cos(x / Image1.Width * 4 * pi) <> 0 then begin y := round(tan(x / Image1.Width * 4 * pi)); LineTo(x, Image1.Height div 2 - y); end; end; |
Re: Tangeskurve
@ibp: Das sind ja die Stellen mit Division durch 0! Die sind raus.
|
Re: Tangeskurve
Weil 0 bei Floats nicht unbedingt genau 0 ist. Du musst eine klitze kleine Spanne um 0 herum abfangen.
|
Re: Tangeskurve
Hm:
Ich hab jetzt folgendes Herausgefunden: es liegt am Pi... Fragt mich nicht wieso, aber das dürfte wohl an der Reihenentwicklung von Tanges liegen... Lässt man das Pi weg, gibts keine Probleme, aber sobald man das Pi reistellt, hängt das Programm an den Polstellen... Vielleicht liegt das daran, dass der Cosinus von Pi -1 und der Sinus von Pi 0 sind... also:
Delphi-Quellcode:
Bitte um Hilfe, das verwirrt mich zu tiefst....
y := round(tan(Amp.Value * x / Image1.Width * Frq.Value * Pi)); //Das Programm hängt
y := round(tan(Amp.Value * x / Image1.Width * Frq.Value)); //Es läuft |
Re: Tangeskurve
Delphi-Quellcode:
Es ist besser du machst eine Abfrage auf das Argument, dass das nicht die unerlaubten Werte annimmt. Da die cosinus-Funktion eine Gleitkommazahl zurück gibt wird die fast nie exakt 0 sein, sondern u.U. 0.00...1!
for x := 0 to Image1.Width do
begin if cos(x / Image1.Width * 4 * pi) <> 0 then begin y := round(tan(x / Image1.Width * 4 * pi)); LineTo(x, Image1.Height div 2 - y); end; end; |
Re: Tangeskurve
Mit ohne Pi kommst du wahrscheinlich nur sehr unwahrscheinlich auf ein Vielfaches von (Pi/2). Daher "triffst" du die Polstellen erst garnicht.
|
Re: Tangeskurve
Zitat:
Danke... Wie würde die lauten? Wann ergibt der Cosinus eines Wertes null? |
Re: Tangeskurve
Der Cosinus ist für Pi/2 und 3*Pi/2 (allgemein (2n-1)*Pi/2 mit n=1,2,3...) 0.
z.B.
Delphi-Quellcode:
while Argument >= 3*Pi/2 do begin
Argument - Pi; // so kommst du in den Bereich von 0 bis ausschließlich 3*Pi/2 end; if Argument <> Pi/2 do begin // hier dein Code end; |
Re: Tangeskurve
Zitat:
Zitat:
Aber das hilft dir nicht weiter, da man bei Float-Werten NIE sicher sein kann einen Wert ganz genau zu treffen. (Zur Erklärung hab ich hier schon mal was längeres gepostet - müsstest mal suchen.) Also:
Delphi-Quellcode:
Unter Win32-Delphi gibt's die Funktion Math.isZero(zahl), die die nötige Spanne aus dem Datentyp ermittelt, und testet.
if (cos(irgendwas) < -0.00000001) or (cos(irgendwas) > 0.00000001) then
begin .... end; \\edit: Und Binärbaum hat unter mir die effizientere Variante gepostet :) |
Re: Tangeskurve
Mach's doch so:
Delphi-Quellcode:
Damit hast du auch solche Fälle überprüft, wo der Cosinus "beinahe" null ist und dürftest so auf der sicheren Seite sein.
var sinus, cosinus: Double;
x: Integer; begin for x := 0 to Image1.Width do begin SinCos(x / Image1.Width * 4 * pi, sinus, cosinus); if abs(cosinus) > 0.00001 then//0.00001 bei Bedarf ändern begin y := round( sinus/ cosinus);//sin(alpha)/cos(alpha)=tan(alpha) LineTo(x, Image1.Height div 2 - y); end; end; end; MfG Binärbaum |
Re: Tangeskurve
Zitat:
x mod 90 mod 2 gilt in dezimalgrad also: 90° = pi/2 rad 270* = pi(2/3) rad usw. |
Re: Tangeskurve
Zitat:
Zweitens: x mod 90 mod 2 ist nicht nur bei den Polstellen null. Bsp: x=4 --> 4 mod 90 mod 2 = 0 oder x=180 --> 180 mod 90 mod 2 = 0, obwohl bei 180° keine Polstelle ist. Damit funktioniert das schonmal nicht, und deswegen muss man es ändern. Also wenn schon über modulo, dann (x-90) mod 180 . MfG Binärbaum |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11: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