atan2: DOMAIN error... Was ist das genau ?
-
Hallo,
nun, ich weis eigentlich nicht was ich sagen soll, aber ich kriege diesen fehler und weis nicht warum. Timer1 ist auf 1ms eingestellt, ich kriege aber viel viel mehr fehler-meldungen pro sekunde und mein RAM ist in 10 sec foll(2GB) .
mein code (C++Builder1)://--------------------------------------------------------------------------- #include <vcl\vcl.h> #include <math.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma resource "*.dfm" TForm1 *Form1; Graphics::TBitmap *img = new Graphics::TBitmap; TCanvas *canv; TCanvas *pbcanv; int MX, MY; int GX, GY; inline double rad2deg (double x) { return x * 180.0 / M_PI; } inline double deg2rad (double x) { return x * M_PI / 180.0; } inline float ga (float xdist, float ydist) // get angle { return atan2(ydist,xdist); } inline float aim(float x1, float x2, float y1, float y2) { return ga(x2-x1,y2-y1); } float fsqrt (float x) { float xhalf = 0.5f*x; int i = *(int*)&x; i = 0x5f3759df - (i>>1); x = *(float*)&i; return x*(1.5f - xhalf*x*x); } float dist(float x1, float y1, float x2, float y2) { float xd = (x2 - x1); float yd = (y2 - y1); xd *= xd; yd *= yd; return fsqrt(xd + yd); } //////////////////////////////////// class TParticle { /*TParticle(float _x, float _y, float _speed, float _dir, float _velx = 0, float _vely = 0, float gmx = 0, float gmy = 0) { x = _x; y = _y; speed = _speed; dir = _dir; velx = _velx; vely = _vely; } */ public: void Set (float _x, float _y, float _speed, float _dir = 0, float _velx = 0, float _vely = 0, float _gmx = 0, float _gmy = 0) { x = _x; prevx = _x; y = _y; prevy = _y; speed = _speed; dir = _dir; velx = _velx; vely = _vely; gmx = _gmx; gmy = _gmy; } void SetGM(float _x, float _y) { gmx = _x; gmy = _y; } void move (bool _handleG = true) // Fehler müsste hier sein { try{ dir = aim(x, MX, y, MY); }catch(...){} prevx = x; prevy = y; x += (cos(dir)*speed) +velx; y += (sin(dir)*speed) +vely; } void render (TCanvas *canv) { canv->MoveTo(prevx, prevy); canv->LineTo(x, y); } private: float prevx, prevy; float x, y; float velx, vely; float speed; float dir; float gmx, gmy; }; TParticle p[100]; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { PaintBox1->Height = ClientHeight; PaintBox1->Width = ClientWidth; img->Height = ClientHeight; img->Width = ClientWidth; pbcanv = PaintBox1->Canvas; canv = img->Canvas; canv->Pen->Color = clWhite; canv->Brush->Color = clWhite; canv->Brush->Style = bsSolid; canv->Rectangle(0, 0, ClientWidth, ClientHeight); canv->Brush->Style = bsClear; canv->Pen->Color = clBlack; for (int i = 0; i < 100; i++) { p[i].move(); p[i].render(canv); } pbcanv->CopyRect(Rect(0, 0, ClientWidth, ClientHeight), canv, Rect(0, 0, ClientWidth, ClientHeight)); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { //for (int i=0; i<100; i++) p = new TParticle(random(ClientWidth), random(ClientHeight), random(3)); for (int i=0; i<100; i++) { p[i].Set(random(ClientWidth), random(ClientHeight), random(2+1)); } } //--------------------------------------------------------------------------- void __fastcall TForm1::PaintBox1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { MX = X; MY = Y; } //---------------------------------------------------------------------------
-
atan2 müßte für alle wertepaare außer 0;0 klappen. dann wirds wohl den DOMAIN ERROR werfen, weil Du 0;0 reintust?
-
Du hättest besser deinen Source-Code nicht zeigen sollen -)
Aber so kann ich nicht anderes:
also die Fehlermeldung deutet darauf hin, daß deine Funktion irgendwie auf's Internet zugreift und dort anscheinend auf eine ungültige Domain zugreiftNein, jetzt im Ernst:
so viele Pseudo-Optimierungen, aber keine vernünftige Struktur in deinem Code!Die Fehler der math. Funktionen kannst du nicht mit catch(...) abfangen, sondern dafür mußt du die Funktion _matherr() definieren, s. http://www.imb-jena.de/~gmueller/kurse/c_c++/c_mather.html
Und jetzt noch ein paar andere "Highlights" deines Codes:
- warum verwendest du 'fsqrt' statt der Standard-Funktion 'sqrt'? Willst du ein paar Taktzyklen sparen - in einen GUI-Programm???
- Timer auf 1 ms bedeutet nicht, daß der 1000mal pro Sekunde aufgerufen wird, sondern der Windows-Timer hat höchstens eine Genauigkeit von ca. 14-15 ms.
- Und dann wiederum packst du die ganzen rechenintensiven Canvas-Initialisierungen in den Timer, obwohl diese konstant sind...
- Und 'Rect(0, 0, ClientWidth, ClientHeight)' könntest du auch in eine Variable packen, anstatt jedesmal zweimal zu berechnen!
- und zu guter letzt: random(2+1)Überleg dir als Programmierer lieber eine gute Struktur, d.h. trenne die Logik von der GUI (d.h. Aufteilung auf verschiedenen Units).