Улучшение моего кода Мандельброта
У меня есть следующий код набора Мандельброта в C. Я делаю вычисления и создаю файл.ppm для окончательного фрактального изображения. Дело в том, что мое фрактальное изображение перевернуто, то есть оно повернуто на 90 градусов. Вы можете проверить это, выполнив мой код:./mandel> test.ppm
С другой стороны, я также хочу изменить цвета. Я хочу добиться этого фрактального изображения:
Моя последняя проблема в том, что мой код не проверяет время выполнения моего кода. У меня есть код для этой части тоже, но когда выполнение кода заканчивается, он не печатает время выполнения. Если бы кто-то мог внести соответствующие изменения в мой код и помочь мне достичь этого фрактального изображения, а также отобразить прошедшее время, я был бы рад.
#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;
}
1 ответ
Часть 1: Вам нужно поменять местами порядок ваших петель:
for(y = 0; y < h; y++)
for(x = 0; x < w; x++)
Это даст вам правильно ориентированный фрактал.
Часть 2: Чтобы получить время для распечатки, вы должны распечатать его в stderr, так как вы печатаете вывод ppm в stdout:
fprintf(stderr, "Elapsed time: %.2lf seconds.\n", time_spent);
Часть 3: Чтобы получить непрерывную плавную раскраску, вам нужно использовать метод Normalized Iteration Count или что-то подобное. Вот замена для вашей раскраски, которая дает вам нечто похожее на то, что вы хотите:
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);
}
Это не совсем так, потому что я вроде как сделал простую приблизительную реализацию метода Normalized Iteration Count.
Это не полностью непрерывная окраска, но она довольно близка.