#include #include #include using namespace std; // class for a complex number a + bi class complexNumber{ public: double v[2]; complexNumber(){ v[0] = v[1] = v[2] = 0.; } complexNumber(double x, double y){ v[0] = x; v[1] = y; } ~complexNumber(){} double magnitude2(); // return the square of the modulus complexNumber square(); }; double complexNumber::magnitude2() { return v[0]*v[0] + v[1]*v[1]; } complexNumber complexNumber::square() { return complexNumber(v[0]*v[0] - v[1]*v[1], 2*v[0]*v[1]); } // define addition of two complex numbers inline complexNumber operator+(const complexNumber& x, const complexNumber& y){ return complexNumber(x.v[0]+y.v[0],x.v[1]+y.v[1]); } inline complexNumber operator*(const complexNumber& x, const complexNumber& y) { return complexNumber(x.v[0]*y.v[0] - x.v[1]*y.v[1], x.v[0]*y.v[1] + x.v[1]*y.v[0]); } // trigonometric functions for complex numbers inline complexNumber sin(complexNumber x) { return complexNumber(sin(x.v[0])*cosh(x.v[1]), cos(x.v[0])*sinh(x.v[1])); } // given a complex number z and constant c, is z in the set or not? bool isInSet(complexNumber z, const complexNumber& c, const int& maxIterations, const double& thresh) { double thresh2 = thresh*thresh; for (int i = 0; i < maxIterations; i++) { z = z.square() + c; // if you don't want to use the quadratic, try the sin: //z = c*sin(z); if (z.magnitude2() > thresh2) { return false; } } return true; } int main(int argc, char** argv) { clock_t startClock = clock(); printf("Starting complex Julia Set...\n"); // image dimensions: int width = 500; int height = 500; // area to scan: double minX = -1.5; double maxX = 1.5; double minY = -1.5; double maxY = 1.5; // value for constant c: complexNumber c(-0.123, 0.745); //complexNumber c(0, 1); // number of iterations and escape threshhold: int maxIterations = 20; double thresh = 1000.0; char* filename = "myFile.bmp"; // array to hold pixel data: bool** pixels; pixels = new bool*[width]; for (int i = 0; i < width; i++) { pixels[i] = new bool[height]; } // scan each pixel to see if it is in the set or not printf("Scanning area: XX.X%%"); for (int i = 0; i < width; i++) { printf("\b\b\b\b\b%04.1f%%", float(i)/float(width)*100.0); for (int j = 0; j < height; j++) { const double a = double(i)*(maxX-minX)/double(width) + minX; const double b = double(j)*(maxY-minY)/double(height) + minY; complexNumber z(a, b); pixels[i][j] = isInSet(z, c, maxIterations, thresh); } } printf("\b\b\b\b\bDone.\n\n"); // write the result to a bitmap printf("Writing file...\n"); ofstream myFile; myFile.open(filename, ios::out | ios::binary); // write BM char header[2] = {'B','M'}; myFile.write(header, 2); // write file size unsigned int fileSize = width*height*3 + 54; myFile.write((char*)&fileSize, 4); // write reserved unsigned short reserved = 0; myFile.write((char*)&reserved, 2); myFile.write((char*)&reserved, 2); // write offset to bitmap data unsigned int offSet = 54; myFile.write((char*)&offSet, 4); // write header size unsigned int headerSize = 40; myFile.write((char*)&headerSize, 4); // write image size myFile.write((char*)&width, 4); myFile.write((char*)&height, 4); // planes unsigned short planes = 0; myFile.write((char*)&planes, 2); // bits per color unsigned short bitCount = 24; myFile.write((char*)&bitCount, 2); unsigned int compression = 0; myFile.write((char*)&compression, 4); unsigned int imageSize = 0; myFile.write((char*)&imageSize, 4); unsigned int ppmX = 0; myFile.write((char*)&ppmX, 4); unsigned int ppmY = 0; myFile.write((char*)&ppmY, 4); unsigned int colorsUsed = 0; myFile.write((char*)&colorsUsed, 4); unsigned int colorsImp = 0; myFile.write((char*)&colorsImp, 4); // write image information for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { char rr, gg, bb; if (pixels[i][j]) { rr = char(0); gg = char(0); bb = char(0); } else { rr = char(255); gg = char(255); bb = char(255); } myFile.write(&bb, 1); myFile.write(&gg, 1); myFile.write(&rr, 1); } } myFile.close(); double dif = (clock() - startClock) / double(CLOCKS_PER_SEC); printf("Wrote file '%s' in %.2lf seconds.\n\n", filename, dif); }