Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Problem mit KomplexeZahlen-Algorithmus

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
14.11.2007, 21:13 Uhr
~erpel
Gast


Hallo. Ich bin am verzweifeln, da ich seit 2 tagen den Fehler nicht finde. Ich schreibe Ein Programm welches mir die mandelbrotmenge ausgibt(zunächst ohne Zoom und Farben), dazu benutze ich C und die WinApi.
zunächst der Code:

Code:
#define STRICT
#include <windows.h>
#include <complex.h>

unsigned long iteration_max;

double real,imag,x,y;       //Real- und Imaginärteil der komplexen Zahl c
complex double c;
int menge,l;              //da es in c kein BOOL gibt muss der int her, guckt ob c in MM ist

HDC hdc;
PAINTSTRUCT ps;
HWND hbutton1,hedit2;

char striteration[10],buffer2[10];

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
int iteration(complex double fc);   //Funktion die die Folge laufen lässt

/*  Make the class name into a global variable  */
char szClassName[ ] = "WindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_HREDRAW | CS_VREDRAW;;                
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = GetStockObject(LTGRAY_BRUSH);

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Herr Apfelmann",    /* Title Text */
           WS_OVERLAPPED | WS_SYSMENU, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           800,                 /* The programs width */
           600,                 /* and height in pixels */
           NULL,      
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);
    UpdateWindow(hwnd);
    
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage(),d.h. nicht dass es von "windows" kommt :)  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{          
    switch (message)                  /* handle the messages */
    {
        case WM_DESTROY:
        {          
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            return 0;
        }      
        case WM_CREATE:
        {
            hbutton1 = CreateWindow("button","Apfel essen",
                                   WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                                   600, 20, 100, 40,
                                   hwnd,1,((LPCREATESTRUCT) lParam) -> hInstance, NULL);
                
            hedit2 = CreateWindowEx(WS_EX_CLIENTEDGE,"edit",buffer2
            ,WS_CHILD | WS_VISIBLE,600,100,100,20,hwnd,2,
                                    ((LPCREATESTRUCT) lParam) -> hInstance,NULL);
            return 0;
        }  
        case WM_COMMAND:
        {  
            switch(LOWORD(wParam))
            {  
                case 1:
                {
                    l = GetWindowTextLength(hedit2);
                    GetWindowText(hedit2,striteration,l+1);
                    sscanf(striteration,"%i",&iteration_max);
                    hdc = GetDC(hwnd);              
                    //Alles zunächst übermalen
                    for (x=0;x<=550;x++)
                    {
                        for (y=0;y<=550;y++)
                        {
                            SetPixel(hdc,x,y,RGB(192,192,192));
                        }
                    }                      
                    for (real=-2.0;real<=0.5;real+=0.005)
                    {
                        for (imag=-1.2;imag<=1.2;imag+=0.005)
                        {
                            c = real + imag * I;
                            menge = iteration(c); //Funktionsaufruf
                            if (menge == 1)
                            {  
                                x = real * 200;
                                y = imag * 200;
                                x += 400;
                                y += 300;
                                SetPixel(hdc,x,y,RGB(0,0,0));
                            }
                        }
                    }    
                    ReleaseDC(hwnd,hdc);
                    return 0;
                }
                return 0;
            }
            return 0;
        }        
    }                        
    return DefWindowProc (hwnd, message, wParam, lParam);
}
int iteration(complex double fc)
{
    unsigned long i; //Laufvariable
    complex double z[iteration_max+1];  //Folgenglid z[n]
    double betrag;
    z[0] = 0 + 0*I; // z[0] = 0
  
    for (i = 1;i<=iteration_max;i++)
    {
        z[i] = (z[i-1]) * (z[i-1]) + fc;  // z[n] = z[n-1]^2 + c
    }
    
    betrag = sqrt(creal(z[iteration_max])*creal(z[iteration_max]) + cimag(z[iteration_max])*cimag(z[iteration_max]));
    // Abstand c zum Ursprung = Betrag
    if (betrag <=2)
    {
        return 1;
    }
    else
    {
        return 0;
    }          
}


Anmerkung: Ich hab den Algorithmus selber geschrieben und sonst auch alles, also nur so.. falls was komisch is..
Jetzt das Problem:
Ich habe gemerkt, dass da was nicht ganz stimmt.
Der Punkt(-2,0) sollte doch 100% in M liegen. Wenn ich das nur mit dem Algo nachprüfe stimmt das auch. Nur er malt ihn nicht!?
Und jetzt kommen die Fakten die mich komplett verwirren:
Wenn ich in der 2. for-Schleife das hier einsetze: for (imag=0;imag<=1.2;imag+=0.005)
zeichnet er nur die Hälfte(soll ja auch) aber jetzt zeichnet er alle Punkte die er auch soll, also auch (-2,0).
Jedoch wenn ich for (imag=0;imag>=-1.2;imag-=0.005) einsetze, zeichnet er die andre Hälfte(logisch) jedoch mit einem Strich drin!?

So, und jetzt seh ich garnicht mehr duch, es müsste doch so wie ich es formuliert habe einwandfrei funktionieren(also so wie im code)...oder etwas mit der rechnung stimmt nicht.

Hoffe mir kann jemand helfen. danke.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
15.11.2007, 11:01 Uhr
~erpel
Gast


Ich glaube ich habe mein Problem gefunden... es liegt einfach an dem datentyp(egal ob double oder float)...
Aber es kann doch nicht so schwer sein, einfahc nur genau + 0.005 zu rechnen!?
Wenn ich jetzt eine andere Bibliothek verwende, z.B. GMP dann muss ich mir ja auch ne eigene KomplexeZahlen Arithmetik schreiben.. mh. toll
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
15.11.2007, 11:27 Uhr
0xdeadbeef
Gott
(Operator)


0.005 ist mit endlicher Mantisse in binär nicht exakt darzustellen; ähnlich wie 1/7 in dezimaler Darstellung.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: