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 zugreift 😃

    Nein, 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).


Log in to reply