Skip to content

Instantly share code, notes, and snippets.

@allyouaskfor
Created November 17, 2019 00:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save allyouaskfor/aef47602a0c0eda06f449ed67e0a017a to your computer and use it in GitHub Desktop.
Save allyouaskfor/aef47602a0c0eda06f449ed67e0a017a to your computer and use it in GitHub Desktop.
attractor #cpp #visual #math #science
/*
xn+1 = sin(a yn) + c cos(a xn)
yn+1 = sin(b xn) + d cos(b yn)
*/
#include <iostream>
#include <cmath>
#include <vector>
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<int>( 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<Color> image( width * height );
for (int i = 0; i < frames; i++) {
const double p = static_cast<double>(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<int>( (x - minX) * width / (maxX - minX) );
int yi = static_cast<int>( (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<unsigned char>( (1.0 - exp( -sensitivity * c.r )) * 255.0 );
unsigned char g = static_cast<unsigned char>( (1.0 - exp( -sensitivity * c.g )) * 255.0 );
unsigned char b = static_cast<unsigned char>( (1.0 - exp( -sensitivity * c.b )) * 255.0 );
cout << r << g << b;
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment