### Fibonacci Word Fractal

I saw this topic: http://www.cplusplus.com/forum/general/254904/
And decided to make a fractal from it... You'll need to include "vector".
I'm not very good on c++, but you guys might like it.

So i made it using CImg (http://cimg.eu/):
 ``12345678910111213141516171819202122232425262728293031323334353637383940414243`` ``````// FIBONACCI WORD string FiboWord(int Iter) { string Last; Last.push_back('0'); if (Iter < 1) { return (Last); } string Now; Now += Last; Now.push_back('1'); if (Iter < 2 && Iter > 1) { return (Now); } string Next; for (int n = 3; n <= Iter; ++n) { Next = Now + Last; Last = Now; Now = Next; } return (Next); } // ####### // FIBONACCI WORD FRACTAL COORDINATES: vector> FiboWordFrac(string Word) { vector> Coord(2); Coord[0].push_back(0); Coord[1].push_back(0); Coord[0].push_back(0); Coord[1].push_back(1); // Makes a vertical bar, x0 = 0, y0 = 0, x1 = 0, y1 = 1; int x = 0, y = 1; short Dir = 0; // Dir = Direction; 0 = Up; 1 = Down; 2 = Left; 3 = Right; bool First = true; if (Word.size() < 1) { return (Coord); } for (int n = 1; n < Word.length(); ++n) { if (!First) { if (Dir == 0) { ++y; Coord[0].push_back(x); Coord[1].push_back(y); } else if (Dir == 3) { ++x; Coord[0].push_back(x); Coord[1].push_back(y); } else if (Dir == 1) { --y; Coord[0].push_back(x); Coord[1].push_back(y); } else if (Dir == 2) { --x; Coord[0].push_back(x); Coord[1].push_back(y); } } if (First) { First = false; } if (Word.at(n) == '0') { if (n % 2 == 0) { if (Dir == 0) { Dir = 2; } else if (Dir == 3) { Dir = 0; } else if (Dir == 1) { Dir = 3; } else if (Dir == 2) { Dir = 1; } } // Change direction else { if (Dir == 0) { Dir = 3; } else if (Dir == 3) { Dir = 1; } else if (Dir == 1) { Dir = 2; } else if (Dir == 2) { Dir = 0; } } // Change direction } } return (Coord); }``````

 ``12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758`` ``````// PLOT BRESENHAM LINES: <-- It can be any function that draws a line, i just had this one in hand void Linexy(CImg& Img, int Thisx1, int Thisy1, int Thisx2, int Thisy2, int R, int G, int B) { int Thisx, Thisy, dx, dy, dx1, dy1, px, py, xe, ye, Thisi; dx = Thisx2 - Thisx1; dy = Thisy2 - Thisy1; dx1 = fabs(dx); dy1 = fabs(dy); px = 2 * dy1 - dx1; py = 2 * dx1 - dy1; unsigned char Color[] = { R, G, B }; if (dy1 <= dx1) { if (dx >= 0) { Thisx = Thisx1; Thisy = Thisy1; xe = Thisx2; } else { Thisx = Thisx2; Thisy = Thisy2; xe = Thisx1; } Img.draw_point(Thisx, Thisy, Color); for (Thisi = 0; Thisx < xe; Thisi++) { Thisx = Thisx + 1; if (px < 0) { px = px + 2 * dy1; } else { if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) { Thisy = Thisy + 1; } else { Thisy = Thisy - 1; } px = px + 2 * (dy1 - dx1); } Img.draw_point(Thisx, Thisy, Color); } } else { if (dy >= 0) { Thisx = Thisx1; Thisy = Thisy1; ye = Thisy2; } else { Thisx = Thisx2; Thisy = Thisy2; ye = Thisy1; } Img.draw_point(Thisx, Thisy, Color); for (Thisi = 0; Thisy < ye; Thisi++) { Thisy = Thisy + 1; if (py <= 0) { py = py + 2 * dx1; } else { if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) { Thisx = Thisx + 1; } else { Thisx = Thisx - 1; } py = py + 2 * (dx1 - dy1); } Img.draw_point(Thisx, Thisy, Color); } } } // PRINT IT: CImg PrintFiboWordFrac(vector> Coord, int SegmentSize) { int maxx = Coord[0][0], minx = Coord[0][0], maxy = Coord[1][0], miny = Coord[1][0]; for (int n = 0; n < Coord[0].size(); ++n) { if (Coord[0][n] > maxx) { maxx = Coord[0][n]; } if (Coord[0][n] < minx) { minx = Coord[0][n]; } if (Coord[1][n] > maxy) { maxy = Coord[1][n]; } if (Coord[1][n] < miny) { miny = Coord[1][n]; } } int sx = round((abs(maxx) + abs(minx) + 1) * SegmentSize), sy = round((abs(maxy) + abs(miny) + 2) * SegmentSize); CImg Fractal(sx, sy, 1, 3, 0); for (int n = 1; n < Coord[0].size(); ++n) { int R = 0, G = 0, B = 0; // CHANGE IT!!!!!!! Linexy(Fractal, ((Coord[0][n - 1] + 1) * SegmentSize), ((Coord[1][n - 1] + 1) * SegmentSize), ((Coord[0][n] + 1) * SegmentSize), ((Coord[1][n] + 1) * SegmentSize), R, G, B); } return (Fractal); }``````

And to choose parameters:
 ``12`` ``````int Opa, Opl; cout << "Iterations: "; cin >> Opa; cout << "Lenght: "; cin >> Opl; PrintFiboWordFrac(FiboWordFrac(FiboWord(Opa)), Opl).save_bmp("FiboWordFrac.bmp");``````

This is the resulting image with red color and black background:
https://i.imgur.com/vnrOZkU.png
Last edited on
Nice, pretty cool. I noticed that fractal too on the wikipedia page but didn't make it:)

Minor formatting complaint, I don't think it helps readability to put everything on one line like this
` else { if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) { Thisy = Thisy + 1; } else { Thisy = Thisy - 1; } px = px + 2 * (dy1 - dx1); }`
You seem to like doing this a lot. It's up to you, I just don't recommend t.
Last edited on
Cool program! Too bad it wasn't complete so we could run it easily.

BTW, as Iter is an int, this will be a rare event indeed:

 `` `` ``if (Iter < 2 && Iter > 1) { return (Now); }``

Last edited on
Also,
`vector<vector<int>> Coord(2); Coord[0].push_back(0); Coord[1].push_back(0); Coord[0].push_back(0); Coord[1].push_back(1); `
This can just become,
` vector<vector<int>> Coord = { {0, 0}, {0, 1} };`

And std::abs can be used instead of std::fabs because C++ has function overloading, but I suppose it doesn't really matter.
Last edited on
Here's a (untested and possibly not-quite-right) re-write of one of your functions. It uses a Point struct. You might want to rewrite your code to use a Point struct.

 ``123456789101112131415161718192021222324252627282930313233343536`` ``````struct Point { int x, y; }; enum {Up, Down, Left, Right}; vector FiboWordFrac(string Word) { static int nextDir[2][4] = { { Left, Up, Right, Down }, { Right, Down, Left, Up } }; vector Coord; Coord.push_back(Point(0,0)); Coord.push_back(Point(0,1)); if (Word.size() < 2) return Coord; int x = 0, y = 1; int Dir = Up; if (Word.at(1) == '0') Dir = nextDir[1][Dir]; for (int n = 2; n < Word.length(); ++n) { if (Dir == Up ) ++y; else if (Dir == Right) ++x; else if (Dir == Down ) --y; else if (Dir == Left ) --x; Coord.push_back(Point(x, y)); if (Word.at(n) == '0') Dir = nextDir[n % 2][Dir]; } return Coord; }``````

Last edited on
I took another look at your program. My first rewrite above wasn't quite right. This one seems to work.

 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109`` ``````//For ubuntu: //\$ sudo apt-get install libx11-dev //\$ sudo apt-get install cimg-dev //\$ g++ -Wall prog.cpp -lpthread -lX11 #include #include #include #include using Byte = unsigned char; using Image = cimg_library::CImg; 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 FiboWordFrac(std::string word) { static int nextDir[2][4] = { { Left, Right, Down, Up }, { Right, Left, Up, Down } }; std::vector 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& 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"); }``````

Last edited on
You guys are amazing, I'm very gladly, thanks! I couldn't imagine so much resuming...
Also, sorry taking long to answer, i was very occupied today...
Sorry for the formating mistakes, i'll from now on post on this forum the working program and not just mere functions, also, in a readable way :p...
Also, i forgot to say the bresenham lines, i used because i already had it, but people can simple use any function that draw lines...

@dutch Omg, i can't believe i made this formula "Iter < 2 && Iter > 1", it should have been "Iter < 3"...

@Ganado, hmm, i don't knew about this "fabs" thing, i'll be honest that i "stole" this function from somewhere in "Stackoverflow", can't find the link here, I'll check it out better...

@dutch, the program is working perfectly now, i'm thankful for your effort!
Sorry any "newbism" from me on this forum! I'll make more proper posts next time...
Last edited on