C ++ Mandelbrot程序不会产生正确的输出

时间:2015-04-27 21:44:03

标签: c++ mandelbrot

我正在尝试制作一个程序,通过制作.PPM文件来生成标准Mandelbrot集的图像。该程序不会生成有效的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;
}

1 个答案:

答案 0 :(得分:1)

调试的良好开端是使用简单输入运行程序(例如,生成8x5输出图像),然后查看输出。由于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;
}

这应该让你继续前进一点。