2013-04-20 29 views
6

Mam następujący kod zestawu Mandelbrota w C. Robię obliczenia i tworzę plik .ppm dla końcowego fraktalnego obrazu. Chodzi o to, że mój fraktalny obraz jest do góry nogami, co oznacza, że ​​jest obrócony o 90 stopni. Możesz to sprawdzić, wykonując mój kod: ./mandel> test.ppmUlepszenie mojego kodu zestawu Mandelbrota

Z drugiej strony chcę również zmienić kolory. Chcę osiągnąć ten fraktalna obrazu:

enter image description here

Moja ostatnia kwestia jest to, że mój kod nie sprawdza czas pracy mojego kodu. Mam również kod dla tej części, ale kiedy kończy się wykonywanie kodu, nie drukuje czasu pracy. Jeśli ktoś może wprowadzić odpowiednie zmiany w moim kodzie i pomóc mi osiągnąć ten fraktalny obraz, i sprawić, że upłynął czas, byłbym zadowolony.

#include <math.h> 
#include <stdlib.h> 
#include <time.h> 
#include <stdio.h> 

void color(int red, int green, int blue) 
{ 
    fputc((char)red, stdout); 
    fputc((char)green, stdout); 
    fputc((char)blue, stdout); 
} 

int main(int argc, char *argv[]) 
{ 
    int w = 600, h = 400, x, y; 
    //each iteration, it calculates: newz = oldz*oldz + p, where p is the current pixel, and oldz stars at the origin 
    double pr, pi;     //real and imaginary part of the pixel p 
    double newRe, newIm, oldRe, oldIm; //real and imaginary parts of new and old z 
    double zoom = 1, moveX = -0.5, moveY = 0; //you can change these to zoom and change position 
    int maxIterations = 1000;//after how much iterations the function should stop 

    clock_t begin, end; 
    double time_spent; 

    printf("P6\n# CREATOR: E.T/mandel program\n"); 
    printf("%d %d\n255\n",w,h); 

    begin = clock(); 

    //loop through every pixel 
    for(x = 0; x < w; x++) 
    for(y = 0; y < h; y++) 
    { 
     //calculate the initial real and imaginary part of z, based on the pixel location and zoom and position values 
    pr = 1.5 * (x - w/2)/(0.5 * zoom * w) + moveX; 
     pi = (y - h/2)/(0.5 * zoom * h) + moveY; 
     newRe = newIm = oldRe = oldIm = 0; //these should start at 0,0 
     //"i" will represent the number of iterations 
     int i; 
     //start the iteration process 
     for(i = 0; i < maxIterations; i++) 
     { 
      //remember value of previous iteration 
      oldRe = newRe; 
      oldIm = newIm; 
      //the actual iteration, the real and imaginary part are calculated 
      newRe = oldRe * oldRe - oldIm * oldIm + pr; 
      newIm = 2 * oldRe * oldIm + pi; 
      //if the point is outside the circle with radius 2: stop 
      if((newRe * newRe + newIm * newIm) > 4) break; 
     } 

     color(i % 256, 255, 255 * (i < maxIterations)); 

    } 

    end = clock(); 

    time_spent = (double)(end - begin)/CLOCKS_PER_SEC; 
    printf("Elapsed time: %.2lf seconds.\n", time_spent); 

    return 0; 
} 

Odpowiedz

7

Część 1: Trzeba zamienić kolejność pętli do:

for(y = 0; y < h; y++) 
for(x = 0; x < w; x++) 

które dadzą Ci prawidłowo zorientowane fraktali.

Część 2: Aby uzyskać czas, aby wydrukować, należy go wydrukować na stderr od drukowania wyjście ppm do stdout:

fprintf(stderr, "Elapsed time: %.2lf seconds.\n", time_spent); 

Część 3: Aby uzyskać ciągłą gładką kolorystykę, musisz użyć znormalizowanej metody Iteracji lub czegoś podobnego. Tutaj jest zamiennikiem dla sekcji barwiący, który daje coś podobnego do tego, co chcecie:

if(i == maxIterations) 
     color(0, 0, 0); // black 
    else 
    { 
     double z = sqrt(newRe * newRe + newIm * newIm); 
     int brightness = 256. * log2(1.75 + i - log2(log2(z)))/log2(double(maxIterations)); 
     color(brightness, brightness, 255); 
    } 

To nie jest całkiem tam, bo niby zrobił prostą przybliżoną wdrożenia znormalizowanej metody licznik iteracji.

Mandelbrot using some semi-continuous coloring

To nie jest w pełni ciągłe farbowanie, ale jest to rodzaj blisko.

+0

Dzięki! Rozwiązał mój problem. Ale w ostatniej części kodu występuje niewielki błąd rzutu dotyczący nawiasów. Jeśli mógłbyś to poprawić ze względu na innych ludzi, może to być wspaniałe. –

+0

@erkant, masz na myśli podwójne (maxIteracje)? Działa dobrze dla mnie z gcc. Czy to coś innego? –

+0

Tak, mówiłem o tym. Nie zadziałało to dla mnie, musiałem użyć nawiasów jak ((podwójne) maxIteracje). –