/* xn+1 = sin(a yn) + c cos(a xn) yn+1 = sin(b xn) + d cos(b yn) */ #include #include #include using namespace std; // Change params only in this block namespace { const int width = 1600; const int height = 1200; const int frames = 10000; const int iters = 10000; const int skipIters = 10; double sensitivity = 0.02; const double minX = -4.0; const double minY = minX * height / width; const double maxX = 4.0; const double maxY = maxX * height / width; const double minA = acos( 1.6 / 2.0 ); const double maxA = acos( 1.3 / 2.0 ); const double minB = acos( -0.6 / 2.0 ); const double maxB = acos( 1.7 / 2.0 ); const double minC = acos( -1.2 / 2.0 ); const double maxC = acos( 0.5 / 2.0 ); const double minD = acos( 1.6 / 2.0 ); const double maxD = acos( 1.4 / 2.0 ); }; class Color { public: double r, g, b; Color(const double &red = 0, const double &green = 0, const double &blue = 0) : r(red), g(green), b(blue) { } Color& operator+=(const Color &rhs) { r += rhs.r; g += rhs.g; b += rhs.b; return *this; } static Color createHue( double h ) { h *= 6.0; int hi = static_cast( h ); double hf = h - hi; switch( hi % 6 ) { case 0: return Color( 1.0 , hf, 0.0 ); case 1: return Color( 1.0 - hf, 1.0, 0.0 ); case 2: return Color( 0.0 , 1.0, hf ); case 3: return Color( 0.0, 1.0 - hf, 1.0 ); case 4: return Color( hf, 0.0, 1.0 ); case 5: return Color( 1.0, 0.0, 1.0 - hf ); } return Color(); } Color operator+(const Color &rhs) const { return Color(*this) += rhs; } }; int main(void) { vector image( width * height ); for (int i = 0; i < frames; i++) { const double p = static_cast(i) / frames; const double a = cos( minA + p * (maxA - minA) ) * 2.0; const double b = cos( minB + p * (maxB - minB) ) * 2.0; const double c = cos( minC + p * (maxC - minC) ) * 2.0; const double d = cos( minD + p * (maxD - minD) ) * 2.0; const Color curCol = Color::createHue( p ); double x = 0.0, y = 0.0; for (int j = 0; j < iters; j++) { double xn = sin(a * y) + c * cos(a * x); double yn = sin(b * x) + d * cos(b * y); x = xn; y = yn; if ( j < skipIters ) continue; int xi = static_cast( (x - minX) * width / (maxX - minX) ); int yi = static_cast( (y - minY) * height / (maxY - minY) ); if ( xi >= 0 && xi < width && yi >= 0 && yi < height ) { image[ xi + yi * width ] += curCol; } } clog << "\r" << i; } clog << "\n"; cout << "P6\n" << width << " " << height << "\n" << "255\n"; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { Color &c = image[ x + y * width ]; unsigned char r = static_cast( (1.0 - exp( -sensitivity * c.r )) * 255.0 ); unsigned char g = static_cast( (1.0 - exp( -sensitivity * c.g )) * 255.0 ); unsigned char b = static_cast( (1.0 - exp( -sensitivity * c.b )) * 255.0 ); cout << r << g << b; } } return 0; }