1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
//For ubuntu:
//$ sudo apt-get install libx11-dev
//$ sudo apt-get install cimg-dev
//$ g++ -Wall prog.cpp -lpthread -lX11
#include <iostream>
#include <string>
#include <vector>
#include <CImg.h>
using Byte = unsigned char;
using Image = cimg_library::CImg<Byte>;
enum {Up, Down, Left, Right};
struct Point
{
int x, y;
Point(int x, int y) : x(x), y(y) {}
};
std::ostream& operator<<(std::ostream& os, const Point& p)
{
return os << '(' << p.x << ',' << p.y << ')';
}
void DrawLine(Image& img,
int x0, int y0, int x1, int y1,
Byte r, Byte g, Byte b)
{
Byte color[] = { r, g, b };
img.draw_line(x0, y0, x1, y1, color);
}
std::vector<Point> FiboWordFrac(std::string word)
{
static int nextDir[2][4] = {
{ Left, Right, Down, Up },
{ Right, Left, Up, Down }
};
std::vector<Point> coord { {0, 0} };
int x = 0, y = 0;
int dir = Up;
for (size_t n = 1; n < word.size(); ++n)
{
if (dir == Up ) ++y;
else if (dir == Right) ++x;
else if (dir == Down ) --y;
else if (dir == Left ) --x;
coord.push_back({x, y});
if (word.at(n) == '0') dir = nextDir[n % 2][dir];
}
return coord;
}
Image DrawFiboWordFrac(const std::vector<Point>& coord, int segmentSize)
{
Point max(coord[0]), min(coord[0]);
for (size_t n = 1; n < coord.size(); ++n) {
if (coord[n].x > max.x) max.x = coord[n].x;
else if (coord[n].x < min.x) min.x = coord[n].x;
if (coord[n].y > max.y) max.y = coord[n].y;
else if (coord[n].y < min.y) min.y = coord[n].y;
}
int sx = (max.x - min.x + 1) * segmentSize,
sy = (max.y - min.y + 1) * segmentSize;
std::cout << "max: " << max << " min: " << min << '\n';
std::cout << "sx: " << sx << " sy: " << sy << '\n';
Image fractal(sx, sy, 1, 3, 0);
for (size_t n = 1; n < coord.size(); ++n)
DrawLine(fractal,
(coord[n - 1].x - min.x) * segmentSize,
(coord[n - 1].y - min.y) * segmentSize,
(coord[n ].x - min.x) * segmentSize,
(coord[n ].y - min.y) * segmentSize,
255, 0, 0);
return fractal;
}
std::string FiboWord(int iters)
{
if (iters < 1) return "0";
std::string prev {"0"}, now{"01"}, next;
for (int n = 2; n < iters; ++n) {
next = now + prev;
prev = now;
now = next;
}
return now;
}
int main()
{
int iters = 20, len = 5;
auto word = FiboWord(iters);
auto frac = FiboWordFrac(word);
std::cout << "frac.size: " << frac.size() << '\n';
auto img = DrawFiboWordFrac(frac, len);
img.save_bmp("fibowordfrac.bmp");
}
|