#include #include #include #include struct Complex { double r, i; Complex(double r, double i) : r(r), i(i) {} Complex operator+(const Complex &a) { return Complex(r+a.r, i+a.i); } Complex operator*(const Complex &a) { return Complex(r*a.r - i*a.i, r*a.i + i*a.r); } double absq() { return r*r + i*i; } }; struct RGB { unsigned char rgb[3]; RGB(unsigned char r, unsigned g, unsigned b) { rgb[0] = r; rgb[1] = g; rgb[2] = b; } }; struct HSV { double h, s, v; HSV(double h, double s, double v) : h(h), s(s), v(v) {} int hi() { return int(floor(h/60)) % 6; } double f() { return h/60 - hi(); } double p() { return (1-s)*v; } double q() { return (1 - f()*s)*v; } double t() { return (1 -((1 - f())*s))*v; } static RGB makeRGB(double r, double g, double b) { return RGB((unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255)); } RGB toRGB() { switch (hi()) { case 0 : return makeRGB(v, t(), p()); case 1 : return makeRGB(q(), v, p()); case 2 : return makeRGB(p(), v, t()); case 3 : return makeRGB(p(), q(), v); case 4 : return makeRGB(t(), p(), v); default : return makeRGB(v, p(), q()); } } }; int width = 640; int height = 480; int maxColor = 360; int maxIterations = 40; double zoomFact = 0.8; double center = -0.65; double xInc = width / (200000 * zoomFact); double yInc = height / (150000 * zoomFact); double sat = 0.85; double val = 0.85; std::vector makeColorMap(int nbCols) { std::vector out; for (int i = 0; i < nbCols; ++i) { out.push_back(HSV((360.0*i)/(nbCols+1), sat, val).toRGB()); } return out; } std::vector colorMap = makeColorMap(std::min(maxIterations, maxColor)); Complex c(int i, int j) { return Complex(xInc*i + center - xInc*width/2, yInc*j - yInc*height/2); } int pixel(Complex c) { Complex z = Complex(0.0, 0.0); for (int i = maxIterations; i >= 0; --i) { z = z*z + c; if (z.absq() >= 4.0) return i; } return -1; } RGB black = RGB(0, 0, 0); RGB color(int iterations) { if (iterations == -1) return black; else return colorMap[iterations % colorMap.size()]; } void render(FILE *out) { for (int j = 0; j < height; j++) { for (int i = 0; i < width; ++i) { RGB rgb = color(pixel(c(i, j))); fwrite(&rgb.rgb, 1, 3, out); } } } void writePPMHeader(FILE *out) { char buf[30]; sprintf(buf, "P6\n%d %d\n255\n", width, height); fwrite(buf, 1, strlen(buf), out); } void run() { FILE *out = fopen("out.ppm", "wb"); if (!out) { printf("unable to open out.ppm\n"); return; } writePPMHeader(out); render(out); fclose(out); } int main() { run(); return 0; }