Программа Мандельброта на C ++ не выдаст корректный вывод

Я пытаюсь создать программу, которая генерирует образ стандартного набора Мандельброта, создавая файл .PPM. Программа не создает действительный файл PPM, и я понятия не имею, почему.

Вот мой код:

#include <fstream>
#include <iostream>

using namespace std;

/*
For each pixel (Px, Py) on the screen, do:
{
x0 = scaled x coordinate of pixel (scaled to lie in the Mandelbrot X scale (-2.5, 1))
y0 = scaled y coordinate of pixel (scaled to lie in the Mandelbrot Y scale (-1, 1))
x = 0.0
y = 0.0
iteration = 0
max_iteration = 1000
while ( x*x + y*y < 2*2  AND  iteration < max_iteration )
{
xtemp = x*x - y*y + x0
y = 2*x*y + y0
x = xtemp
iteration = iteration + 1
}
color = palette[iteration]
plot(Px, Py, color)
}
*/

int findMandelBrot(double cr, double ci, int max_iterations){
int i = 0;
double zr = 0.0, zi = 0.0;
while (i > max_iterations && zr * zr + zi * zi < 4.0){
double temp = zr * zr - zi * zi;
zi = 2.0 * zr * zi + ci;
zr = temp;
i++;
}
return i;
}

double mapToReal(int x, int imageWidth, double minR, double maxR){
double range = maxR - minR;

return x * (range / imageWidth) + minR;
}

double mapToImaginary(int y, int imageWidth, double minI, double maxI){
double range = maxI - minI;

return y * (range / imageWidth) + minI;

}

int main(){

ifstream fin;
fin.open ("input.txt");
int imageWidth, imageHeight, maxN;
double minR, maxR, minI, maxI;

if (!fin.is_open()){
cerr << "Couldn't load input.txt file" << endl;
return 0;
}

fin >> imageWidth >> imageHeight >> maxN;
fin >> minR >> maxR >> minI >> maxI;
fin.close();

ofstream fout("output_image.ppm");
fout << "P3" << endl;
fout << imageWidth << " " << imageHeight;
fout << "256" << endl;

for (int y = 0; y < imageHeight; y++){
for (int x = 0; x < imageWidth; x++){
double cr = mapToReal(x, imageWidth, minR, maxR);
double ci = mapToImaginary(y, imageHeight, minI, maxI);

int n = findMandelBrot(cr, ci, maxN);

int r = (n % 256);
int g = (n % 256);
int b = (n % 256);

fout << r << " " << g << " " << b << " ";
}
fout.close();
}
fout.close();
cout << "Finished! " << endl;

cin.ignore();
cin.get();
return 0;
}

2

Решение

Хорошее начало с отладки — запустить программу с простыми входными данными (например, для генерации выходного изображения 8×5), а затем посмотреть на выходные данные. Поскольку PPM легко читается человеком, вы увидите, что вы получите только 8 образцов. Это должно быть подсказкой, что с первым рядом все в порядке, и между этим и вторым рядом есть проблема. Теперь увеличьте масштаб строки цикла, и вы увидите, что вы написали fout.close() где вы хотели испустить новую строку.

Следующее, что вы заметите, это то, что все ваши значения равны нулю. Это немного сложнее диагностировать, но если вы посмотрите в findMandelBrot и шагните в своем уме, вы войдете в while цикл с i равно 0, и вы должны заметить, что цикл никогда не будет введен.

Я немного переработал твой код. В дополнение к исправлению ошибок, у меня есть

  • использовал std :: complex вместо того, чтобы заново изобретать колесо — посмотрите его в своем любимом справочнике, если вы не знакомы с ним
  • Предполагается, что вы сделаете что-то другое с цветами, когда он будет работать, или я бы упростил вывод в PGM, а не в PPM.
  • добавлена ​​минимальная проверка чтения и записи файлов
  • включены комментарии к коду, объясняющие мои исправления.

Вот код:

#include <fstream>
#include <iostream>
#include <complex>

using namespace std;// Converted to take a std::complex to make the arithmetic clearer
int findMandelBrot(complex<double> c, int max_iterations)
{
int i = 0;
complex<double> z = 0;
// was while(i > max_iterations ...) which would make this always
// return false
while (i <= max_iterations && norm(z) < 4.0) {
z *= z;
z += c;
i++;
}
return i;
}

double mapToReal(int x, int imageWidth, double minR, double maxR)
{
double range = maxR - minR;
return x * (range / imageWidth) + minR;
}

double mapToImaginary(int y, int imageWidth, double minI, double maxI)
{
double range = maxI - minI;
return y * (range / imageWidth) + minI;

}

int main()
{
ifstream fin;
fin.open("input.txt");
int imageWidth, imageHeight, maxN;
double minR, maxR, minI, maxI;

if (!fin.is_open()) {
cerr << "Couldn't load input.txt file" << endl;
return EXIT_FAILURE;
}

fin >> imageWidth >> imageHeight >> maxN;
fin >> minR >> maxR >> minI >> maxI;

// Check whether we managed to read the values
if (!fin) {
cerr << "Failed to read input.txt file" << endl;
return EXIT_FAILURE;
}
fin.close();

ofstream fout("output_image.ppm");
if (!fout) {
// something went wrong
cerr << "Couldn't open output file" << endl;
return EXIT_FAILURE;
}
fout << "P3" << endl;
fout << imageWidth << " " << imageHeight;
fout << " " << "256" << endl;

for (int y = 0; y < imageHeight; y++) {
for (int x = 0; x < imageWidth; x++) {
double cr = mapToReal(x, imageWidth, minR, maxR);
double ci = mapToImaginary(y, imageHeight, minI, maxI);

int n = findMandelBrot({cr, ci}, maxN);

int r = (n % 256);
int g = (n % 256);
int b = (n % 256);

fout << r << " " << g << " " << b << " ";
}
// was fout.close() - ending the image after first line
fout << endl;

// Periodically check for errors
if (!fout) {
// something went wrong
cerr << "Write failed" << endl;
return EXIT_FAILURE;
}
}
fout.close();

return EXIT_SUCCESS;
}

Это должно позволить вам продолжить немного дальше.

1

Другие решения


По вопросам рекламы [email protected]