kostenloser Webspace werbefrei: lima-city


Problem beim Lösen einer Aufgabe [Fraktale]

lima-cityForumProgrammiersprachenC/C++ und D

  1. Autor dieses Themas

    zyclop

    zyclop hat kostenlosen Webspace.

    Hi,

    vor kurzem habe ich eine Aufgabe bekommen, es geht um Fraktale. Ich hab hier mal den Auszug aus dem Skript:
    http://zyclop.zy.funpic.de/member/Skript_Aufgaben_PP_Teil3b_20061111.pdf

    und hier mal meinen ersten Lösungsansatz:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    int main(int argc, char *argv[])
    {
       
      double z,c,x,y;
      
      z = 0;
      x = 1.5;
      y = 1.0;
      
      while(z < 2)
      {
        c = sqrt((x*x)+(y*y));
        z = (z*z)+c;
        printf(\"\\n%f\",z);
      }
      
      getch();
      
    }



    Ich steh irgendwie auf der Leitung und hab keine Ahnung, was ich machen muss :lol:
    es geht ausschließlich um den Algorithmus, die grafische Ausgabe ist erst mal unwichtig.
    die zahlen für x und y habe ich mal so aus einer Beispiel Rechnung aus dem Unterricht übernommen.

    Hier die Formel für komplexe Zahlen, für den Fall das sie einer nicht kennt:
    z = x+j*y bzw. z = a+j*b
    |z| = sqrt((x*x)+(y*y)) bzw. |z| = sqrt((a*a)+(b*b))

    Ich danke schon mal für eventuelle Hilfen ^^

    ---zyclop


    Beitrag geändert: 8.1.2008 9:03:42 von zyclop
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. c*a

    Hallo,

    die Mandelbrotmenge ist nach deinem Skript definiert als die Menge der komplexen Zahlen c für die die Folge

    z_n+1 = z_n^2 + c

    mit z_0 = 0

    konvergiert.

    Da man nicht unendlich viele Folgenglieder berechnen kann, sagt man: 1. \"Wenn eine bestimmte Schranke (in deinem Fall 2) überschritten wird, bereche die Iteration ab und liefere das Ergebnis: Der Punkt gehört nicht zur Mandelbrotmenge\"

    2. \"Wenn eine Anzahl von Iterationen erreicht wurden und liefere das Ergebnis: Der Punkt gehört zur Mandelbrotmenge\"

    Punkt 2 fehlt bei dir.

    Dann hast du die Formel
    z_n+1 = z_n^2 + c
    das sind komplexe Zahlen, du musst also schon die Rechenregeln für komplexe Zahlen benutzen!!!

    Ich schreibe die komplexe Zahlen jetzt mal als Zahlenpaar:

    z = x + iy = (x,y)

    Addition: (x,y) + (u,v) = (x + u, y + v) [wie Vektoren]

    Multiplikation: (x,y) * (u,v) = (u x - v y, v x + u y)

    Sei z = (z_x, z_y) und c = (c_x, c_y)

    dann haben wir:
    z_x = 0;
    z_y = 0;
    
    c_x = 1.5;
    c_y = 1.0;
    
    while (sqrt(z_x * z_x + z_y * z_y) < 2) { //das kann man optimieren zu z_x * z_x + z_y * z_y < 4
    
     x = z_x * z_x - z_y * z_y;
     z_y = 2 * z_x * z_y;
     z_x = x + c_x;
     z_y = z_y + c_y;
     
     printf(...)
    
    }
    (ungetestet).

    du solltest noch eine Abbruchbedingung einfügen, z. B. dass er die Schleife nur 300 mal durchläuft. Sonst hast du eine Endlosschleife, wenn der Punkt zur Mandelbrotmenge gehört!!!

    Beitrag geändert: 9.1.2008 22:40:37 von cga
  4. Autor dieses Themas

    zyclop

    zyclop hat kostenlosen Webspace.

    also ich hab den Algorithmus voll funktionsfähig und getestet... So ist es auch gemeint vom Lehrer:

    /* fract.h */
    int fract(double x0, double y0)
    {
      double x,y,z,tmpx;
      int j = 0;
      
      x = x0;
      y = y0;
    
      while((x*x + y*y) < 4 && j < 255)
      {
        tmpx = ((x*x)-(y*y))+x0;
        y = (2*x*y)+y0;
        x = tmpx;
        j++;
      }
      
      return j;
    }

    /* draw.h */
    void draw(HWND hwnd, RECT rect)
    {
      HDC hdc = GetDC(hwnd);
      int x,y,j,iterationen;
      double x0,y0;
      COLORREF col[256];
      
      for(j = 0; j < 256; j++)
      {
        col[j] = RGB(j+20,(int)(j*0.8)+20,(int)(j*0.2)+20);
      }
      col[255] = RGB(0,0,0);
      
      for(y = 1; y < rect.bottom; y++)
      {
        for(x = 1; x < rect.right; x++)
        {
          //x0 = ((double) ((x+190)*3) / (double) (rect.right-rect.left)) - 2; //mit verschiebung
          //x0 = ((double) (x*3*0.5) / (double) (rect.right-rect.left)) - 2; //mit zoom
          x0 = ((double) (x*3) / (double) (rect.right-rect.left)) - 2;
          y0 = ((double) (y*2) / (double) (rect.bottom-rect.top)) - 1;
          
          iterationen = fract(x0,y0);
          SetPixel(hdc, x, y, col[iterationen]);    
        }    
      }
      ReleaseDC(hwnd, hdc);
    }


    Soooo jetzt hab ich noch das problem, dass bei einem Linksklick reingezoomt werden soll und bei einem Rechtsklick raus... So sieht meine FensterProzedur gerade aus:

    LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        RECT rect;
        PAINTSTRUCT ps;
        POINT pos;
        
        switch (message)                  /* handle the messages */
        {
            case WM_DESTROY:
                PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
                break;
            case WM_PAINT:
                 GetClientRect(hwnd, &rect);
                 BeginPaint(hwnd, &ps);
                 draw(hwnd, rect);
                 EndPaint(hwnd, &ps);
                 break;
            case WM_LBUTTONUP:
                 GetCursorPos(&pos); // Hier weiß ich nicht wie ich den Zoom
                                     // und die Maus-Position an WM_Paint übergebe
                 break;   
            default:                      /* for messages that we don\'t deal with */
                return DefWindowProc (hwnd, message, wParam, lParam);
        }
    
        return 0;
    }


    Wenn ich bei \"case WM_LBUTTONUP\" die draw-Funktion aufrufe überschreib er mir mein neuerstelltes Bild sofort wieder wegen \"WM_PAINT\" und ich hab wieder den Ursprung!

    Beitrag geändert: 9.1.2008 21:11:23 von zyclop
  5. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!