i trying make program generates image of standard mandelbrot set making .ppm file. program doesn't produce valid ppm file , have no clue why.
here code:
#include <fstream> #include <iostream> using namespace std; /* each pixel (px, py) on screen, do: { x0 = scaled x coordinate of pixel (scaled lie in mandelbrot x scale (-2.5, 1)) y0 = scaled y coordinate of pixel (scaled lie in mandelbrot y scale (-1, 1)) x = 0.0 y = 0.0 iteration = 0 max_iteration = 1000 while ( x*x + y*y < 2*2 , 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 = 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; (int y = 0; y < imageheight; y++){ (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; }
a start debugging run program simple inputs (e.g. generate 8x5 output image), @ output. since ppm human-readable, you'll see 8 samples. should clue first row okay, , there's problem between , second row. zoom in row loop , you'll see you've written fout.close()
meant emit newline.
the next thing you'll spot values come out zero. that's bit harder diagnose, if in findmandelbrot
, step through in mind, you'll go while
loop i
equal 0, , should spot loop never gets entered.
i've re-worked code little. in addition bug fixes, have
- used std::complex rather re-invent wheel - in favourite reference if you're not familiar it
- assumed you'll different colours once it's working, or have simplified output pgm rather ppm
- added minimal checking of reading , writing of files
- included comments code explaining fixes.
here's code:
#include <fstream> #include <iostream> #include <complex> using namespace std; // converted take std::complex make arithmetic clearer int findmandelbrot(complex<double> c, int max_iterations) { int = 0; complex<double> z = 0; // while(i > max_iterations ...) make // 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 managed read values if (!fin) { cerr << "failed read input.txt file" << endl; return exit_failure; } fin.close(); ofstream fout("output_image.ppm"); if (!fout) { // went wrong cerr << "couldn't open output file" << endl; return exit_failure; } fout << "p3" << endl; fout << imagewidth << " " << imageheight; fout << " " << "256" << endl; (int y = 0; y < imageheight; y++) { (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() - ending image after first line fout << endl; // periodically check errors if (!fout) { // went wrong cerr << "write failed" << endl; return exit_failure; } } fout.close(); return exit_success; }
that should allow continue little further.