Last active
December 20, 2015 23:49
-
-
Save artsobolev/6215372 to your computer and use it in GitHub Desktop.
Circle map bifurcation generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cv.h> | |
#include <highgui.h> | |
#include <cmath> | |
#include <string> | |
#include <iostream> | |
#include <fstream> | |
#include <sstream> | |
#include <vector> | |
#include <algorithm> | |
const int POINTS = 20000; | |
const int ITERS = 1000; | |
const int WIDTH = 600; | |
const int HEIGHT = 1200; | |
const double OMEGA = 1.0 / 3; | |
const double X_LIM = 1; | |
const double Y_LIM = 4 * M_PI; | |
double calculate(double omega, double K, std::vector<double> &xs) { | |
double theta = 0; | |
int sz = xs.size(); | |
for (int i = 0; i < ITERS + sz; ++i) { | |
theta = (theta + omega - K / (2 * M_PI) * std::sin(2 * M_PI * theta)); | |
theta = theta - floor(theta / X_LIM) * X_LIM; | |
int j = i - ITERS; | |
if (j >= 0) xs[j] = theta; | |
} | |
return theta; | |
} | |
cv::Vec3d color(double x) { | |
if (4 * x < 1) return cv::Vec3d(0, 0, 4*x); | |
if (4 * x < 2) return cv::Vec3d(0, 4*x - 1, 2 - 4*x); | |
if (4 * x < 3) return cv::Vec3d(4*x-2, 1, 0); | |
return cv::Vec3d(1, 4 - 4*x, 0); | |
} | |
int main(int argc, char **argv) { | |
cv::Mat out = cv::Mat(HEIGHT, WIDTH, CV_8UC3); | |
unsigned **count = new unsigned*[HEIGHT]; | |
unsigned *max = new unsigned[HEIGHT]; | |
for (int i = 0; i < HEIGHT; ++i) { | |
count[i] = new unsigned[WIDTH]; | |
for (int j = 0; j < WIDTH; ++j) { | |
count[i][j] = 0; | |
} | |
max[i] = 0; | |
} | |
std::cout << "Generating data..." << std::endl; | |
for (int i = 0; i < HEIGHT; ++i) { | |
double K = Y_LIM / HEIGHT * i; | |
std::cout << "Processing " << (100 * i / HEIGHT) << "%...\r"; | |
std::vector<double> xs(POINTS); | |
calculate(OMEGA, K, xs); | |
for (int k = 0; k < xs.size(); ++k) { | |
double x = xs[k]; | |
int j = floor(x / X_LIM * WIDTH); | |
++count[i][j]; | |
if (count[i][j] > max[i]) max[i] = count[i][j]; | |
} | |
} | |
std::cout << "Data generated." << std::endl; | |
for (int i = 0; i < HEIGHT; ++i) { | |
for (int j = 0; j < WIDTH; ++j) { | |
if (max[i] > 0) { | |
double v = double(count[i][j]) / max[i]; | |
cv::Vec3d c = color(v); | |
out.at<cv::Vec3b>(HEIGHT - i - 1, j) = cv::Vec3b(255 * c[2], 255 * c[1], 255 * c[0]); | |
} else { | |
out.at<cv::Vec3b>(HEIGHT - i - 1, j) = cv::Vec3b(0, 0, 0); | |
} | |
} | |
} | |
// выводим изображение | |
cv::imwrite("out.png", out); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Сделал возможность менять 1/4, 1/2, 3/4 в функции расчёта цвета
Добавил логарифмическую шкалу. Обычный логарифм оказался уныло-ровным, поэтому можно сделать несколько итераций, чем больше — тем логарифмичнее. Но приблизиться к оригиналу так и не удалось, надо играться с итерациями и светом, либо придумывать новую шкалу.